Various prototypes adopted by Clang, GCC for the same function
I would like to report a bug against Clang and GCC for adopting multiple incompatible prototypes for the same function.
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 will call "expected behavior". However, if the parameter is f
set to enum
or unsigned int
:
$ cat t2.c
typedef enum { m1 } t ;
t f();
unsigned int f();
$ gcc -c t2.c
$ clang -c t.c
When the return types in two separate declarations f
are simple enum
and unsigned int
neither GCC nor Clang will issue diagnostics. I would like to report this behavior as a bug. In the C11 standard in clause 6.2.7: 2, two programs t1.c and t2.c above undefined are executed:
6.2.7: 2 All declarations referring to the same object or function must be of a compatible type; otherwise, the behavior is undefined.
However, 6.2.7: 2 is not inside the Restrictions section , so the two compilers are allowed to do what they want with these undefined behaviors, including their silence. Is there any other proposal that would make diagnostics mandatory in a program like t2.c and would it be right to report no diagnostics as a compiler error? Or am I wrong in expecting the enumerated type is incompatible with unsigned int
?
source to share
The "expected behavior" for the first example is required by the constraints in C11 (n1570) 6.7 p4:
All declarations in the same scope that refer to the same object or function must specify compatible types.
As pointed out by your answer , enum types can be compatible with unsigned int
what they usually are in the case of Gcc :
Typically, type
unsigned int
if there are no negative values in the enumeration, otherwiseint
. If specified-fshort-enums
, then if there are negative values, it is the first ofsigned char
,short
andint
, which can represent all values, otherwise it is the first ofunsigned char
,unsigned short
andunsigned int
, which can represent all values.
(I couldn't find a suitable part in the Clang documentation, but I expect it to be the same.)
For the second example, diagnostics are required if and only if the enumeration type is incompatible with unsigned int
. If it is not, the behavior (outside diagnostics) of undefined follows the standard quote in the question.
OT: In C ++, the second code is not valid because enumeration types are themselves incompatible with other integer types.
source to share
I found the answer as I wrote the last sentence in the above question:
In t2.c. no undefined behavior. Each type listed is compatible with one simple integer type selected by the compiler. In the example t2.c, GCC and Clang have opted unsigned int
for enum
typedef'd compatibility as t
.
6.7.2.2:4 Each enumerated type shall be compatible with char, signed integer type, or unsigned integer type. The choice of type is implementation-defined, 128 but must be able to display the values of all enumeration members [...]
128) An implementation MAY delay the selection of an integer type until all the enumeration constants are visible.
source to share