How can I print the result of sizeof() at compile time in C?
如何在编译时用C打印sizeof()的结果?
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.
现在,我使用一个静态断言(基于其他web资源创建的home)将sizeof()结果与各种常量进行比较。虽然这工作……它既不优雅也不快速。我还可以创建变量/struct的实例并查看映射文件,但这也不如直接调用/命令/操作符来得优雅和快速。此外,这是一个使用多个交叉编译器的嵌入式项目……因此,构建并加载一个示例程序到目标中,然后读出一个值,比上面的任何一个都要麻烦。
In my case (old GCC), #warning sizeof(MyStruct)
does not actually interpret sizeof() before printing the warning.
在我的例子中(旧GCC), #警告sizeof(MyStruct)在打印警告之前并没有实际解释sizeof()。
4 个解决方案
#1
24
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?
是否可以在编译时打印c++类的大小?
Which gave me the idea for this:
这让我有了这样的想法:
char (*__kaboom)[sizeof( YourTypeHere )] = 1
Which results in the following warning in VS2015:
以下是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.
这里88就是你要找的尺寸。
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.
我还没有机会尝试使用gcc或clang,但是如果有人没有在我之前接触到的话,我将尝试确认它是否有效。
Edit: Works out of the box for clang 3.6
编辑:为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:
我为GCC工作的唯一诀窍是滥用-Wformat并让宏定义如下所示的函数:
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.
比最初的建议略显粗俗,但也许更了解gcc的人可以想出一个更好的警告。
#2
3
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 ==========
----- Build started: Project: cpptest, Configuration: Debug Win32 ---- cpptest。cpp(29): error C2196: case值“48”已经使用========== ==== Build: 0成功,1失败,0更新,0跳过========== ========== ========
So sizeof the struct X is 48
结构X的大小是48
#3
0
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:
我偶然发现了一个类似于Bakhazard的伟大解决方案的解决方案,而这个解决方案产生了一个更不详细的警告,所以您可能会发现它很有用:
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)
.
这是用最新版本的clang(1)测试的。
#4
-2
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中,你可以找到这样的例子:
gcc -dM -E - </dev/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.
如果不编写一个程序并执行它,就无法知道定制结构的大小。
#1
24
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?
是否可以在编译时打印c++类的大小?
Which gave me the idea for this:
这让我有了这样的想法:
char (*__kaboom)[sizeof( YourTypeHere )] = 1
Which results in the following warning in VS2015:
以下是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.
这里88就是你要找的尺寸。
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.
我还没有机会尝试使用gcc或clang,但是如果有人没有在我之前接触到的话,我将尝试确认它是否有效。
Edit: Works out of the box for clang 3.6
编辑:为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:
我为GCC工作的唯一诀窍是滥用-Wformat并让宏定义如下所示的函数:
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.
比最初的建议略显粗俗,但也许更了解gcc的人可以想出一个更好的警告。
#2
3
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 ==========
----- Build started: Project: cpptest, Configuration: Debug Win32 ---- cpptest。cpp(29): error C2196: case值“48”已经使用========== ==== Build: 0成功,1失败,0更新,0跳过========== ========== ========
So sizeof the struct X is 48
结构X的大小是48
#3
0
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:
我偶然发现了一个类似于Bakhazard的伟大解决方案的解决方案,而这个解决方案产生了一个更不详细的警告,所以您可能会发现它很有用:
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)
.
这是用最新版本的clang(1)测试的。
#4
-2
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中,你可以找到这样的例子:
gcc -dM -E - </dev/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.
如果不编写一个程序并执行它,就无法知道定制结构的大小。