[英]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.