On 11/10/2023 12:17, Florian Weimer wrote:
* David Brown:

On 11/10/2023 10:10, Florian Weimer wrote:
* David Brown:

So IMHO (and as I am not a code contributor to GCC, my opinion really
is humble) it is better to be stricter than permissive, even in old
standards.  It is particularly important for "-std=c89", while
"-std=gnu89" is naturally more permissive.  (I have seen more than
enough terrible code in embedded programs - I don't want to make it
easier for them to write even worse code!)
We can probably make (say) -std=gnu89 -fno-permissive work, in a way
that is a bit less picky than -std=gnu89 -pedantic-errors today.


The gcc manual has "-permissive" under "C++ Dialect Options".  Are you
planning to have it for C as well?

Yes, I've got local patches on top of Jason's permerror enhancement:

   [PATCH v2 RFA] diagnostic: add permerror variants with opt
   
<https://inbox.sourceware.org/gcc-patches/20231003210916.1027930-1-ja...@redhat.com/>


That sounds like a good idea (perhaps with some examples in the
documentation?).  Ideally (and I realise I like stricter checking than
many people) some long-obsolescent features like non-prototype
function declarations could be marked as errors unless "-permissive"
were used, even in C89 standards.

For some of such declarations, this falls out of the implicit-int
removal.

Yes.


C23 changes meaning of of extern foo(); to match the C++ interpretation
of extern foo(void);.  I don't think we should warn about that.  If we
warn, it would be at the call site.

I'm not sure I fully agree. "extern foo();" became invalid when implicit int was removed in C99. But "extern T foo();", where "T" is void or any type, has changed meaning between C17 (and before) and C23.

With C23, it means the same as "extern T foo(void);", like in C++ (and like all C standards if it is part of the definition of the function). However, prior to C23, a declaration of "T foo();" that is not part of the definition of the function declares the function and "specifies that no information about the number or types of the parameters is supplied". This use was obsolescent from C90.

To my mind, this is very different. I think it is fair to suppose that for many cases of pre-C23 declarations with empty parentheses, the programmer probably meant "(void)". But the language standards have changed the meaning of the declaration.

IMHO I think calling "foo" with parameters should definitely be a warning, enabled by default, for at least -std=c99 onwards - it is almost certainly a mistake. (Those few people that use it as a feature can ignore or disable the warning.) I would also put warnings on the declaration itself at -Wall, or at least -Wextra (i.e., "-Wstrict-prototypes"). I think that things that change between standards, even subtly, should be highlighted. Remember, this concerns a syntax that was marked obsolescent some 35 years ago, because the alternative (prototypes) was considered "superior to the old style on every count".

It could be reasonable to consider "extern T foo();" as valid in "-std=gnu99" and other "gnu" standards - GCC has an established history of "back-porting" useful features of newer standards to older settings. But at least for "-std=std99" and other "standard" standards, I think it is best to warn about the likely code error.


(As a side note, I wonder if "-fwrapv" and "-fno-strict-aliasing"
should be listed under "C Dialect Options", as they give specific
semantics to normally undefined behaviour.)

They are code generation options, too.

I see them as semantic extensions to the language, and code generation differences are a direct result of that (even if they historically arose as code generation options and optimisation flags respectively). Perhaps they could be mentioned or linked to in the C dialect options page? Maybe it would be clearer to have new specific flags for the dialect options, which are implemented by activating these flags? Perhaps that would be confusing.


And of course there's still -Werror, that's not going to go away.  So if
you are using -Werror=implicit-function-declaration today (as you
probably should 8-), nothing changes for you in GCC 14.

I have long lists of explicit warnings and flags in my makefiles, so I
am not concerned for my own projects.  But I always worry about the
less vigilant users - the ones who don't know the details of the
language or the features of the compiler, and don't bother finding
out.  I don't want default settings to be less strict for them, as it
means higher risks of bugs escaping out to released code.

We have a tension regarding support for legacy software, and ongoing
development.

Agreed, and I fully understand that there is no easy answer here. On the one hand, you don't want to break existing code bases or build setups, and on the other hand you want to help developers write good code (and avoid bad code) going forwards.

I think we should draw the line at C99.  That's the first
language standard that removes most of these obsolescent features, after
all.


C99 removed implicit int and implicit function declarations (though these are still merely warnings by default in GCC!). Non-prototype function declarations were not removed until C23, and some things (minor issues, to be fair) have been explicitly marked obsolescent from C89 up to and including C23 !

Still, I fully agree with the principle of being stricter for later standards versions than older standards versions. Having had to maintain code where a function's definition, declarations and uses varied wildly in parameter types and count throughout a program, I am favour of anything that makes it harder for people to write such nonsense and claim "it compiles, let's ship it!".

I appreciate your taking the time to read and consider my opinions, whether you implement any of them or not. And - as always - thank you all for your work on GCC.

David

Reply via email to