我想知道GCC中float
的大小,而不必运行编译器。我知道一个选项是编写一个小函数并让编译器打印出一个汇编列表。
有limits.h
,其中包含最小值和最大值,但是有类似的东西可以告诉不同隐式类型的大小吗?
我在Windows 7 x64上使用GCC;目标平台是ARM7 32位模式。语言是C.
答案 0 :(得分:14)
您可以让GCC打印出所有默认宏:
gcc -dM -E - </dev/null | grep FLT
然后你得到如下行:
#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
答案 1 :(得分:9)
答案是4.任何合理的C实现都符合IEEE 754,它将float
(“单精度”)定义为32位二进制浮点类型,带有1个符号位,23个尾数位和8个指数位。在现实世界中,你永远不会遇到任何与此不同的东西。
由于您指定了GCC,因此这个答案更加明确。 GCC不支持float
不是32位的任何目标。
答案 2 :(得分:7)
假设您只是希望这可以帮助您确定目标系统上各种类型的大小,而无需在目标系统上实际运行程序,但您不打算将此作为某种工具集成进入构建系统,我可能会有一个黑客攻击...
hack确实需要运行编译器来编译程序,但是你不必在任何地方运行编译输出。实际上,这个hack旨在通过生成编译器错误来告诉您想要了解的内容。
这里的小宏将导致编译器吐出与给定类型的大小相对应的错误消息。它还会发出一条关于“搜索结束”的错误消息,以防你传递一个大于它检查的类型。这只是一个“方便”,提醒你去为宏添加更多行,这样它就能处理你好奇的类型。
一些主要限制是:
typedef
对于long double
这样的内容是必需的,如示例所示。)但是如果你对某种类型的大小感到好奇,并且不想在目标上实际运行一个程序来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
不同)希望这会有所帮助。实际上,有时候我会想要这个......通常,如果我对嵌入式目标上的结构体的大小感到好奇,我会在调试器中查找该信息,或者我必须在调试中进行调试{{ 1}}某个地方。
我认为这实际上更容易使用:
printf()
'来电'放入源文件SAY_SIZEOF()
'来电'答案 3 :(得分:1)
另一种选择可能是gdb:只需在没有任何程序的情况下运行它并执行sizeof(float)
。问题是你的目标和主机平台不一样,所以你必须在arm-gdb上运行它们。