tags:

views:

144

answers:

2

I'm sure there are sometimes good reasons for taking the sizeof() a #define in C, but I occasionally come across bugs where someone has taken the sizeof() a #define instead of the sizeof() a structure (and in my codebase I don't need to take the sizeof() a #define).

For example (contrived, but hopefully illustrates the point):

typedef struct my_struct
{
  fields
} MY_STRUCT;

#define MY_DEFINE 1234
my_size = sizeof(MY_DEFINE);  // Should be sizeof(MY_STRUCT)

Is there any easy, automated way to catch this?

Thanks for any help. NickB

+6  A: 

Well, no. Macros are macros. If the result of macro substitution is a valid expression (or type), then the code will compile. The compiler does not know what you want to do.

One thing that might help you (or not), is that in this specific example you want to sizeof a type as opposed to sizeof of an expression. If your coding standard insisted on always doing it through struct tag, as in

sizeof(struct my_struct)

then accidental mistakes like the specific one in your example would be less likely. Although other mistakes would not be.

You could probably replace your size of with a macro that somehow requires a type (and use it everywhere in place of ordinary sizeof). For example something like this

#define SIZE_OF_TYPE(T) ((T *) 0, sizeof(T))

would fail to compile with non-type argument. But it also will fail to compile with some type arguments.

Actually I don't know your context, but in general the whole idea seems counterproductive. A good programming practice is actually to avoid applying sizeof to types, preferring to apply it to expressions instead, as in

int *p = malloc(n * sizeof *p); /* good */

instead of

int *p = malloc(n * sizeof(int)); /* bad */

And you seem to want to move in the opposite direction.

AndreyT
+2  A: 

Why are you using ALL CAPS in your typedef'd name? A typedef is a C language construct, as opposed to a C preprocessor construct. It's an identifier, just like any other identifier.

If you only use all caps for MACROs, it will be pretty obvious when you're using them.

David Thornley
+1, Naming conventions can be a really helpful way of aiding the programmer
David Rodríguez - dribeas
FWIW, the Windows SDK does this all over the place. There's a gazillion names - I counted - that are all caps but not macros. I think for most part it's cruft from the very early days of Win16, but they're all still there (changing them would break too much stuff for little - if any - gain). MS may have even had a good reason to it way back then, but it was probably just that it was done in the early days of C programming (on PCs anyway), and they didn't know better. My point isn't that it's a good practice (it's not), just that it's a reality forced on us for a lot of code.
Michael Burr