How can I print the result of sizeof() at compile time in C?

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

How can I print the result of sizeof() at compile time in C?

For now I am using a static assert (home brewed based on other web resources) to compare the sizeof() result to various constants. While this works... it is far from elegant or fast. I can also create an instance of the variable/struct and look in the map file but this is also less elegant and fast than a direct call/command/operator. Further, this is an embedded project using multiple cross-compilers... so building and loading a sample program to the target and then reading out a value is even more of a hassle than either of the above.

In my case (old GCC), #warning sizeof(MyStruct) does not actually interpret sizeof() before printing the warning.

回答1:

I was mucking around looking for similar functionality when I stumbled on this:

Is it possible to print out the size of a C++ class at compile-time?

Which gave me the idea for this:

char (*__kaboom)[sizeof( YourTypeHere )] = 1 

Which results in the following warning in VS2015:

warning C4047: 'initializing': 'DWORD (*)[88]' differs in levels of indirection from 'int' 

Where 88 in this case would be the size you're looking for.

Super hacky, but it does the trick. Probably a couple years too late, but hopefully this will be useful to someone.

I haven't had a chance to try with gcc or clang yet, but I'll try to confirm whether or not it works if someone doesn't get to it before me.

Edit: Works out of the box for clang 3.6

The only trick I could get to work for GCC was abusing -Wformat and having the macro define a function like the following:

void kaboom_print( void ) {     printf( "%d", __kaboom" ); } 

Which will give you a warning like:

...blah blah blah... argument 2 has type 'char (*)[88]' 

Slightly more gross than the original suggestion, but maybe someone who knows gcc a bit better can think of a better warning to abuse.



回答2:

All you need is a trick that causes the compiler to complain about some compile time integer values being used incorrectly, like duplicated case constant:

struct X {     int a,b;     int c[10]; }; int _tmain(int argc, _TCHAR* argv[]) {     int dummy;      switch (dummy) {     case sizeof(X):     case sizeof(X):         break;     }     return 0; } 

------ Build started: Project: cpptest, Configuration: Debug Win32 ------ cpptest.cpp c:\work\cpptest\cpptest\cpptest.cpp(29): error C2196: case value '48' already used ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

So sizeof the struct X is 48



回答3:

I stumbled upon a solution similar to Bakhazard's great solution, and this one produces a much less verbose warning, so you may find it useful:

char (*__fail)(void)[sizeof(uint64_t)] = 1; 

This produces the error message

Function cannot return array type 'char [8]' 

This was tested with the latest version of clang(1).



回答4:

You can't do this, not with structures. The preprocessor is invoked before compilation takes place, so there isn't even the concept of structure; you can't evaluate the size of something that doesn't exist / wasn't defined. The preprocessor does tokenize a translation unit, but it does so only for the purpose of locating macro invocation.

The closest thing you can have is to rely on some implementation-defined macros that evaluate to the size of built-in types. In gcc, you can find those with:

gcc -dM -E - /null | grep -i size 

Which in my system printed:

#define __SIZE_MAX__ 18446744073709551615UL #define __SIZEOF_INT__ 4 #define __SIZEOF_POINTER__ 8 #define __SIZEOF_LONG__ 8 #define __SIZEOF_LONG_DOUBLE__ 16 #define __SIZEOF_SIZE_T__ 8 #define __SIZEOF_WINT_T__ 4 #define __SIZE_TYPE__ long unsigned int #define __SIZEOF_PTRDIFF_T__ 8 #define __SIZEOF_FLOAT__ 4 #define __SIZEOF_SHORT__ 2 #define __SIZEOF_INT128__ 16 #define __SIZEOF_WCHAR_T__ 4 #define __SIZEOF_DOUBLE__ 8 #define __SIZEOF_LONG_LONG__ 8 

There is really nothing you can do to know the size of a custom struct without writing a program and executing it.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!