• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 374
  • Last Modified:

sizeof operator

I am trying to find the size of variable with out using sizeof operator.
Its working fine, but i dont know how it works

code :
double *i;
int size;

// below line is not understood by me;
size=(char *)(i+1)- (char *)(i));

printf("size=%d",size);
0
nagaharikola
Asked:
nagaharikola
  • 19
  • 13
3 Solutions
 
ozoCommented:
If you do not know how it works, you should not be using it.
0
 
nagaharikolaAuthor Commented:
I understand that...
But I want to know how it is treated internally.
0
 
ozoCommented:
Do you understand what (char *) means?
Do you understand what it means to add a pointer and an integer, or to subtract two pointers?
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell┬« is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
nagaharikolaAuthor Commented:
yes I do understand all the things u have said
but i do not understand how this line works

size=(char *)(i+1)- (char *)(i));

0
 
ozoCommented:
Actually, since i is uninitialized, the behavior of the line in question is undefined.
0
 
ozoCommented:
When an expression that has integer type is added to or subtracted from a pointer, the
result has the type of the pointer operand. If the pointer operand points to an element of
an array object, and the array is large enough, the result points to an element offset from
the original element such that the difference of the subscripts of the resulting and original
array elements equals the integer expression. In other words, if the expression P points to
the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and
(P)-N (where N has the value n) point to, respectively, the i+n-th and i-n-th elements of
the array object, provided they exist. Moreover, if the expression P points to the last
element of an array object, the expression (P)+1 points one past the last element of the
array object,
0
 
ozoCommented:
When two pointers are subtracted, both shall point to elements of the same array object,
or one past the last element of the array object; the result is the difference of the
subscripts of the two array elements.
0
 
ozoCommented:
When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object
0
 
nagaharikolaAuthor Commented:
what happens when the following is done

double *d;
(char *)d
0
 
nagaharikolaAuthor Commented:
please ignore my previous coment...



Here the size is printed correctly for all the types but when  the adress of i and i+1 in

size=(char *)(i+1)- (char *)(i));
the difference is one byte .

how is it possible?
0
 
ozoCommented:
unless d is initialized to point to a valid object, the behavior is undefined
0
 
ozoCommented:
your previous sentence seems to be missing a clause, and I'm not sure what you are asking.
0
 
ozoCommented:
Are you trying to say that the difference between
(char *)(i+1)
and
(char *)(i)
is one byte?


(char *)(i+1)
is not the same as
((char *)i)+1
0
 
nagaharikolaAuthor Commented:
Please consider that *I is initialized
 and the folowing expression is used size=(char *)(i+1)- (char *)(i));
differnce of (char *)(i+1) and (char *)(i) is 8 bytes
but differenceof address of (char *)(i+1) and address of (char *)(i) is 1byte
0
 
ozoCommented:
what do you mean by address of (char *)(i+1) and address of (char *)(i) ?
(char *)(i+1) and  (char *)(i)  are not lvalues, so do not have an address
0
 
nagaharikolaAuthor Commented:
so do you  say that the code is not correct and by coincidence it is givig right answer
0
 
nagaharikolaAuthor Commented:

double *i; //assume i initialized
int size;

// below line is not understood by me;
size=(char *)(i+1)- (char *)(i));

printf("size=%d",size);


This code is working fine and giving correct size for all object(char ,int ,double ,float,struct etc)
 but i dont know how it is working .
Request to explain the working of the code
please explain how this working.
0
 
ozoCommented:
If i points to a valid object of type double
and if the extra ) is removed.
then I would expect it to give the same answer as sizeof(double)
but I would still not want to use it.
0
 
ozoCommented:
If i points to a valid object of type double
then it is as if you had said
double i[1];
0
 
nagaharikolaAuthor Commented:
In that case can u give some code snippet to find the sizeof an object with out sizeof operator
0
 
ozoCommented:
so (char *)(i) would point to the lowest addressed byte of i[0] and (char *)(i+1) would point to the lowest addressed byte of i[1]
0
 
