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

alt*_*dky 43 c sizeof compile-time

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

现在我使用静态断言(基于其他Web资源自酿)来将sizeof()结果与各种常量进行比较.虽然这有效但它远非优雅或快速.我还可以创建变量/ struct的实例并查看映射文件,但这比直接调用/命令/运算符更不优雅和快速.此外,这是一个使用多个交叉编译器的嵌入式项目......因此,为目标构建和加载示例程序然后读出一个值比上述任何一个都更麻烦.

在我的情况下(旧的GCC),#warning sizeof(MyStruct)在打印警告之前实际上并没有解释sizeof().

小智 56

当我偶然发现这个时,我正在寻找类似的功能:

是否可以在编译时打印出C++类的大小?

这给了我这个想法:

char (*__kaboom)[sizeof( YourTypeHere )] = 1;
Run Code Online (Sandbox Code Playgroud)

这导致VS2015中出现以下警告:

warning C4047: 'initializing': 'DWORD (*)[88]' differs in levels of indirection from 'int'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,88将是您正在寻找的大小.

超级hacky,但它的确如此.可能要晚了几年,但希望这对某人有用.

我还没有机会尝试使用gcc或clang,但是如果有人在我之前没有达到它,我会尝试确认它是否有效.

编辑:为clang 3.6开箱即用

我可以为GCC工作的唯一技巧是滥用-Wformat并让宏定义如下函数:

void kaboom_print( void )
{
    printf( "%d", __kaboom );
}
Run Code Online (Sandbox Code Playgroud)

哪个会给你一个警告:

...blah blah blah... argument 2 has type 'char (*)[88]'
Run Code Online (Sandbox Code Playgroud)

比原始建议稍微粗略一点,但也许有人知道更好的gcc可以想到更好的警告滥用.

  • 一年后访问此网站,我发现上述 gcc 解决方案不再有效(gcc 4.4.2)。经过更多搜索后,我发现http://stackoverflow.com/questions/21001044/is-there-a-way-to-define-a-member-offset-at-compile-time(使用一个数组到大,使用“-Wframe-larger-than”)仍然有效(您必须向下滚动到接受的答案,因为由于某种原因它不在顶部......)。 (2认同)

Rus*_*lan 11

以下方法适用于 GCC、Clang、MSVC 等,即使在旧版本中也是如此,它基于函数参数从指针到数组到标量类型的失败转换。编译器会打印数组的大小,因此您可以从输出中获取值。适用于 C 和 C++ 模式。

找出示例代码sizeof(long)在线玩):

char checker(int);
char checkSizeOfInt[sizeof(long)]={checker(&checkSizeOfInt)};
Run Code Online (Sandbox Code Playgroud)

相关输出示例:

  • 海湾合作委员会 4.4.7

<source>:1: note: expected 'int' but argument is of type 'char (*)[8]'

  • 叮当 3.0.0

<source>:1:6: note: candidate function not viable: no known conversion from 'char (*)[8]' to 'int' for 1st argument;

  • MSVC 19.14

<source>(2): warning C4047: 'function': 'int' differs in levels of indirection from 'char (*)[4]'


Jav*_*Man 8

所有你需要的是一个技巧,导致编译器抱怨一些编译时整数值被错误地使用,如重复case常量:

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;
}
Run Code Online (Sandbox Code Playgroud)

------构建开始:项目:cpptest,配置:调试Win32 ------ cpptest.cpp c:\ work\cpptest\cpptest\cpptest.cpp(29):错误C2196:大小写值'48'已经使用==========构建:0成功,1失败,0最新,0跳过==========

所以struct X的大小是48


Kon*_*nik 5

另一种方式(实际上有效):

char __foo[sizeof(MyStruct) + 1] = {[sizeof(MyStruct)] = ""};
Run Code Online (Sandbox Code Playgroud)

适用于较旧的gcc5.x。产生这样的错误:

a.c:8:54: error: initializer element is not computable at load time
a.c:8:54: note: (near initialization for 'a[8]')
Run Code Online (Sandbox Code Playgroud)

ps很明显,这是(非常)gcc特定的。所有其他方法都不适合我。

  • 您甚至不必指定数组的大小:`char __foo [] = {[sizeof(MyStruct)] =“”};` (3认同)

Fil*_*ves -5

你不能这样做,不能用结构。预处理器是在编译之前调用的,因此甚至没有结构的概念;您无法评估不存在/未定义的事物的大小。预处理器确实对翻译单元进行标记,但这样做只是为了定位宏调用。

您可以拥有的最接近的方法是依赖一些实现定义的宏,这些宏计算内置类型的大小。在 gcc 中,您可以找到以下内容:

gcc -dM -E - </dev/null | grep -i size
Run Code Online (Sandbox Code Playgroud)

在我的系统中打印:

#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
Run Code Online (Sandbox Code Playgroud)

如果不编写程序并执行它,您实际上无法知道自定义结构的大小。