簡體   English   中英

在沒有編譯的情況下確定`sizeof float`

[英]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'放入源文件中
  • 按Shift-Ctrl-B(或編譯/構建的熱鍵),獲取信息,然后
  • 刪除SAY_SIZEOF() 'call'

另一種選擇可能是gdb:只需在沒有任何程序的情況下運行它並執行sizeof(float) 問題是您的目標和主機平台不一樣,因此您必須在arm-gdb上運行它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM