aaronpuchert added a comment.

In D66919#1651108 <https://reviews.llvm.org/D66919#1651108>, @dexonsmith wrote:

> we just don't warn on non-prototype defining declarations, where the meaning 
> is unambiguous:
>
>   void foo() {}
>


"Meaning" is a difficult term. What we know is that this is a K&R-style 
definition, and does not define a prototype. So one would expect 
`-Wstrict-prototypes` to warn about this.

If you look at the section about function calls in the C11 standard (6.5.2.2), 
you can see that it distinguishes "Constraints" and "Semantics". Constraints 
are only placed on calls to prototype functions: "If the expression that 
denotes the called function has a type that includes a prototype, the number of 
arguments shall agree with the number of parameters. Each argument shall have a 
type such that its value may be assigned to an object with the unqualified 
version of the type of its corresponding parameter." Only in the semantics 
section we find something regarding calls to non-prototype functions: "If the 
expression that denotes the called function has a type that does not include a 
prototype, [...]. If the number of arguments does not equal the number of 
parameters, the behavior is undefined." So one is a compiler error, the other a 
runtime error (at best).

For me this warning is about usage of an "obsolescent" feature (6.11.6 and 
6.11.7), and thus should warn even when we can warn about wrong usage at call 
sites. Note that the warning is off by default and neither enabled by `-Wall` 
nor `-Wextra`.

In D66919#1651259 <https://reviews.llvm.org/D66919#1651259>, @aaron.ballman 
wrote:

> There are two different warnings, and perhaps we're speaking about different 
> ones. We have a warning about not having a prototype (warning: this function 
> declaration is not a prototype) and we have a warning about not seeing a 
> preceding prototype (warning: this old-style function definition is not 
> preceded by a prototype). I think this patch deals with the latter.


There is also `-Wmissing-prototypes`, which could have been named better. It 
warns about a definition (never a declaration) that doesn't have a preceding 
prototype declaration. It warns when there are preceding declarations that do 
not provide a prototype, and also when there is no preceding declaration at 
all, even if the definition itself does provide a prototype. It doesn't fire on 
`static` or `inline` definitions. I would describe the purpose of this warning 
as finding functions that should be declared `static`.

This warning (`-Wstrict-prototypes`) is rather straightforward: it warns on 
old-style (K&R) function declarators and enforces the usage of prototype 
declarations. (Well, with the caveat that among multiple non-definition 
declarations, only the first declaration needs to provide said prototype.) The 
purpose of this warning is to detect (perhaps unintentional) usage of the 
old-style unsafe declarator syntax.

So the warnings have some overlap, but I see their intention as different.

>> Given my understanding, then the only corner case that's left is when we 
>> *do* see the definition.
> 
> Yeah, and we already handle that situation with an un-ignorable warning: 
> https://godbolt.org/z/TPklNE

A non-prototype definition could be inline in a header. Now we have a warning 
that detects when we call the function with the wrong number of arguments, but 
users of the header might use a different compiler and not see a warning: the 
compiler is not required to diagnose this, as it's undefined behavior. Now if 
Clang warns me that this isn't a prototype, I'll fix it and users of the header 
with the hypothetical other compiler now get an error if they use it wrong.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66919/new/

https://reviews.llvm.org/D66919



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to