nagaharikolaAuthor Commented:
can u be bit clear
0
 
ozoCommented:
you are essentially doing
size=(char *)(&i[1])- (char *)(&i[0]);
0
 
theKashyapCommented:
Let me try..

If the question is why "(char *)(i+1) - (char *)(i))" instead of "(i+1) - i;" then the answer is it's not necessary. They should give you the same result.
As ozo said std says "When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object". AFAIK a pointer to an object of any type would point to the first byte in the object's storage, so casting to char * is redundant.

If you already knew that then perhaps your question is why does it work? Why doesn't it always return 1 (viz the sizeof(char))? Because I'm casting the pointers to char*.
Well, remember that the + (in i+1) is evaluated as i + sizeof(i). There is no char* involved in this. When the output of this (i+1) is casted to char*, it just forces the pointer point to first byte of the object (which I said above is unnecessary).
The - is evaluated as subtraction of two pointers. Each of type char* but pointing to beginning of two double objects allocated contiguously.
Thus you get the results as sizeof(double) and not sizeof(char).

If you want to understand the nerdy way then refer to "6.5.6 Additive operators" & "6.3.1.8 Usual arithmetic conversions" in C99 standard.

HTH
0
 
ozoCommented:
the (char *) cast is necessary so the - takes the difference between char pointers instead of the difference between double pointers
0
 
nagaharikolaAuthor Commented:
double *i;
int size;
size=(char *)(i+1)- (char *)(i));// assume i initialized

if i use printf("%u   ,%u",(char *)i, (char *)(i+1))
the addresses printed are   4215100   4215104
how is this happening though i typecasted the double pointer to char pointer



0
 
ozoCommented:
Did you expect the casting to a char * then casting to an int to give different values than casting directly to an int?

I don't think the language gives you any guarantees on that, one way or the other,
the only guarantee is that if you cast a double * to a char * then back to a double *
the result will compare equal to the original pointer.
0
 
nagaharikolaAuthor Commented:
even though I typecast to (char *) the difference is given as 8 why it so.
0
 
ozoCommented:
Were you expecting the typecast to change the difference?

Whether or not you cast to (char *), you are in any case doing an implicit cast to int
the result of casting a pointer to an int is implementation defined,
but in most implementations I can think of, casting to char * before casting to int would have no effect on the result.
0
 
nagaharikolaAuthor Commented:

line 1:double *d;
int size;
// below line is not understood by me;
line 2:size=(char *)(d+1)- (char *)(d));

As per my understanding only the vlaue pointed by i is casted but not the adress,as it is a int value
initially value pointed will be double so eight bytes will be allocated in line 1.
in line#2 d+1 means we incrementing the double pointer by 1 so next address is address of d plus 8 bytes.
casting to char pointer only the first byte is casted so the difference is 8
is this correct?
0
 
ozoCommented:
size=(char *)(d+1)- (char *)(d));
I assume you mean
size=(char *)(d+1)- (char *)(d);
As per my understanding only the vlaue pointed by i is casted but not the adress,as it is a int value
I'm not sure what you mean.  the value contained in d is the address of a double.
It is cast to the the address of a char.

initially value pointed will be double so eight bytes will be allocated in line 1.
line 1 does not allocate any space for the double, and leaved d uninitialized, which could lead to undefined behavior

in line#2 d+1 means we incrementing the double pointer by 1 so next address is address of d plus 8 bytes.
that would be a reasonable implementation when doubles are 8 bytes.

casting to char pointer only the first byte is casted so the difference is 8
is this correct?
the pointer is cast, not the double or the char, and you did a cast on both pointers, not just the first.
0
 
nagaharikolaAuthor Commented:

size is  the difference of the lower address bytes of the both the pointers

are we on the same page
0
 
ozoCommented:
sizeof is measured in units of the size of char
if you take the difference of double pointers, or of you cast the pointers to int,
you are not guaranteed to get the same result.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

  • 19
  • 13
Tackle projects and never again get stuck behind a technical roadblock.
Join Now