UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C
  • » sizeof behaviour

#1 2007-04-19 07:38 AM

ananthbv
Member
Registered: 2007-04-13
Posts: 13

Re: sizeof behaviour

Please see the following program. the macro 'min' evaluates the minimum of X and Y. When i pass ++i as one of the args, it evaluates the value of i twice (as expected). but what i dont understand is why doesn't sizeof do the same, since sizeof is also a macro?

#define min(X, Y)  ((X) < (Y) ? (X) : (Y))

main ()
{
        int i = 5;
        int j = 10;
        int minimum;

        minimum = min(++i, j);

        printf ("i = %d\n", i);
        printf ("min = %d\n", minimum);

        sizeof (++i);
        printf ("i = %d\n", i);
}

The program prints out the values

i = 7
min = 7
i = 7

Offline

#2 2007-04-19 12:43 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: sizeof behaviour

sizeof() isn't a macro, it's a compiler built-in function. It returns the size of the storage space occupied by the argument you give, so what matters is its type, not its value.

Your code is wrong too, it should be "printf ("i = %d\n", sizeof(i));"

Offline

#3 2007-04-19 12:47 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: sizeof behaviour

No, you're mistaken: sizeof() is definitely NOT a macro...  It's a compiler feature...
The argument passed to sizeof() is never evaluated at all; that's why you can do
things like "sizeof (*uninitialized_ptr)", and not have your program crash...  The
compiler mearly uses the supplied arg to determine the proper type to obtain the
size of...

(Damn, beaten by i3839 again! ;-))

Offline

#4 2007-04-19 03:07 PM

ananthbv
Member
Registered: 2007-04-13
Posts: 13

Re: sizeof behaviour

Thanks i3839 and Rob for your replies! I thought sizeof(x) was implemented something like this:

#define sizeof(x) ((char *)&x + 1) - (char *)&x)

any idea how sizeof is implemented?

Offline

#5 2007-04-19 04:02 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: sizeof behaviour

The compiler implements it. The compiler knows the type and the allocated memory space, as it is the one doing all that.

(char *)&x + 1) won't work, because you're casting to char*, so your sizeof will always return 1.

#define sizeof(x) ((&x + 1) - &x) has more chance of working, but doing a &x + 1 is the same as (char *)&x + sizeof(x), which points out nicely that the compiler really needs to know the sizeof things to be able to handle them.

Offline

#6 2007-04-19 07:21 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: sizeof behaviour

I think he just left out an open-paren in there:

#define sizeof(x) ((char *)(&x + 1) - (char *)&x)

That'll actually work for SOME things...  (Without the "char*" casts, you might run
into other pointer-arithmetic issues doing the subtraction; maybe not, though...
Better would be to cast both sides of the subtraction to "size_t" or "ptrdiff_t" or
some integer-based type like that, since that's really what you want sizeof() returning...)

However, the main problem with such an implementation is that it just won't work
for some things that the real sizeof() works for...  Most importantly, it won't work
for plain type names...  You should be able to do stuff like "sizeof (int)" or "sizeof (long)",
and such a macro assumes you're always passing in a variable instead...  And, I'm
not convinced it would work (and don't feel like testing it ;-)) on a char buffer, because
the address would likely be treated as a simple "char*", yielding you a return value
of whatever your native pointer size is, rather than the actual buffer size, as it
SHOULD return...

As i3839 said, the compiler already knows the size of everything, so it can easily
implement it internally, with no need for preprocessor macros, anyway...  Perhaps
the fact that offsetof() is a macro mistakenly led you to believe sizeof() was, too?
That one really could be a compiler internal too, but it's usually a simple macro:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

Offline

#7 2007-04-19 07:40 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: sizeof behaviour

Offline

#8 2007-04-19 11:13 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: sizeof behaviour

Offline

#9 2007-04-20 12:55 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: sizeof behaviour

Probably not very portable, but...

$ cat /proc/self/maps 
08048000-0804c000 r-xp 00000000 08:03 2420115    /bin/cat
0804c000-0804d000 rwxp 00004000 08:03 2420115    /bin/cat
0804d000-0806e000 rwxp 0804d000 00:00 0          [heap]
a7e2c000-a7e2d000 rwxp a7e2c000 00:00 0 
a7e2d000-a7f52000 r-xp 00000000 08:03 2829835    /lib/libc-2.5.so
a7f52000-a7f53000 r-xp 00125000 08:03 2829835    /lib/libc-2.5.so
a7f53000-a7f55000 rwxp 00126000 08:03 2829835    /lib/libc-2.5.so
a7f55000-a7f59000 rwxp a7f55000 00:00 0 
a7f67000-a7f68000 r-xp a7f67000 00:00 0          [vdso]
a7f68000-a7f82000 r-xp 00000000 08:03 2829832    /lib/ld-2.5.so
a7f82000-a7f83000 r-xp 00019000 08:03 2829832    /lib/ld-2.5.so
a7f83000-a7f84000 rwxp 0001a000 08:03 2829832    /lib/ld-2.5.so
afac3000-afad8000 rw-p afac3000 00:00 0          [stack]

Offline

#10 2007-04-20 04:27 AM

ananthbv
Member
Registered: 2007-04-13
Posts: 13

Re: sizeof behaviour

Thanks a lot, once again!

Offline

  • Index
  • » C
  • » sizeof behaviour

Board footer

Powered by FluxBB