Operator sizeof (AKA Reading Berkeley’s FM, take II)
Posted by: nico on
Mar 29th, 2010 |
Filed under: C++, Grumpy, Programming, WTF
Last time I told you about an evil snipet I found on Oracle Berkeley DB’s manual:
-
skey->size = sizeof((struct student_record *)pdata->data)->last_name;
A very subtle difference. Can you spot it? a and b will have the exact same value, rest assured. The difference is in the operator itself: sizeof MUST have parenthesis when applied to a type name, yet parenthesis are optional when applied to an instance of a datatype, so this code is legal:
-
MyClass x;
-
int a = sizeof(MyClass);
-
int b = sizeof x;
Oh, wait, the fun doesn’t stop there: sizeof also has bizarre precedence order, meaning it won’t get applied as you expect it. So, this is valid too:
-
struct MyClass { int y; } x;
-
int b = sizeof x->y;
Can you see where we are going? Knowing that sizeof will be applied last lets you write something like this too:
-
void *ptr = …
-
int b = sizeof((X*)ptr)->y;
Which means nothing else than “store in b the size of member y in struct X. It should be easy to see why BDB’s example does compile, and why did I spend half an hour trying to understand the reason it compiled fine.
By using some more casts and a clever arangement of parenthesis you can come up with a great job security device.




Add A Comment