A: a new bug to old plain C

Александр Поваляев apovalyaev@gmail.com
Wed Nov 26 15:45:58 GMT 2025


Hi Matthias!!! Thank you a lot for jumping in this e-mail thread!

Many compilers (including Intel and Clang and some others) compile "Foo**"
-> "const Foo * const * const" conversion without errors.

The rationale why do we need "const" is pretty simple. To make our code
more error prone. And so to make some hint to compilers and may be to some
static syntax analyzers.
When I am writing code sometimes I need to specify and restrict behaviour
of some functions, to provide and supply something which is usually called
INVARIANT.
Let me post a little example here:

"
// PRE-CONDITION: ...
// POST-CONDITION: ...
// INVARIANT: array 'arg' and all its elements won't be changed

void subfunc(struct zzz const * const * const arg) {

if (arg != NULL) {
printf("%s", "Done!");
}
}

void func(struct zzz ** arr_of_ptr, unsigned count) {

subfunc((struct zzz const * const * const)arr_of_ptr); // ОК!

*subfunc(arr_of_ptr);* // CLANG: x86-64 clang (trunk) - WARNING!!!
// GCC: x86-64 gcc (trunk) - ERROR!!!
// INTEL: x86-64 icc 2021.10.0 - OK!!!
// MICROSOFT(c++?): x64 msvc v19.latest - OK!!!
// POWER64 GCC trunk - ERROR!!!
// ARM gcc(trunk) - ERROR!!!
// NOTE: based on godbolt.org
}".

There is a function "subfunc" and its INVARIANT is "array arg and its
elements won't be changed".
So, how should I design this part of code?
Right. One of the way to create a function "subfunc" with a parameter of
"Foo const * const * const" type.
And this is what I am doing.
So, when the "subfunc" is implemented, I can use it and make a call
"subfunc(arr_of_ptr)".

And here is the place where "our conversion under question" comes into play.
As I noted some of the compilers return an error, some - not. So, this is a
gray area.

I can make an implicit conversion like "subfunc((struct zzz const * const *
const)arr_of_ptr);" and it will work fine.
So, this is a kind of thing which can be gotten around.

It looks like a warning, and it might be a warning while compiling (saying,
that such kind of behavour is not a good "safe programming"
practice on something like this). And many compilers do it, they return a
warning giving all the necessary information.

But why some of the compilers return an error????
While some of our colleagues are still looking through C standard to find
out answer.

Is it actually an error???
What kind of error? Is it logical error? System fault?
Is it an error just because there is some tricky way to get around 'const'
qualifier and make an assignment in the end?

Respectfully,
Aleksandr G Povaliaev.






ср, 26 нояб. 2025 г. в 10:19, Matthias Pfaller <leo@marco.de>:

> On 2025-11-26 07:27, Simon Richter wrote:
> > Hi,
> >
> > On 11/26/25 3:14 PM, Александр Поваляев via Gcc-help wrote:
> >
> >> Could somebody point out where in the C standard a conversion "Foo**" ->
> >> "const Foo * const * const" is prohibited?
> >
> > It's disallowed because
> >
> >     void foo(int const *const p)
> >     {
> >         int *nonconst_p;
> >         int *const *const pp = &nonconst_p;
> >         *pp = p;
> >         *nonconst_p = 42;
> >     }
> >
> > would allow overwriting a variable passed in as pointer-to-const.
> >
> >    Simon
>
> Sorry Simon,
>
> *pp = p;
>
> would not be possible because "*pp" is marked as const  in the declaration
> of pp. It
> really hurts that I have to pour additional fuel into the fire...
>
> regards, Matthias
>
>


More information about the Gcc-help mailing list