I would like to enable -Wstrict-prototypes
by default in all C language modes, and I would like to surface it as a warning which defaults to an error instead of a typical warning.
Background
C has the notion of functions with prototypes and functions without prototypes. A function with a prototype is one which specifies its parameter type list. A function without a prototype either uses an identifier list or empty parentheses. e.g.,
void func1(int a, int b); // Prototype
void func2(a, b) int a, b; {} // No prototype
void func3(); // No prototype, can be called with any number and type of arguments
Functions without prototypes have never been a recommended practice in any standard version of C. In fact, they were introduced into C89 as already being deprecated (see C89 3.9.4 and 3.9.5). After a 35+ year deprecation period, C2x will be removing support for functions with identifier lists (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2432.pdf) and will be changing the behavior of prototypeless functions with empty parentheses to match the behavior of C++ (N 2841: No function declarators without prototypes).
void f1(a, b) int a, b; {} // No longer syntactically valid in C2x
void f2(); // Changes meaning in C2x to be void f2(void);
void use(void) {
f2(1, 2); // Changes meaning in C2x, no longer valid
}
Justification
I would like to be aggressive about users migrating their code to functions with prototypes for several reasons:
-
There are substantial changes of behavior that users should be alerted to.
void f();
goes from accepting any number and type of arguments at the call site to accepting exactly zero arguments at the call site; certain syntactic constructs are now invalid -
Functions with prototypes are more secure than functions without prototypes due to the extra type information and type checking the prototype enables (EXP37-C. Call functions with the correct number and type of arguments - SEI CERT C Coding Standard - Confluence, CVE - CVE-2006-1174, MISRA C:2004, 8.1 - Functions shall have prototype declarations and the prototype shall be visible at both the function definition and call).
-
Ultimately, I want to remove
FunctionNoPrototype
from Clang. This type adds maintenance costs that are not born out from the functionality provided. To be clear, I donāt expect to removeFunctionNoPrototype
anytime soon, this is more of a 5-10 year plan.
By enabling the diagnostic as a warning which defaults to an error, I think we can take the aggressive stance while still giving users a reasonable migration path. Users who want to know about the prototype issues in their code base but not able to fix them all yet can use -Wno-error=strict-prototypes
to downgrade the error back into a warning. Users who have no interest in updating their code base case use -Wno-strict-prototypes
to disable the diagnostic entirely.
I have taken steps to prepare the clang and clang-tools-extra test suites to enable this diagnostic by default, which involved changing around 3000 test files. The vast majority of those changes were to give a function with an empty parameter list an explicit parameter of (void) because the lack of a prototype is not whatās being tested. The rest of the changes were to add -Wno-strict-prototypes
to test files that were incidentally testing functions without prototypes (e.g., when testing attribute functionality, testing whether the attribute applies to a K&R C function the same as a function with a prototype is āincidentalā). This leaves roughly 60 test files that are almost exclusively testing functions without prototypes. My intention is to downgrade the error diagnostic into a warning for the majority of these test files (and perhaps add #if __STDC_VERSION__
guards around the code blocks that wonāt work in C2x mode any longer) and add new expected warning flags where appropriate.
Fallout
I would like to hear folksā thoughts on this. As a WG14 representative for the Clang community, I donāt believe itās reasonable to continue to leave -Wstrict-prototypes
disabled by default. However, I still expect there to be fallout from enabling this diagnostic even as a warning. By failing to warn users about this for so long, thereās likely to be a fair amount of accidental uses of functions without prototypes in the wild that this will catch. The issues we had in our own test suite are likely to also hit downstream folks with their test suites, for instance. However, I do not think this is a case where we want to allow āthis is disruptive but I can migrate my codeā hold us back from making the change. The situations I think should hold us back from surfacing this as an error are more along the lines of āthere is no way to migrate my code to use a prototype because <specific reasons> and I need more time/features to solve that.ā