Assuming that you just want this to help you determine what the size of various types on your target system is without having to actually run a program on the target system, but you don't intend on this being some sort of tool integrated into a build system, I may have a hack for you...
The hack does require running the compiler to compile a program, but you don't have to run the compiled output anywhere. In fact, this hack is designed to tell you what you want to know by generating compiler errors.
The little macro here will cause the compiler to spit out an error message that corresponds to the size of the type given. It'll also spit out an error message about the 'end of the search' just in case you pass it a type that's larger than what it checks. That's just a 'convenience' to remind you to go add a bunch more lines to the macro so it'll handle the type you're curious about.
Some of the main limitations are:
- it's horribly hacky
- it tells you the information in a god-awful way
- it'll only work with types that can be expressed as a single word (so a
typedef
is necessary for things like long double
as shown in the example).
But if you're ever curious about the size of some type, and don't want to actually run a program on the target to printf()
the information, this may help.
Here's the macro(s) along with some examples of it being used:
#if !defined( PASTE)
#define PASTE2( x, y) x##y
#define PASTE( x, y) PASTE2( x, y)
#endif /* PASTE */
#define SAY_IF_SIZEOF( type, size) static char PASTE( PASTE( PASTE( sizeof_, type), _is_), size) [(sizeof(type) == (size)) ? -1 : 1]
#define SAY_SIZEOF_END(type) static char PASTE( end_search_for_sizeof_, type)[-1]
#define SAY_SIZEOF(type) \
SAY_IF_SIZEOF( type, 1); \
SAY_IF_SIZEOF( type, 2); \
SAY_IF_SIZEOF( type, 3); \
SAY_IF_SIZEOF( type, 4); \
SAY_IF_SIZEOF( type, 5); \
SAY_IF_SIZEOF( type, 6); \
SAY_IF_SIZEOF( type, 7); \
SAY_IF_SIZEOF( type, 8); \
SAY_IF_SIZEOF( type, 9); \
SAY_IF_SIZEOF( type, 10); \
SAY_IF_SIZEOF( type, 11); \
SAY_IF_SIZEOF( type, 12); \
SAY_IF_SIZEOF( type, 13); \
SAY_IF_SIZEOF( type, 14); \
SAY_IF_SIZEOF( type, 15); \
SAY_IF_SIZEOF( type, 16); \
SAY_SIZEOF_END(type)
//here's where you get to ask about the size of a type
SAY_SIZEOF(float);
typedef long double long_double;
SAY_SIZEOF(long_double);
struct foo {
char x;
short y;
int* p;
};
struct bar {
char x;
int* p;
short y;
};
typedef struct foo foo_t;
typedef struct bar bar_t;
SAY_SIZEOF(foo_t);
SAY_SIZEOF(bar_t);
int main(void)
{
return 0;
}
And here's what compiling that program with GCC/MinGW 4.5.1 says:
C:\temp\test.c:34:1: error: size of array 'sizeof_float_is_4' is negative
C:\temp\test.c:34:1: error: size of array 'end_search_for_sizeof_float' is negative
C:\temp\test.c:38:1: error: size of array 'sizeof_long_double_is_12' is negative
C:\temp\test.c:38:1: error: size of array 'end_search_for_sizeof_long_double' is negative
C:\temp\test.c:56:1: error: size of array 'sizeof_foo_t_is_8' is negative
C:\temp\test.c:56:1: error: size of array 'end_search_for_sizeof_foo_t' is negative
C:\temp\test.c:57:1: error: size of array 'sizeof_bar_t_is_12' is negative
C:\temp\test.c:57:1: error: size of array 'end_search_for_sizeof_bar_t' is negative
So, you can easily see that:
float
is 4 bytes
long double
is 12 bytes
struct foo
is 8 bytes
struct bar
is 12 bytes (different than struct foo
due to alignment/padding differences)
Hope this helps. Actually, there have been times when I would want this... Generally, if I'm curious about the size of a struct on my embedded targets I poke around in the debugger for that info or I have to hack in a debug printf()
somewhere.
I think this would actually be easier to use:
- wonder how big something is
- drop a
SAY_SIZEOF()
'call' into the source file
- hit Shift-Ctrl-B (or whatever the hotkey is to compile/build), get the info, and
- delete the
SAY_SIZEOF()
'call'