False positives for -Wstrict-prototypes

Hello there!

Been working in C90 for a long time but always looked forward for the latest standards and love all the new features. Now, since XCode upgraded to the latest clang version, the -Wstrict-prototypes flag is on by default. Which I don’t mind, I always prototype my functions and it always worked with that flag turned on anyway.

But now I get a lot of false positives.

A very, ultimative, and extremely obvious,simple example is:

void test(void);
void test(){}

I get a warning that the function definition is missing a prototype. In my understanding, that should not happen.

Now, the problem can of course easily be resolved by just adding void to the parameter list of the function definition but that is not what I want to do, especially, since C23 will completely “legalize” the use of NO parameter at all. By that I mean, it will simply not matter whether we have a void or not in a few months time and I surely prefer the more modern style of writing no parameters.

I have no problem with the warning flag itself, I have a problem that this is a false positive. It almost looks to me like clang is simply treating any occurrence of a parameter list without content like K&R style. And that is a false assumption.

I’m ready to discuss and please correct me if there is a confusion on my side.

Cheers!

This seems fine to me as you’re not declaring C23 usage, so these do not, in fact, match. A clang-tidy lint for C23 code to suggest removing void parameter lists seems the way to go here longer-term.

CC @AaronBallman

@ben.boeckel I do not completely understand your answer. The two lines do indeed not match syntactically (one has void as parameter, the other has not) but according to standard, the first one is in fact a valid prototype and the second one is a matching definition. So, again, I do not see a warning reflecting correct behaviour. Secondly, I do not see using a linter being the way forward long term, because what is written in the two lines is correct and according to standard. Again, please correct me if I am wrong.

I have been investigating some different compilers (just by using https://rextester.com/) and indeed, clang 6 does not show this behavour very much the same as gcc 7.4.

Not sure if Apple changed something in their fork, but in upstream Clang, -Wstrict-prototypes isn’t on by default. It is intended to be opt-in for people who want to be extra strict.

The upstream default is instead for the diagnostic -Wdeprecated-non-prototype to be on by default. That one is designed to only warn about uses which are actually incompatible with C23 (e.g. calling a function declared without a prototype with more than zero arguments).

1 Like

This situation is a false positive, but it’s not one I expect we’ll fix. I left an explanation of what’s happening on this issue, but the gist of it is:

It’s technically a false positive to diagnose in that case, but I don’t think we’ll ever fix that bug because of the difficulties it presents to do so. We want to still catch cases like (void (*)()) as a type cast because that forms a function type without a prototype (and similar for typedefs, etc). This is why we diagnose when forming the type itself. There’s not a trivial way to retroactively say “nevermind, don’t issue that diagnostic about the type because we happened to merge with a function type that does have a prototype”; we’d have to delay issuing diagnostics (potentially until the end of the TU) which can then mess with the order in which diagnostics are issued in a confusing way (e.g., you get warnings about those functions well after you would get other diagnostics related to those functions), and because this is an off-by-default diagnostic in Clang, it seems like the false positive in that case is better than the alternatives.

Thanks @AaronBallman for the detailed answer. I presume, -std=c23 will omit this issue all together?

Correct, in C23, void f(void); and void f(); are the same types before doing declaration merging: Compiler Explorer

Thank you for clarification!

1 Like