I would like to report a bug against Clang and GCC for accepting 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 am going to call the “expected behavior”.
However, if f is set to return an enum or an unsigned 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. 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:
6.2.7:2 All declarations that refer to the same object or function shall have compatible type; 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. 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? Or am I perhaps wrong in expecting that an enumerated type be incompatible with unsigned int?