| 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
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > >