Solved

sizeof operator

Posted on 2011-09-08
33
357 Views
Last Modified: 2012-05-12
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
Comment
Question by:nagaharikola
  • 19
  • 13
33 Comments
 
LVL 84

Expert Comment

by:ozo
Comment Utility
If you do not know how it works, you should not be using it.
0
 

Author Comment

by:nagaharikola
Comment Utility
I understand that...
But I want to know how it is treated internally.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Actually, since i is uninitialized, the behavior of the line in question is undefined.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 
LVL 84

Accepted Solution

by:
ozo earned 250 total points
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility
what happens when the following is done

double *d;
(char *)d
0
 

Author Comment

by:nagaharikola
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
unless d is initialized to point to a valid object, the behavior is undefined
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
your previous sentence seems to be missing a clause, and I'm not sure what you are asking.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility
so do you  say that the code is not correct and by coincidence it is givig right answer
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:nagaharikola
Comment Utility

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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
If i points to a valid object of type double
then it is as if you had said
double i[1];
0
 

Author Comment

by:nagaharikola
Comment Utility
In that case can u give some code snippet to find the sizeof an object with out sizeof operator
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility
can u be bit clear
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
you are essentially doing
size=(char *)(&i[1])- (char *)(&i[0]);
0
 
LVL 6

Expert Comment

by:theKashyap
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
the (char *) cast is necessary so the - takes the difference between char pointers instead of the difference between double pointers
0
 

Author Comment

by:nagaharikola
Comment Utility
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
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility
even though I typecast to (char *) the difference is given as 8 why it so.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility

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
 
LVL 84

Assisted Solution

by:ozo
ozo earned 250 total points
Comment Utility
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
 

Author Comment

by:nagaharikola
Comment Utility

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

are we on the same page
0
 
LVL 84

Assisted Solution

by:ozo
ozo earned 250 total points
Comment Utility
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now