> 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.
I don't understand the difficulty. As I said before in order to perform
assignment/initialization in C, you have to satisfy constraints
imposed by C standard on assignment/initialization. These contraints
are a bit convoluted, but if you make an effort you'll get through
them. Your code does not satisfy these constraints. It is a constraint
violation, i.e. what we normally call an "error".
> And so, I don't see that such conversion ("Foo**" -> "const Foo * const *
> const) is NOT explicitly prohibited by C standard.
It does not need a personal "explicit prohibition". If it does not satisfy
the constraints, it is prohibited. It is as simple as that.
> 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.
If you want language errors to be reported as "errors", and formally
correct yet questionable code to be reported as "warnings", then you
have to use '-pedantic-errors'. That's exactly what this flag is for.
However, GCC by default adheres to a different diagnostic approach:
"errors" are _aborting_ diagnostic messages, while "warnings" are
_non-aborting_
diagnostic messages. Note, that even when GCC encounters a hard language
error but still wants to act permissively, i.e. allow the code as a nonstandard
extension and continue to compile, it will report this hard error as a
"warning".
The separation is quite dynamic. For example, this code
int main(void) { int *p = 42; }
has always been a constraint violation in standard C. However, all the way
to GCC 13 it's been a "warning" by default, becoming an "error" only
in GCC 14.
You just found another example when a hard error formerly reported as
a "warning" by default eventually transitioned to an "error".
> But in our case, a conversion "Foo**" -> "const Foo * const * const" is an
> absolutely safe way of coding.
It does not matter. The only thing that matters is what the language
specification says. If it says that it is a constraint violation, then
it is a constraint violation. Period.
If you think it is "an absolutely safe way of coding", submit a proposal
to the committee, asking them to update the language specification.
But in this case you don't have to. We agree with you. It should be
allowed. And the work on allowing it is already underway.
--
Best regards,
Andrey