Reputation: 3110
I have seen this complex declaration of sizeof operator somewhere in book which is teasing me:
#define SIZEOF(int) (int)&((int *)0)[1]
Can any one explain this declaration, whats going on here...?
Upvotes: 0
Views: 558
Reputation: 53037
Here it is with the [1]
part 'expanded':
(int)(&(*(((int*)0) + 1)))
Now do you see how it works?
The 0 will increase by the sizeof
int
due to the properties of pointer arithmetic and the final int
cast is getting you the value of the resulting address which is the 'size'.
It's totally undefined behavior though (the arithmetic on null and possibly the dereference of invalid pointer), fairly pointless.
The update with the macro parameter doesn't make much sense. The final cast should probably be std::uintptr_t
.
Upvotes: 6
Reputation: 318498
It defines SIZEOF
as the size of an integer.
(int *)0
is an int pointer at address zero[1]
accesses the next integer after that one.(int *)0
has the address zero, the one after it has the address sizeof int
as it comes right after the previous one.(int)
casts it to a number since a size is a number, not a pointer.Obviously it's a nasty hack, one should simply use sizeof int
.
Upvotes: 1
Reputation: 39807
First -- it's confusing things with the term int
-- we naturally assume that to be the keyword of a familiar type, however in this case it's not -- instead, it's the argument to the macro. So to simplify, consider the macro as follows:
#define SIZEOF(type) &((type *)0)[1]
Now looking at it this way, it's perhaps easier to see that the macro is first casting address 0 to be a pointer to type
, and then it's taking the address of the second element. This will reveal the size.
Upvotes: 4