如何在编译时用C打印sizeof()的结果?

时间:2021-07-26 21:36:40

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.

如果不编写一个程序并执行它,就无法知道定制结构的大小。