This is the mail archive of the
mailing list for the glibc project.
non-prototype function definitions
> Thanks. Out of curiosity, why have old-style definitions persisted
> so long in the glibc source? I asked about this years ago, and,
> as I recall, Ulrich told me to buzz off without telling me why
> he thought it important to keep them old-style. (I asked
> because gnulib uses prototypes and there are clashes.)
I recall two issues. It's very plausible that both are obsolete with
recent compilers, but I don't know for sure. It's also quite plausible
that one or both was based on some misunderstanding in the past, but I
also don't know about that.
1. Ulrich claimed that the warning options in some past GCC versions were
broken in some way, so that using a non-prototype definition was the
only reliable way to get a warning about a missing declaration.
Today -Wmissing-prototypes should address this problem, and if it has
holes we'll just get the compiler fixed.
2. It's always been the intent that the libc ABI not include any function
signatures that might differ in their treatment between calls made with
a prototype declaration in scope and calls made without. Actually,
that's not quite true, since that's the case of any function taking
arguments of floating-point types. What I mean more precisely is
signatures that would differ in their treatment at call sites by a C89
compiler with a prototype and a pre-C89 compiler without a prototype.
So, we should never have arguments of integer types smaller than int or
of floating-point types smaller than double, for example. (Leaving
aside the *f math functions, where avoiding promotion to double is
the whole point of the interface.)
AIUI, in pre-C89 C, a definition like:
was essentially equivalent to:
char c = c_arg;
It's for this reason that the standard functions like strchr take an int
argument rather than a char. We always intended the whole of the libc
ABI to follow the example of C89's standard library API in this regard.
Once upon a time, GCC would give you a warning or error about:
extern void foo (char c);
because the definition didn't really match the declaration.
At least as of 4.6 for x86_64-linux-gnu targets, that's no
longer the case.
Nowadays we have -Wtraditional-conversion, but that only warns
about individual call sites that are actually affected this way.
There is no option I can find to warn about a declaration or
definition that is subject to this issue in the general case.
We still would like to preserve these two properties in the API/ABI:
that every public function has a prototype declaration in an installed
header file; and that every function works correctly when called
without a prototype declaration in scope. -Wmissing-prototypes ought
to be sufficient for the former, but we're not using it except under
the --enable-all-warnings configure option (which nobody actually
uses); we do use -Wstrict-prototypes, but that is not sufficient
unless we uniformly use non-prototype definitions as we once did.
Nothing is helping us with the latter AFAICT.
Using non-prototype definitions is not a necessary part of the
solution to either problem. It could be a part of solving the former,
but needn't be since -Wmissing-prototypes exists.