繁体   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