在没有编译的情况下确定`sizeof float`

我想知道GCC中float的大小,而不必运行编译器。 我知道一个选项是编写一个小函数并让编译器打印出一个汇编列表。

limits.h ,它包含最小值和最大值,但有没有类似的东西告诉不同的隐式类型的大小?

我在Windows 7 x64上使用GCC; 目标平台是ARM7 32位模式。 语言是C.

您可以让GCC打印出所有默认宏:

 gcc -dM -E -  

然后你得到如下行:

 #define __FLT_MANT_DIG__ 24 #define __FLT_MAX_EXP__ 128 

现在你可以解析如下:

 24 + lg(128) + 1 = 32 

要查找文档:

1) man gcc

  -E Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output. ... -dCHARS CHARS is a sequence of one or more of the following characters, and must not be preceded by a space. Other characters are interpreted by the compiler proper, or reserved for future versions of GCC, and so are silently ignored. If you specify characters whose behavior conflicts, the result is undefined. M Instead of the normal output, generate a list of #define directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor. Assuming you have no file foo.h, the command touch foo.h; cpp -dM foo.h will show all the predefined macros. 

2)实际的宏:

http://www.gnu.org/s/hello/manual/libc/Floating-Point-Parameters.html

答案是4.任何合理的C实现都符合IEEE 754,它将float (“单精度”)定义为具有1个符号位,23个尾数位和8个指数位的32位二进制浮点类型。 在现实世界中,你永远不会遇到任何与此不同的东西。

由于您指定了GCC,因此这个答案更加明确。 GCC不支持float不是32位的任何目标。

假设您只是希望这可以帮助您确定目标系统上各种类型的大小,而无需在目标系统上实际运行程序,但您不打算将此类工具集成到构建中系统,我可能有一个黑客为你…

黑客确实需要运行编译器来编译程序,但您不必在任何地方运行编译输出。 事实上,这个hack旨在通过生成编译器错误告诉您想要了解的内容。

这里的小宏将导致编译器吐出与给定类型的大小相对应的错误消息。 它还会发出一条关于“搜索结束”的错误消息,以防你传递的类型大于它检查的类型。 这只是一个“方便”,提醒你去为宏添加更多行,这样它就能处理你好奇的类型。

一些主要限制是:

  • 这太可怕了
  • 它以一种可怕的方式告诉你这些信息
  • 它只适用于可以表示为单个单词的类型(因此对于像示例中所示的long double这样的东西, typedef是必需的)。

但是如果你对某种类型的大小感到好奇,并且不想在目标上实际运行printf()信息,这可能有所帮助。

这是宏(s)以及它的一些使用示例:

 #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; } 

以下是使用GCC / MinGW 4.5.1编译该程序的原因:

 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 

所以,你可以很容易地看到:

  • float是4个字节
  • long double是12个字节
  • struct foo是8个字节
  • struct bar是12个字节(由于对齐/填充差异而不同于struct foo

希望这可以帮助。 实际上,有时候我会想要这个…通常,如果我对我的嵌入式目标上的结构的大小感到好奇,我会在调试器中查找该信息,或者我必须破解调试printf()某处。

我认为这实际上更容易使用:

  • 想知道有多大
  • SAY_SIZEOF() ‘call’放入源文件中
  • 按Shift-Ctrl-B(或任何热键是编译/构建),获取信息,然后
  • 删除SAY_SIZEOF() ‘call’

另一种选择可能是gdb:只需在没有任何程序的情况下运行它并执行sizeof(float) 。 问题是你的目标和主机平台不一样,所以你必须在你的arm-gdb上运行它们。