![](/img/trans.png)
[英]How does this piece of code determine array size without using sizeof( )?
[英]Determine `sizeof float` without compilation
我想知道GCC中float
的大小,而不必運行編譯器。 我知道一個選項是編寫一個小函數並讓編譯器打印出一個匯編列表。
有limits.h
,它包含最小值和最大值,但是有類似的東西可以告訴不同隱式類型的大小嗎?
我在Windows 7 x64上使用GCC; 目標平台是ARM7 32位模式。 語言是C.
您可以讓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
答案是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'放入源文件中 SAY_SIZEOF()
'call' 另一種選擇可能是gdb:只需在沒有任何程序的情況下運行它並執行sizeof(float)
。 問題是您的目標和主機平台不一樣,因此您必須在arm-gdb上運行它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.