AW: A: a new bug to old plain C

<[email protected]>
Newsgroups gmane.comp.gcc.help
Message-ID <[email protected]>
Refering to that example

int compare (const void *a1, const void *b1) {
  char *const *a = a1;
   ...

Here a and a1 have a different types.

void foo(char **x1) {
  char const * const *  const x = x1;
...

Here "char const * const" is treated as a different type as "char *" and now results in an error.

The expected behavior is: Adding const anywhere does not change the type.

**BUT**

void f(const char **cpp) {
    *cpp = "hello";   // assigns const char* into *cpp
}

void g() {
    char *p;
    f(&p);            // if allowed, p now points to "hello"
    *p = 'H';         // modifies a string literal → UB
}

The committee decided: better to reject all such conversions than to allow a silent hole that leads to undefined behavior.

GCC implemented it conforming to that rule.

Is it “futile”?
Yes, in one sense: C programmers can always cast away const explicitly. If someone wants to break the rules, they can. The compiler can’t stop malicious or careless code.

No, in another sense: The restriction catches accidental mistakes. Without it, you’d have code that compiles cleanly but corrupts string literals or read-only buffers at runtime. That’s the kind of bug that’s very hard to track down.

=> Live with it and close this thread.

> -----Ursprüngliche Nachricht-----
> Von: Gcc-help <[email protected]> Im Auftrag von
> Martin Uecker via Gcc-help
> Gesendet: Donnerstag, 4. Dezember 2025 21:40
> An: Александр Поваляев <[email protected]>; Александр Поваляев via
> Gcc <[email protected]>
> Cc: David Brown <[email protected]>; Andrey Tarasevich
> <[email protected]>; LIU Hao <[email protected]>; gcc-help <gcc-
> [email protected]>; Chris S <[email protected]>; Henrik Holst
> <[email protected]>; Jonathan Wakely <[email protected]>;
> Matthias Pfaller <[email protected]>
> Betreff: Re: A: a new bug to old plain C
> 
> 
> I was not involved in this decision, but I still think that making the defaults for C
> stricter is generally the right direction and I am happy that GCC did those
> changes.
> 
> 
> I agree with you though that for the specific case you point out it was bad and
> this should be changed (both in GCC and in the C standard), and ideally should
> have changed before switching the defaults.
> 
> But I am not sure how this email dicussion is in any way helpful.
> 
> 
> Martin
> 
> 
> Am Donnerstag, dem 04.12.2025 um 21:36 +0300 schrieb Александр
> Поваляев:
> > Hi Martin,
> >
> > I would like to believe in it.
> >
> > But the trend is right the opposite. 1.5 years ago the default behaviour of GCC
> pointers conversion was changed.
> > As for me, it added some mess and the description is not straight forward:
> > "
> > Type checking on pointer types (-Werror=incompatible-pointer-types)GCC no
> longer allows implicitly casting all pointer types to all other pointer types. This
> behavior is now restricted to the void * type and its qualified variations.
> > To fix compilation errors resulting from that, you can add the appropriate
> casts, and maybe consider using void * in more places (particularly for old
> programs that predate the introduction of void * into the C language).
> > " - The section looks like the change of parameter behaviour, but in reality it
> changed how type conversion is handled by default breaking 30years backward
> compatibility.
> >
> > The description was also accompanied by a small example (code snippet):
> > "
> > int
> > compare (const void *a1, const void *b1) {
> >   char *const *a = a1;
> >   char *const *b = b1;
> >   return strcmp (*a, *b);
> >
> > }
> > " which shows some possible unsafe conversion (Q: why they don't convert
> "const void*" -> "const char **a = a1" instead?) but it is irrelevant to the case
> which was discussed in this e-mail thread.
> >
> > Respectfully,
> > Aleksandr G Povaliaev.
> >
> >
> > ср, 3 дек. 2025 г. в 16:01, Martin Uecker <[email protected]>:
> > >
> > > I am not sure this has been pointed out, but you can downgrade this
> > > to a warning with -fpermissive.
> > >
> > > Otherwise, I do not quite I understand the point of this discussion.
> > > Somebody needs to write a patch downgrading the warning in this
> > > specific case (but not others that are problematic) to a pedantic
> > > warning.  I would assume that such a patch would have a good chance
> > > of being accepted.
> > >
> > > Martin
> > >
> > >
> > >
> > > Am Mittwoch, dem 03.12.2025 um 15:49 +0300 schrieb Александр
> Поваляев via Gcc:
> > > > Hi David! Thank you a lot for your time and postings!
> > > >
> > > > I agree that it should be an option and it should be a developer
> > > > decision whether to turn on/off pedantic errors.
> > > > But as for now, we have no option whether to treat such conversion
> ("Foo**"
> > > > -> "const Foo * const * const") as an error or warning.
> > > >
> > > > Up to version 13.4 GCC x86-64 also treats it as a warning by default.
> > > > So, if you compiles the following code snippet with x86-64 gcc
> > > > 13.4 ( godbolt.org was used) "
> > > > struct zzz {
> > > > unsigned x, y;
> > > > };
> > > >
> > > > void subfunc(struct zzz const * const * const arg) {
> > > >
> > > > if (arg != NULL) {
> > > > printf("%s", "Done!");
> > > > }
> > > > }
> > > >
> > > > void func(struct zzz ** arr_of_ptr, unsigned count) {
> > > >
> > > > subfunc(arr_of_ptr);
> > > > }
> > > > "
> > > > you will get only the warning.
> > > > So, starting from version 3.4.6 up to version 13.4 gcc x86-64 DOES
> > > > provide an option for decades.
> > > >
> > > > But then SOMETHING happened to version 14.1 of gcc x86-64, so it
> > > > started returning an error.
> > > > It BROKES BAKE COMPATIBILITY of safe conversion without any
> > > > reasoning. Is that right?
> > > >
> > > > The same change of default behaviour (when converting "Foo**" ->
> > > > "const Foo
> > > > * const * const") is observed within POWER gcc compiler:
> > > > it treated it as a warning starting from version 4.8.5 until the
> > > > version 13.4. Starting from 14.1 POWER GCC returns an error.
> > > > And the same story with versions happens for ARM GCC...
> > > >
> > > > ---------------------------------------------
> > > >
> > > > The interesting fact is that if you add "-std=c90 -pedantic"
> > > > compiler options, all the versions will work FINE! returning a warning.
> > > >
> > > > So, the BUG IS ABOUT CHANGING OF DEFAULT GCC BEHAVIOUR WHEN
> > > > CONVERTING "Foo**" -> "const Foo * const * const".
> > > > IT BROKES BACK-COMPATIBILITY WITHOUT ANY VISIBLE REASON AND IT
> > > > SHOULD BE FIXED!!!
> > > >
> > > > Respectfully,
> > > > Aleksandr G Povaliaev.
> > > >
> > > > P.S. This e-mail would be much shorter if it had been less
> > > > irrelevant examples and proofs.
> > > >
> > > >
> > > > ср, 3 дек. 2025 г. в 12:02, David Brown <[email protected]>:
> > > >
> > > > > This has been explained to you repeatedly, by many people, on
> > > > > both the gcc help list (which is for people asking for help
> > > > > about gcc, not for people needing help with the C language) and
> > > > > the gcc developers list (which is for discussing gcc development
> > > > > and is totally inappropriate for your posts).
> > > > >
> > > > > It has been explained to you, repeatedly, that the C standards
> > > > > could not and do not have a list of "explicitly prohibited"
> > > > > conversions.  They have a list of /allowed/ conversions.  You
> > > > > have been directed to these, with chapter and paragraph numbers
> > > > > and direct quotations from the standards.  The conversion you
> > > > > want is not allowed in C as of C23 (and before), though it is
> > > > > allowed in C++ and will likely be allowed in future C versions.
> > > > > The C standard term for "not allowed" here is "constraint
> > > > > violation".  In C, /nothing/ is allowed unless it is explicitly allowed in the
> standards.
> > > > >
> > > > > It does not matter if your use of this conversion is "safe" and
> > > > > gives correct working code with some compilers, or when you add
> > > > > explicit casts to your C.  What matters is that the rules of C do not allow
> it.
> > > > > Countless things can be considered "safe" and are yet not
> > > > > allowed by the C standards.
> > > > >
> > > > > When a conforming C compiler encounters a constraint violation -
> > > > > such as in your code - it is required to "issue a diagnostic".
> > > > > This typically means either a warning message (continuing
> > > > > compilation) or an error message (halting compilation).  A
> > > > > compiler implementation can choose either strategy.  Some
> > > > > compiler implementations will choose one, others will choose a
> > > > > different option - both are allowed.  Good compilers (including
> > > > > gcc and clang) offer command-line options to let you override the
> compiler's default actions here.
> > > > >
> > > > > So it is fine that clang gives a warning and continues
> > > > > compilation.  It is also fine that gcc gives an error and halts
> > > > > compilation.  (As a general rule, I believe compilers should be
> > > > > strict by default but allow less strict modes by compiler flags,
> > > > > so I personally prefer gcc's
> > > > > approach.)
> > > > >
> > > > > Neither gcc, clang, or any other compilers you tried have a bug
> > > > > here (unless they didn't even give a warning).
> > > > >
> > > > >
> > > > >
> > > > > No matter what any compiler does with your code, your C code is
> > > > > incorrect - it has a constraint violation.
> > > > >
> > > > >
> > > > > This has all been explained to you several times.  It is quite
> > > > > apparent that you do not have familiarity with the C standards -
> > > > > the definition of the language.  You are either incapable of
> > > > > understanding them, or have not bothered trying - despite being
> > > > > spoon-feed the relevant sections.  (No one expects you to read
> > > > > the entire standard.)  You are not qualified to judge what is
> > > > > and is not allowed in C, or what is or is not a bug in a
> > > > > compiler.  You can have your opinions, but they are not
> > > > > qualified or informed opinions, and as such they are worthless
> > > > > to everyone else.  (A qualified and informed opinion would be "I
> > > > > know this is not allowed in C, but I think it should be".)
> > > > >
> > > > >
> > > > > You should come away from all this with certain facts:
> > > > >
> > > > > 1. The conversion you want is not allowed in C.
> > > > >
> > > > > 2. It is extremely easy to write C code that /is/ valid, and
> > > > > works exactly as you want - add an explicit cast.
> > > > >
> > > > > 3. GCC is never going to consider this behaviour a bug, and is
> > > > > never going to change its behaviour here.
> > > > >
> > > > > I sincerely hope you understand facts 2 and 3 here.
> > > > >
> > > > > You can continue to beat your head against the wall claiming
> > > > > that 1 above is not true.  As long as it is your own head in the
> > > > > privacy of your own room, go for it.  It won't change reality.
> > > > >
> > > > > No one can force you to understand this.  But I hope that you
> > > > > can appreciate that your continued posts are a waste of
> > > > > everyone's time, and the practical way forward is just to change
> > > > > your code and stop posting on these mailing lists.  I don't
> > > > > think anyone will particularly care if you go away thinking "we
> > > > > agree to disagree", or even "they are wrong but won't admit it" - just as
> long as you go away.
> > > > >
> > > > > Please let this be an end to these posts to the gcc mailing
> > > > > lists.  If you want to email to me personally, go ahead - I am
> > > > > willing to try again to explain things to you if it stops you
> > > > > from wasting the time of thousands of list members.  But if you
> > > > > continue, then it is perhaps time for the list administrators to
> > > > > consider blacklisting you (I know that is a step they are always very
> reluctant to take).
> > > > >
> > > > >
> > > > >
> > > > > On 03/12/2025 07:38, Александр Поваляев via Gcc wrote:
> > > > > > Hi there! Thank you for being on it!
> > > > > >
> > > > > > You've written quite a lot of messages and replies. Thank you
> > > > > > again for this.
> > > > > >
> > > > > > However, I still don't see how you're proving that such a kind
> > > > > > of conversion must be rejected by any C compiler within an error.
> > > > > > Liu previously tried to do it (to provide logical reasoning),
> > > > > > but his
> > > > > prove
> > > > > > lacks some logical consistency.
> > > > > > And so, I don't see that such conversion ("Foo**" -> "const
> > > > > > Foo * const *
> > > > > > const) is NOT explicitly prohibited by C standard.
> > > > > > And still there is no sign that what is not explicitly
> > > > > > prohibited by C standard should end up with a compiler error.
> > > > > >
> > > > > > Per my understanding, an error "diagnostic" message should be
> > > > > > present
> > > > > only
> > > > > > if there is a possible way of getting the program working
> > > > > > wrong or
> > > > > leading
> > > > > > to fault.
> > > > > > And a warning "diagnostic" message should be present if there
> > > > > > is a
> > > > > possible
> > > > > > way of unsafe behavior.
> > > > > > But in our case, a conversion "Foo**" -> "const Foo * const *
> > > > > > const" is
> > > > > an
> > > > > > absolutely safe way of coding.
> > > > > >
> > > > > > This is the reason why commercial compilers (like
> > > > > > Microsoft/IBM and
> > > > > Intel)
> > > > > > DO support such a kind of conversion.
> > > > > > And so this is an artefact.
> > > > > > It appears when an absolutely safe way of coding which is not
> > > > > > explicitly prohibited by C standard is identified by an ERROR.
> > > > > >
> > > > > > I consider such behaviour as a BUG which should be fixed.
> > > > > > This is my attitude.
> > > > > >
> > > > > > Respectfully,
> > > > > > Aleksandr G Povaliaev.
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > ср, 3 дек. 2025 г. в 06:08, Andrey Tarasevich
> <[email protected]>:
> > > > > >
> > > > > > > It looks like we are getting nowhere here... To conclude
> > > > > > > this
> > > > > "discussion"
> > > > > > > I'll
> > > > > > > reiterate just the relevant points as concisely as I can:
> > > > > > >
> > > > > > > 1. Standard C language does not allow the following pointer
> > > > > > > conversions
> > > > > as
> > > > > > > implicit conversions:
> > > > > > >
> > > > > > >     T ** -> const T *const *
> > > > > > >     T ** -> const T *const *const
> > > > > > >
> > > > > > > A program that attempts to rely on such conversions (as
> > > > > > > implicit
> > > > > > > conversions) is
> > > > > > > invalid, i.e. it contains a constraint violation - a "hard
> > > > > > > error" in standard C.
> > > > > > >
> > > > > > > 2. Compliant C compilers are required to issue diagnostic
> > > > > > > messages for constraint violations. Format and wording of
> > > > > > > such diagnostic messages
> > > > > are
> > > > > > > not
> > > > > > > standardized in any way. Standard C does not have concepts of
> "errors"
> > > > > or
> > > > > > > "warnings".
> > > > > > >
> > > > > > > It is your responsibility to figure out that a diagnostic
> > > > > > > message issued for this constraint violation indicates a
> > > > > > > "hard error", provided you possess sufficiently pedantic
> > > > > > > knowledge of C standard. If you don't possess this level of
> > > > > > > knowledge of C standard (which is apparently the case in
> > > > > > > your case), but still want to write code in standard C,
> > > > > > > configuration settings like `-pedantic-errors` will help
> > > > > > > you. Moreover, in the latter case, you are not allowed to
> > > > > > > even approach C compilers without `-pedantic-errors`. Trying
> > > > > to
> > > > > > > do so
> > > > > > > will only lead to confusion.
> > > > > > >
> > > > > > > 3. If you do not have a "language-lawyer" level of knowledge
> > > > > > > of C standard, you do not get to make such bold statements
> > > > > > > as "I found a bug in C
> > > > > compiler".
> > > > > > > Which
> > > > > > > is well-illustrated by this thread: in this case there's no
> > > > > > > bug. The compiler is behaving 100% correctly, despite your
> > > > > > > claims to the contrary.
> > > > > > >
> > > > > > > 4. As it has been stated repeatedly, there's ongoing work
> > > > > > > aiming to support such conversions in future iterations of C
> > > > > > > language standard. But as of C23, these conversions are not
> > > > > > > supported (as implicit conversions).
> > > > > > >
> > > > > > > --
> > > > > > > Best regards,
> > > > > > > Andrey
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.