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