Is it legal to have multiple const qualifiers?
GCC is correct.
A compiler should not compile the code. The reason is explicit [dcl.type.cv]/1:
There are two cv-qualifiers, const
and volatile
. Each cv-qualifier shall appear at most once in a cv-qualifier-seq.
You are allowed to add const
to an already const
type (template programming would be difficult if this were not possible). But you can't write const const
as per the above rule.
Is it legal to have multiple const qualifiers?
const const int a = 5;
No. The rule was already covered by other fine answer and another.
Note that this applies only to the grammar, and not to the type system in general. You can apply const to a const type alias:
using T = const int;
const T a = 5; // OK
Multiple cv qualifiers combined this way "collapse" into one.
Which compiler is right?
In the sense of "which compiler conforms to the standard": All of them.
Compilers are not required to reject ill-formed programs, nor are they required to accept them. Since all compilers issue a diagnostic message, they all conform to the standard. Quote:
[intro.compliance.general]
Although this document states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:
- If a program contains no violations of the rules in [lex] through [thread] and [depr], a conforming implementation shall, within its resource limits as described in [implimits], accept and correctly execute5 that program.
- If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
- If a program contains a violation of a rule for which no diagnostic is required, this document places no requirement on implementations with respect to that program.
5) “Correct execution” can include undefined behavior
Accepting an ill-formed program intentionally is called a "language extension".
I think this is ill-formed. [dcl.type]/2
As a general rule, at most one defining-type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a defining-type-specifier-seq, and at most one type-specifier is allowed in a type-specifier-seq. The only exceptions to this rule are the following:
const
can be combined with any type specifier except itself.- ...
So it's not allowed to repeat const
literally like const const int a = 5;
. (PS redundant cv-qualifications introduced by typedefs are allowed and would be ignored).