Clang,GCC接受的相同功能的不同原型
我想报告针对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
设置为返回一个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也不锵发出诊断。我想将此行为报告为一个错误。在C11标准中,6.2.7:2使上述两个程序t1.c和t2.c中的行为不明确:
6.2.7:2引用同一对象或函数的所有声明都应该兼容类型;否则,行为是不确定的。
然而,6.2.7:2不是约束部分里面,所以两种编译器被允许这样做,他们希望这些不确定的行为,什么样,包括接受他们默默地。是否有其他任何条款可以在像t2.c这样的程序中使诊断成为必需的,并且可以正确地报告缺少诊断作为编译器错误?或者我可能错在期待枚举类型与unsigned int
不兼容?
“预期行为”为第一个例子是由约束要求C11(n1570)6.7 P4:
在同一范围内的所有声明的是指相同的对象或功能必须指定兼容的类型。
由于your answer状态,枚举类型可能是unsigned int
兼容的,他们通常是在Gcc情况:
通常情况下,该类型是
unsigned int
如果有枚举中没有负值,否则,int
。如果指定了-fshort-enums
,则如果存在负值,则它是可以表示所有值的第一个signed char
,short
和int
,否则它是可以表示所有值的第一个unsigned char
,unsigned short
和unsigned int
。
(我找不到锵文档中corresponging一部分,但我希望它是一样的。)
对于第二个例子中,诊断是必需的,当且仅当枚举类型与unsigned int
不兼容。如果不是,则根据问题中的标准报价来定义行为(超出诊断范围)。
OT:在C++中,第二个代码是无效的,因为枚举类型本身是类型,与其他整数类型不兼容。
我找到了答案,因为我写的最后一句话在上面的问题:
有一个在t2.c.没有未定义行为每个枚举类型都与一个由编译器选择的纯整数类型兼容。在t2.c的例子中,GCC和Clang都选择unsigned int
与enum
类型兼容为t
。
6.7.2.2:4每个枚举类型应与char,有符号整数类型或无符号整数类型兼容。类型的选择是由实现定义的,但是应该能够表示所有枚举成员的值
128)一个实现可以延迟选择哪个整数类型,直到所有的枚举常量已被看到。
我认为6.7 p4适用于(在一个约束部分):在同一范围内引用同一对象或函数的所有声明都应指定兼容的类型。如果它是无效的,则需要诊断。 – mafso 2014-12-04 10:40:41
@mafso你回答了我的问题,尽管我没有GCC bug报告,所以如果你把你的评论变成答案,我会接受它。 – 2014-12-04 17:17:21