Peter Pichler said:
I forgot to mention that in the newer version of the standard, C99, implicit
int was made obsolete, so lack of prototypes requires diagnostics. Just FYI.
The C99 foreword contains a laundry list of differences from C89.
One of the items in the list simply says "remove implicit int".
I've now seen several misinterpretations of what this means.
Here's what it really means: in C99, every declaration must
include a type-specifier, such as `char', `short', `int', `long',
`signed', or `unsigned'. That means that each declaration on the
left below is no longer allowed, and must be replaced by the
corresponding declaration on the right:
valid in C89 only valid in C89, C99
----------------- -----------------
const w; const int w;
static x; static int x;
typedef y; typedef int y;
extern z[]; extern int z[];
foo () {} int foo () {}
static bar () {} static int bar () {}
This change is an intentional consequence of a pair of fairly
minor changes from C89 to C99:
1. C89 contained the following language in section 6.5.2
"Type specifiers":
Each list of type specifiers shall be one of the
following sets (delimited by commas, when there is
more than one set on a line); the type specifiers may
occur in any order, possibly intermixed with the other
declaration specifiers.
...
- int, signed, signed int, or no type specifiers
...
C99 added the following sentence at the top of the
paragraph, which is now in section 6.7.2:
At least one type specifier shall be given in the
declaration specifiers in each declaration...
C99 also removed the choice `no type specifiers' from the
list of aliases for int.
2. C89 sections 6.7.1 "Function definitions" makes
declaration-specifiers optional in function-definition.
In C99, now in section 6.9.1, declaration-specifiers are
mandatory.
Now for what removal of "implicit int" does not mean:
* All of the following are valid declarations in both C89 and
C99, because all of them include a type-specifier. This is
admittedly confusing because the keyword `int' is indeed
implied in these declarations. It would be more accurate
to say that C99 removes "implicit type-specifier", not
"implicit int", but for whatever reason, the committee
didn't choose that wording.
short w;
long x;
signed y;
unsigned z;
* The following have always been invalid declarations:
x;
foo ();
The problem is that neither one of these includes any
declaration-specifier, whereas at least one is mandatory.
Three classes of syntax can be declaration-specifiers: a
type-specifier (already described), a type-qualifier
(`const', `volatile', and in C99 `restrict'), or a
storage-class-specifier (`typedef', `extern', `static',
`auto', `register'). Adding any of these to either of
these declarations will make it valid.
(If these constructions could be accepted as declarations,
then declarations would be ambiguous with statements at
block scope.)
Notwithstanding this, the following was valid in C89,
though it is no longer in C99:
foo () {}
The reason is that function definitions are subject to
syntax rules separate and somewhat different from other
declarations; see #2 above.
* In C89, undeclared functions could be called, with the
compiler assuming that the function returned `int'. In
C99, this is no longer true, but it is a separate change,
described in the foreword as "remove implicit function
declaration". So this is not, strictly speaking, removal
of "implicit int" either.