简体   繁体   English

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

[英]Different prototypes accepted by Clang, GCC for the same function

I would like to report a bug against Clang and GCC for accepting multiple incompatible prototypes for the same function. 我想报告一个针对Clang和GCC的错误,因为它接受了同一功能的多个不兼容的原型。

Consider the examples below: 请考虑以下示例:

$ 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.

Both GCC and Clang conform to what I am going to call the “expected behavior”. GCC和Clang都符合我所称的“预期行为”。 However, if f is set to return an enum or an unsigned int : 但是,如果将f设置为返回enumunsigned int

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

t f();

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

When the returned types in the two separate declarations of f are a simple enum and unsigned int , neither GCC nor Clang emit a diagnostic. f的两个单独声明中返回的类型是简单的enumunsigned int ,GCC和Clang都不会发出诊断。 I would like to report this behavior as a bug. 我想将此行为报告为错误。 In the C11 standard, clause 6.2.7:2 make the two programs t1.c and t2.c above undefined behavior: 在C11标准中,第6.2.7节:2使两个程序t1.c和t2.c高于未定义的行为:

6.2.7:2 All declarations that refer to the same object or function shall have compatible type; 6.2.7:2所有涉及同一对象或功能的声明均应具有兼容类型; otherwise, the behavior is undefined. 否则,行为未定义。

However, 6.2.7:2 is not inside a Constraints section, so the two compilers are allowed to do what they want with these undefined behaviors, including accepting them silently. 但是,6.2.7:2不在Constraints部分中,因此允许两个编译器使用这些未定义的行为执行他们想要的操作,包括静默接受它们。 Is there any other clause that would make a diagnostic mandatory in a program like t2.c, and would make it right to report the absence of diagnostic as a compiler bug? 是否有任何其他条款会在像t2.c这样的程序中强制执行诊断,并且会将缺少诊断作为编译器错误报告? Or am I perhaps wrong in expecting that an enumerated type be incompatible with unsigned int ? 或者我可能错误地认为枚举类型与unsigned int不兼容?

I found the answer as I was writing the last sentence in the above question: 当我在上面的问题中写下最后一句话时,我找到了答案:

There is no undefined behavior in t2.c. t2.c中没有未定义的行为。 Each enumerated type is compatible with one plain integer type, chosen by the compiler. 每个枚举类型都与编译器选择的一个普通整数类型兼容。 In the example t2.c, GCC and Clang have both chosen unsigned int to be compatible with the enum typedef'd as t . 在该示例中t2.c,GCC和锵兼得选择unsigned int以与兼容enum typedef为t

6.7.2.2:4 Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. 6.7.2.2:4每个枚举类型应与char,有符号整数类型或无符号整数类型兼容。 The choice of type is implementation-defined, 128 but shall be capable of representing the values of all the members of the enumeration […] 类型的选择是实现定义的, 128但应能够表示枚举的所有成员的值[...]

128) An implementation may delay the choice of which integer type until all enumeration constants have been seen. 128)实现可以延迟选择哪个整数类型,直到看到所有枚举常数。

The "expected behavior" for the first example is required by the constraints in C11 (n1570) 6.7 p4: C11(n1570)6.7 p4中的约束需要第一个示例的“预期行为”:

All declarations in the same scope that refer to the same object or function shall specify compatible types. 引用同一对象或函数的同一范围内的所有声明都应指定兼容类型。

As your answer states, enumeration types may be compatible with unsigned int , what they usually are in case of Gcc : 正如你的答案所述,枚举类型可能与unsigned int兼容,它们通常是Gcc的情况

Normally, the type is unsigned int if there are no negative values in the enumeration, otherwise int . 通常,如果枚举中没有负值,则类型为unsigned int ,否则为int If -fshort-enums is specified, then if there are negative values it is the first of signed char , short and int that can represent all the values, otherwise it is the first of unsigned char , unsigned short and unsigned int that can represent all the values. 如果指定了-fshort-enums ,那么如果有负值,则它是signed char的第一个, shortint可以表示所有值,否则它是unsigned charunsigned shortunsigned int ,可以表示所有值价值。

(I couldn't find the corresponging part in the Clang documentation, but I'd expect it to be the same.) (我在Clang文档中找不到相应的部分,但我希望它是相同的。)

For the second example, the diagnostic is required if and only if the enumeration type is incompatible with unsigned int . 对于第二个示例,当且仅当枚举类型与unsigned int不兼容时才需要诊断。 If it isn't, the behavior (beyond the diagnostic) is undefined as per the standard quote in the question. 如果不是,则根据问题中的标准引用,未定义行为(超出诊断范围)。

OT: In C++, the second code is invalid, as enumeration types are types on its own, incompatible with other integer types. OT:在C ++中,第二个代码无效,因为枚举类型本身就是类型,与其他整数类型不兼容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM