2014-12-04 54 views
3

我想報告針對Clang和GCC的錯誤,以接受同一功能的多個不兼容原型。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也不鏘發出診斷。我想將此行爲報告爲一個錯誤。在C11標準中,6.2.7:2使上述兩個程序t1.c和t2.c中的行爲不明確:

6.2.7:2引用同一對象或函數的所有聲明都應該兼容類型;否則,行爲是不確定的。

然而,6.2.7:2不是約束部分裏面,所以兩種編譯器被允許這樣做,他們希望這些不確定的行爲,什麼樣,包括接受他們默默地。是否有其他任何條款可以在像t2.c這樣的程序中使診斷成爲必需的,並且可以正確地報告缺少診斷作爲編譯器錯誤?或者我可能錯在期待枚舉類型與unsigned int不兼容?

+1

我認爲6.7 p4適用於(在一個約束部分):在同一範圍內引用同一對象或函數的所有聲明都應指定兼容的類型。如果它是無效的,則需要診斷。 – mafso 2014-12-04 10:40:41

+0

@mafso你回答了我的問題,儘管我沒有GCC bug報告,所以如果你把你的評論變成答案,我會接受它。 – 2014-12-04 17:17:21

回答

2

「預期行爲」爲第一個例子是由約束要求C11(n1570)6.7 P4:

在同一範圍內的所有聲明的是指相同的對象或功能必須指定兼容的類型。

由於your answer狀態,枚舉類型可能是unsigned int兼容的,他們通常是在Gcc情況:

通常情況下,該類型是unsigned int如果有枚舉中沒有負值,否則, int。如果指定了-fshort-enums,則如果存在負值,則它是可以表示所有值的第一個signed charshortint,否則它是可以表示所有值的第一個unsigned char,unsigned shortunsigned int

(我找不到鏘文檔中corresponging一部分,但我希望它是一樣的。)

對於第二個例子中,診斷是必需的,當且僅當枚舉類型與unsigned int不兼容。如果不是,則根據問題中的標準報價來定義行爲(超出診斷範圍)。

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

5

我找到了答案,因爲我寫的最後一句話在上面的問題:

有一個在t2.c.沒有未定義行爲每個枚舉類型都與一個由編譯器選擇的純整數類型兼容。在t2.c的例子中,GCC和Clang都選擇unsigned intenum類型兼容爲t

6.7.2.2:4每個枚舉類型應與char,有符號整數類型或無符號整數類型兼容。類型的選擇是由實現定義的,但是應該能夠表示所有枚舉成員的值

128)一個實現可以延遲選擇哪個整數類型,直到所有的枚舉常量已被看到。

相關問題