我有兩個用C編寫的包含相同頭文件的應用程序。在這個頭文件中我有一個結構的聲明。我使用GCC編譯器來編譯這兩個應用程序。sizeof爲同一個結構返回不同的值
當我執行這兩個應用程序時,它們產生不同的值sizeof(struct-defined-in-the-header)
。
爲什麼會出現這種情況?
我有兩個用C編寫的包含相同頭文件的應用程序。在這個頭文件中我有一個結構的聲明。我使用GCC編譯器來編譯這兩個應用程序。sizeof爲同一個結構返回不同的值
當我執行這兩個應用程序時,它們產生不同的值sizeof(struct-defined-in-the-header)
。
爲什麼會出現這種情況?
首先,確保做一切乾淨的構建。
如果問題仍然存在,這可能意味着兩個翻譯單元使用了不同的編譯選項。我將捕獲用於兩個編譯的命令行,並將比較它們,特別注意與對齊,結構填充等有關的任何選項。
另一種可能性是結構的定義取決於某些預處理器符號,並且這兩個符號被定義爲兩個翻譯單元的不同。使用gcc -E
並比較兩個預處理器輸出中的結構定義將是一個好的開始。
sizeof
是不是函數。它是一個編譯時操作符。
你不知道什麼標題給你帶來麻煩。
一個可能的猜測可能是一些不明確的預處理器技巧是刪除它中的某個字段或更改該字段的實際類型。例如,假設一個頭foo.h
有
// in file foo.h
#ifdef FOO_BAR
typedef short number_t;
#else
typedef long number_t;
#endif
,另一頭bar.h
有
// in file bar.h
#define FOO_BAR
#include "foo.h"
struct barbare_st {
number_t num;
char name[20];
};
爲了找到答案,你可以使用gdb
調試器的ptype
命令,或者直接查看到預處理形式xxx.i
部分文件xxx.c
用
gcc -C -E -Dappropriate_defines -Iinclude_dirs/ xxx.c > xxx.i
我使用Eclipse來編譯程序。我檢查了彙編的標誌。看看:
gcc -I/lib-header-directory-with-struct -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"program-a.d" -MT"program-a.d" -o"program-a.o" "../program-a.c"
gcc -I/lib-header-directory-with-struct -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"program-b.d" -MT"program-b.d" -o"program-b.o" "../program-b.c"
gcc -L/lib-directory-with-struct -o"program-b" -l<lib-with-struct>
他們之間的區別是,在一個我使用的lib和另一個我只使用結構定義。我使用了gcc -E
並將stdout重定向到文件。我在這個文件中查找結構定義,並且在兩個程序中都是一樣的。
由於這不是對原始問題的回答,所以應該將其添加到您的問題中。它可以被編輯。 –
正如Doc Brown所評論的那樣,有幾種可能性。你應該顯示代碼。不過,這是另一種猜測。
也許另一個變量是你的struct
陰影在其中一個案例?像:
extern struct { char foo; } bar;
void baz(void) {
long bar;
sizeof bar; /* will be sizeof(long) */
}
void qux(short bar) {
sizeof bar; /* will be sizeof(short) */
}
對我來說,它不是GCC,它是一個應用程序,但也有不同的.c文件的sizeof(MYSTRUCT)的不同的結果。 原因是結構的不同包裝值,因爲這些。在包含具有MyStruct聲明的頭文件之前,c文件包含了不同的.h文件集。 我採用的解決方案是創建通用標題,並設置適當的包裝值,並將其包含在系統和庫標題之後但在標題之前的所有.h文件中。
有幾個可能的原因,沒有關於這兩個應用程序之間的差異的更多信息,您將只獲得一些野生猜測或一些非常一般的建議。 –
這就是爲什麼你永遠不能對結構的大小作出假設。 – Kevin
@凱文:這有點誇張。我們當然可以假設'struct {char x,y; }'不小於2. –