簡體   English   中英

Clang,GCC接受的不同原型具有相同的功能

[英]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設置為返回enumunsigned int

$ cat t2.c
typedef enum { m1 } t ;

t f();

unsigned int f();
$ gcc -c t2.c
$ clang -c t.c

f的兩個單獨聲明中返回的類型是簡單的enumunsigned 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的第一個, shortint可以表示所有值,否則它是unsigned charunsigned shortunsigned int ,可以表示所有值價值。

(我在Clang文檔中找不到相應的部分,但我希望它是相同的。)

對於第二個示例,當且僅當枚舉類型與unsigned int不兼容時才需要診斷。 如果不是,則根據問題中的標准引用,未定義行為(超出診斷范圍)。

OT:在C ++中,第二個代碼無效,因為枚舉類型本身就是類型,與其他整數類型不兼容。

暫無
暫無

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

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