By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,172 Members | 1,751 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,172 IT Pros & Developers. It's quick & easy.

sizeof operator implementation

P: n/a
hi,
if you see assembly then sizeof operator has sizeof(type) or
sizeof(variable) at compile time. How does C compiler gets value at
compiler time.?

How can we implement sizeof operator?

the implementation as macro is as below

#define sizeof_op1(val) (&val +1 ) - &val // for variable ex
sizeof_op1(n)

#define sizeof_op2(type) ((type*) (10) + 1) - (type*) (10) // for type
as sizeof_op2(int)

is there any other way to implemnent sizeof operator in C ? can we
implemnt sizeof_op2 as function. is there any way to combine above two
macros in one macro or function.

Thanks
vijay

Dec 7 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
vijay wrote:
hi,
if you see assembly then sizeof operator has sizeof(type) or
sizeof(variable) at compile time. How does C compiler gets value at
compiler time.?
It's the compiler: it does the right sums.
How can we implement sizeof operator?
By being the compiler-writer.
the implementation as macro is as below

#define sizeof_op1(val) (&val +1 ) - &val // for variable ex
sizeof_op1(n)
This is homework, isn't it. Oh well.

When this "works", it will get the answer `1`. It won't work for
things that don't have addresses or, more accurately, things that
aren't legal operands of &.

Conclusion: not useful. And you didn't test it.
#define sizeof_op2(type) ((type*) (10) + 1) - (type*) (10) // for type
as sizeof_op2(int)
This will /also/ get the answer `1` if it works, and that will
be by coincidence I think, since casting `10` to any pointer type
is at best iffy.

You didn't test this, either.
is there any other way to implemnent sizeof operator in C ? can we
implemnt sizeof_op2 as function.
No.
is there any way to combine above two
macros in one macro or function.
Not if you want a sensible answer.

--
Chris "Perikles triumphant" Dollin
"- born in the lab under strict supervision -", - Magenta, /Genetesis/

Dec 7 '06 #2

P: n/a
"Chris Dollin" <ch**********@hp.comwrote in message
news:el**********@murdoch.hpl.hp.com...
vijay wrote:
>if you see assembly then sizeof operator has sizeof(type) or
sizeof(variable) at compile time. How does C compiler gets value at
compiler time.?
....
>the implementation as macro is as below

#define sizeof_op1(val) (&val +1 ) - &val // for variable ex
sizeof_op1(n)

This is homework, isn't it. Oh well.

When this "works", it will get the answer `1`. It won't work for
things that don't have addresses or, more accurately, things that
aren't legal operands of &.

Conclusion: not useful. And you didn't test it.
Wouldn't this work (for some definition of "work") if you did:

#define sizeof_op1(val) ((char*)(&val+1)-(char*)(&val))

In fact, I can't see any reason that'd even invoke UB.
>#define sizeof_op2(type) ((type*) (10) + 1) - (type*) (10) // for
type
as sizeof_op2(int)

This will /also/ get the answer `1` if it works, and that will
be by coincidence I think, since casting `10` to any pointer type
is at best iffy.

You didn't test this, either.
The same trick as above (casting to char* before subtracting) should
"work" for this as well. However, it definitely invokes UB due to
casting 10 to a pointer type; might as well cast 0 and make what you're
doing obvious.

The real answer to this is there's no portable or even unportable way to
implement sizeof() in user code. That's why it's a core language
feature instead of being left to users to roll their own. Users cannot
add _operators_ to C; the problem is that sizeof() doesn't _look_ like
an operator to newbies -- it looks like a function or macro.

The far-simpler offsetof() can at least be implemented non-portably in
user code, but it's still included it in the language definition because
it's needed and there's no portable way to provide it. sizeof() has
much, much bigger problems and there's not even a non-portable way to do
it without specific compiler support -- at which point you might as well
have the compiler implement sizeof() itself.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
--
Posted via a free Usenet account from http://www.teranews.com

Dec 7 '06 #3

P: n/a
Stephen Sprunk wrote:
"Chris Dollin" <ch**********@hp.comwrote in message
news:el**********@murdoch.hpl.hp.com...
>vijay wrote:
>>if you see assembly then sizeof operator has sizeof(type) or
sizeof(variable) at compile time. How does C compiler gets value at
compiler time.?
...
>>the implementation as macro is as below

#define sizeof_op1(val) (&val +1 ) - &val // for variable ex
sizeof_op1(n)

This is homework, isn't it. Oh well.

When this "works", it will get the answer `1`. It won't work for
things that don't have addresses or, more accurately, things that
aren't legal operands of &.

Conclusion: not useful. And you didn't test it.

Wouldn't this work (for some definition of "work") if you did:

#define sizeof_op1(val) ((char*)(&val+1)-(char*)(&val))

In fact, I can't see any reason that'd even invoke UB.
Let's ignore the fact that you'd better put parentheses around "val" in the
expansion to avoid some of the sillier pitfalls. Even so, "sizeof_op1(char)"
is a syntax error and "sizeof_op1('0')" a constraint violation. If "f" is
declared as

void f(void);

then "sizeof_op1(&f)" and "sizeof_op1(f)" are both constraint violations (of
course, so is "sizeof f"). If "a" is declared as

int a[4];

then "sizeof_op1(a[4])" yields UB.

In C99, an expression not involving sizeof can never return correct results
for variable-sized arrays.

Even if we're very generous and restrict use of the macro to valid objects
of scalar type only, it will still yield UB on objects declared with
register class.

The sizeof operator has none of the above restrictions. But of course, you
did say "some definition of 'work'". So yes, for some definitions, I suppose
it works. But that's not really the point.
>>#define sizeof_op2(type) ((type*) (10) + 1) - (type*) (10) // for type
as sizeof_op2(int)

This will /also/ get the answer `1` if it works, and that will
be by coincidence I think, since casting `10` to any pointer type
is at best iffy.

You didn't test this, either.

The same trick as above (casting to char* before subtracting) should
"work" for this as well. However, it definitely invokes UB due to
casting 10 to a pointer type; might as well cast 0 and make what you're
doing obvious.
Casting 10 to a pointer type does *not* invoke UB, it invokes
implementation-defined behavior. Conversions of pointers to and from
integers are perfectly legal. What will most likely invoke UB is adding 1 to
the result, since it will probably not point to an object.

However, "casting 0" and then adding 1 to the result will *definitely*
invoke UB, since you're adding to a null pointer, which by definition cannot
point to any object.
The real answer to this is there's no portable or even unportable way to
implement sizeof() in user code. That's why it's a core language
feature instead of being left to users to roll their own.
Indeed. So it's not a good reason to suggest approaches to it anyway. There
be dragons.

S.

Dec 7 '06 #4

P: n/a
Skarmander wrote:
Stephen Sprunk wrote:
"Chris Dollin" <ch**********@hp.comwrote in message
news:el**********@murdoch.hpl.hp.com...
vijay wrote:
if you see assembly then sizeof operator has sizeof(type) or
sizeof(variable) at compile time. How does C compiler gets value at
compiler time.?
...
>the implementation as macro is as below

#define sizeof_op1(val) (&val +1 ) - &val // for variable ex
sizeof_op1(n)

This is homework, isn't it. Oh well.

When this "works", it will get the answer `1`. It won't work for
things that don't have addresses or, more accurately, things that
aren't legal operands of &.

Conclusion: not useful. And you didn't test it.
Wouldn't this work (for some definition of "work") if you did:

#define sizeof_op1(val) ((char*)(&val+1)-(char*)(&val))

In fact, I can't see any reason that'd even invoke UB.
Let's ignore the fact that you'd better put parentheses around "val" in the
expansion to avoid some of the sillier pitfalls. Even so, "sizeof_op1(char)"
is a syntax error and "sizeof_op1('0')" a constraint violation. If "f" is
declared as

void f(void);

then "sizeof_op1(&f)" and "sizeof_op1(f)" are both constraint violations (of
course, so is "sizeof f"). If "a" is declared as

int a[4];

then "sizeof_op1(a[4])" yields UB.

In C99, an expression not involving sizeof can never return correct results
for variable-sized arrays.
Are you saying that

#include <stdio.h>
int main(void) {
int n = 4;
int vla[n];
printf("%td\n", (char *) (&vla + 1) - (char *) (&vla));
}

is not guaranteed to print sizeof(vla)? If so, it is. Arithmetic on
pointers to VLAs behaves the same as ordinary pointer arithmetic.
The same trick as above (casting to char* before subtracting) should
"work" for this as well. However, it definitely invokes UB due to
casting 10 to a pointer type; might as well cast 0 and make what you're
doing obvious.
Casting 10 to a pointer type does *not* invoke UB, it invokes
implementation-defined behavior. Conversions of pointers to and from
integers are perfectly legal. What will most likely invoke UB is adding 1 to
the result, since it will probably not point to an object.
The standard says casting an integer to a pointer type may result in a
trap representation. This is not possible, since merely casting an
integer to a pointer type does not result in an object, and if there is
no object, there is no representation. The intent may or may not be
that simply casting 10 to a pointer type is allowed to result in
undefined behaviour, the standard is not clear. I'd say both Stephen
Sprunk's interpretation and yours are valid.

Dec 8 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.