On a search through the spec, it appears that my compiler isn't required to diagnose such mistakes as 

```
extern int a;
extern float a;

```

I previously thought that my compiler needs to diagnose that, but the spec says (emphasis added by me)

> 
> After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types speciﬁed by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound (8.3.4). **A violation of this rule on type identity does not require a diagnostic.**
> 
> 
> 

And in fact, I found cases where compilers don't care. For example, GCC and clang accept the following

```
void g() { int f(); } 
void h() { float f(); }

```

Since a violation of a rule for which no diagnostic is required means that the entire program requires no diagnostic at all anymore, it means that the following ill-formed program doesn't require a diagnostic either (see 1.4p2). Fortunately, both GCC and Clang diagnose them.

```
int f();
float f();

```

The behavior of this code at translation time is effectively undefined. What is the reason for this? Why can the spec not require such cases to be rejected and require these to be diagnosed?