[英]Different prototypes accepted by Clang, GCC for the same function
我想報告一個針對Clang和GCC的錯誤,因為它接受了同一功能的多個不兼容的原型。
請考慮以下示例:
$ clang -v Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4) Target: x86_64-pc-linux-gnu … $ gcc -v … gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) $ cat t1.c int f(void); float f(void); $ gcc -c t1.c t1.c:3:7: error: conflicting types for ‘f’ float f(void); ^ t1.c:1:5: note: previous declaration of ‘f’ was here int f(void); ^ $ clang -c t1.c t1.c:3:7: error: conflicting types for 'f' float f(void); ^ t1.c:1:5: note: previous declaration is here int f(void); ^ 1 error generated.
GCC和Clang都符合我所稱的“預期行為”。 但是,如果將f
設置為返回enum
或unsigned int
:
$ cat t2.c
typedef enum { m1 } t ;
t f();
unsigned int f();
$ gcc -c t2.c
$ clang -c t.c
當f
的兩個單獨聲明中返回的類型是簡單的enum
和unsigned int
,GCC和Clang都不會發出診斷。 我想將此行為報告為錯誤。 在C11標准中,第6.2.7節:2使兩個程序t1.c和t2.c高於未定義的行為:
6.2.7:2所有涉及同一對象或功能的聲明均應具有兼容類型; 否則,行為未定義。
但是,6.2.7:2不在Constraints部分中,因此允許兩個編譯器使用這些未定義的行為執行他們想要的操作,包括靜默接受它們。 是否有任何其他條款會在像t2.c這樣的程序中強制執行診斷,並且會將缺少診斷作為編譯器錯誤報告? 或者我可能錯誤地認為枚舉類型與unsigned int
不兼容?
當我在上面的問題中寫下最后一句話時,我找到了答案:
t2.c中沒有未定義的行為。 每個枚舉類型都與編譯器選擇的一個普通整數類型兼容。 在該示例中t2.c,GCC和鏘兼得選擇unsigned int
以與兼容enum
typedef為t
。
6.7.2.2:4每個枚舉類型應與char,有符號整數類型或無符號整數類型兼容。 類型的選擇是實現定義的, 128但應能夠表示枚舉的所有成員的值[...]
128)實現可以延遲選擇哪個整數類型,直到看到所有枚舉常數。
C11(n1570)6.7 p4中的約束需要第一個示例的“預期行為”:
引用同一對象或函數的同一范圍內的所有聲明都應指定兼容類型。
正如你的答案所述,枚舉類型可能與unsigned int
兼容,它們通常是Gcc的情況 :
通常,如果枚舉中沒有負值,則類型為
unsigned int
,否則為int
。 如果指定了-fshort-enums
,那么如果有負值,則它是signed char
的第一個,short
和int
可以表示所有值,否則它是unsigned char
,unsigned short
和unsigned int
,可以表示所有值價值。
(我在Clang文檔中找不到相應的部分,但我希望它是相同的。)
對於第二個示例,當且僅當枚舉類型與unsigned int
不兼容時才需要診斷。 如果不是,則根據問題中的標准引用,未定義行為(超出診斷范圍)。
OT:在C ++中,第二個代碼無效,因為枚舉類型本身就是類型,與其他整數類型不兼容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.