Re: A: a new bug to old plain C
LIU Hao via Gcc-help <[email protected]>
| Newsgroups | gmane.comp.gcc.help |
|---|---|
| Message-ID | <[email protected]> |
在 2025-11-26 14:14, Александр Поваляев via Gcc-help 写道:
> Hi there! So, any update on this?
>
> Could somebody point out where in the C standard a conversion "Foo**" ->
> "const Foo * const * const" is prohibited?
> Any link? Some quote from any book on C language?
>
You may download a copy of the draft of the C standard at
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf
I will quote the standard for you. I will add markers such as >>>>>>> and <<<<<<< which are not part of
the standard.
Your original question was about initialization:
6.7.11 Initialization
12 The initializer for a scalar shall be a single expression, optionally enclosed
in braces, or it shall be an empty initializer. If the initializer is not the
empty initializer, the initial value of the object is that of the expression
(after conversion); the same type constraints and conversions >>>>>>> as for
simple assignment apply <<<<<<<, taking the type of the scalar to be the
unqualified version of its declared type.
The constraint by simple assignment is:
6.5.17 Assignment operators
6.5.17.2 Simple assignment
1 One of the following shall hold
— the left operand has atomic, qualified, or unqualified pointer type, and
(considering the type the left operand would have after lvalue conversion)
both operands are pointers to >>>>>>> qualified or unqualified versions of
compatible types <<<<<<<, and the type pointed to by the left operand has all
the qualifiers of the type pointed to by the right operand;
And finally, the rules about compatible qualifiers are:
6.7.4 Type qualifiers
6.7.4.1 General
11 For two qualified types to be compatible, both shall have >>>>>>> the
identically qualified version <<<<<<< of a compatible type; the order of
type qualifiers within a list of specifiers or qualifiers does not affect the
specified type.
So, why doesn't `Foo**` convert to `const Foo* const* const` implicitly? It's simple. First, top-level
qualifiers are not meaningful and are ignored, like `int` converts to `const int`. Then, the first type
is a pointer to `Foo*`, but the second type is a pointer to `const Foo* const`, and these are not
'qualified versions of compatible types', because `Foo*` and `const Foo*` are not 'identically qualified'.
On the other hand, `Foo**` converts to `Foo* const*` implicitly. It's because the first type is a pointer
to `Foo*`, and the second type is a pointer to `Foo* const`, and these are 'qualified versions of
compatible types'. Actually. they are qualified versions of the same type.
The standard may look weird, but it's just the standard.
--
Best regards,
LIU Hao
OpenPGP_signature.asc
(application/pgp-signature, 840 B)
-----BEGIN PGP SIGNATURE----- wsF5BAABCAAjFiEEYmSQWY4DEzq4FUs4hfveZl3ogBsFAmkmpFYFAwAAAAAACgkQhfveZl3ogBvl TA//fGrs4CNbdCEGcSMeEdSipMwYUNR1PFl+WudU3AmgseQOiV8XpYtDTp/AIRuOKf5qCmAysBjM 2SvQ1UdTMV2J7A8Fb8FeJEUiILnNIM6NA7fhs1hGf5YN/xFaDMw6Jl0WcNWayTh032vE7CtGDucF NOCxpW+3e6jZOlpiYszZv1qhEBoS0KxIySi+JCObpz7X9mGtX//SEckrReYPXrKzhaLEGbD5wefg 7VFniADRVwl000GWvK7tACl+IK0w78HRc276ZVApiEDXLnqdigD4z9L4pSkYLnn5MOpQJpM4HkAy 5BxRmCz5Iju7In4RFBSi4TqRqkss03lx9FoIeFo1woBi61HWgt/qobqPEaYEQw+v8HEh0hK6q4eX g9htWsCkhbOvD/jjzb8YlGgP0XBS5fvFIVMu/5F28xEhCxTJwmNtNt1AaSuTskjCU/122mR1tlmh JDErAodUNeeiBu0EICEd5Ga0WApyJ2+i+7+HnP0K6kCgD0Hkza8UXf7erKXIrocm/BePpSjXtcx4 oskXxImPy/rb/mxUf0EL0YmHX7eNOkvJypJC8OeIC06QWdYVOZRhviYtpyhuZjge2LP5t/JTHAy8 pIcLqp+WykQlOauozgWxMRdBtHlam3A+nmPL//GNyf16gRwpIQW22NU6M2lUN3GE8pUP2EhDQs3C WOQ= =oc2a -----END PGP SIGNATURE-----