In the draft C++11 standard: N3337 I found several references to top-level cv-qualifiers
, but no definition.

- 154,301
- 39
- 440
- 740

- 1,065
- 8
- 12
-
There's a definition of cv-qualifiers, top-level is the standard english word, no need for a definition. – Deduplicator Jul 10 '14 at 12:41
-
2@Deduplicator as I note in my answer below there is a defect report no this and it was not rejected as `NAD` so I don't think it is obvious – Shafik Yaghmour Apr 14 '15 at 16:22
3 Answers
From Dan Saks's Top-Level cv-Qualifiers in Function Parameters:
In C++, a cv-qualifier that applies to the first level of a type is called a toplevel cv-qualifier. For example, in:
T *const p;
the top-level cv-qualifier is
const
, and in:T const *volatile q;
the top-level cv-qualifier is
volatile
. On the other hand:T const volatile *q;
has no top-level cv-qualifiers. In this case, the cv-qualifiers
const
andvolatile
appear at the second level.The signature of a function includes all cv-qualifiers appearing in that function’s parameter types, except for those qualifiers appearing at the top-level of a parameter type.
For example, in:
int f(char const *p);
the
const
qualifier is not at the top level in the parameter declaration, so it is part of the function’s signature.On the other hand, in:
int f(char *const p);
the
const
qualifier is at the top level, so it is not part of the function’s signature. This function has the same signature as:int f(char *p);
I couldn't find a definition in the standard either but what I posted above is explicitly stated in N3337 §8.3.5-5
After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type.
Edit: At the time of writing the above post a definition in the standard could not be found but now there's one as pointed out by Shafik:
n4296 excerpt:
In this International Standard, the notation cv (or cv1 , cv2 , etc.), used in the description of types, represents an arbitrary set of cv-qualifiers, i.e., one of {const}, {volatile}, {const, volatile}, or the empty set. For a type cv T, the top-level cv-qualifiers of that type are those denoted by cv. [Example: The type corresponding to the type-id const int& has no top-level cv-qualifiers. The type corresponding to the typeid volatile int * const has the top-level cv-qualifier const. For a class type C, the type corresponding to the type-id void (C::* volatile)(int) const has the top-level cv-qualifier volatile. — end example ]
In C++20 draft, N4713, the definition is found in §6.7.3 (5) ("CV-qualifiers" or [basic.type.qualifier])

- 55,411
- 20
- 125
- 222

- 43,032
- 26
- 132
- 246
-
1It seems like the Standard doesn't have a definition for `top-level cv-qualifiers`. I'm accepting your answer for the excellent article provided above. Thanks. – Mao Jul 10 '14 at 13:29
-
@juanchopanza well it is a creative way to infer the definition but I am not sure that `8.3.5p5` is well specified without a definition. Which as I note in my answer is now at least part of the latest draft, although it could change once it becomes C++17 t least this issue is tracked via a defect report. – Shafik Yaghmour Apr 14 '15 at 16:48
-
@ShafikYaghmour thanks for giving me the chance to go and take a peek in the new standard. It seems n4296 added that definition at the time of writing this – Marco A. Apr 14 '15 at 17:45
This question is the subject of defect report 609: What is a “top-level” cv-qualifier? which says:
The phrase “top-level cv-qualifier” is used numerous times in the Standard, but it is not defined. The phrase could be misunderstood to indicate that the const in something like const T& is at the “top level,” because where it appears is the highest level at which it is permitted: T& const is ill-formed.
and the proposed resolution suggests adding the following wording and note:
For a type cv T, the top-level cv-qualifiers of that type are those denoted by cv. [Example: The type corresponding to the type-id “const int&” has no top-level cv-qualifiers. The type corresponding to the type-id “volatile int * const” has the top-level cv-qualifier const. For a class type C, the type corresponding to the type-id “void (C::* volatile)(int) const” has the top-level cv-qualifier volatile. —end example]
Update
The defect has changed status to DRWP which means it is now part of the latest draft standard and we can find the new wording in N4527.

- 154,301
- 39
- 440
- 740
I only found one instance of the phrase in the standard, and
that was in a non-normative note. Lacking any other definition,
one must assume that the expression is interpreted as it would
be normally in English; that the qualifier is at the highest
level of the type declaration. Of course, we generally write
the declarations (in plain text, not in C++) from left to right,
not from up to down, but the usual rules apply: left comes
before right, and up comes before down. So for something like
char *const p
, we would write it (in English): "p is a const
pointer to char". (In this case, English is the exact opposite
of the order we would use in C++. This isn't always the case,
however.) Since the const
modifies pointer, which is the left
most (top) element, it is a top level qualifier.

- 150,581
- 18
- 184
- 329
-
2The left-most element in your example is `char`, which can also be qualified seperately from the pointer... Or are you talking about the English version? Your explanation is confusing. – rubenvb Jul 10 '14 at 13:15
-
@rubenvb I'm talking about the English version. Finding the top-most in the C++ version requires parsing. Which results in the English version, where it is left-most. – James Kanze Jul 10 '14 at 13:32
-
@rubenvb No. You have to parse the declaration into English, and then take the left-most. (Consider something like `void (*const fp)( char const* )`, where the first `const` is the top-most.) – James Kanze Jul 10 '14 at 15:05
-
Hm, with function pointers you'll have to ignore the arguments, and look at the function pointer variable's declaration, but still from right to left. For the record: `void(*const* fp)(char const* const)` has no top-level qualifiers. The right-most pointer in the `fp` part is unqualified. Anyways, C pointer syntax makes everyone's eyes bleed. – rubenvb Jul 10 '14 at 15:29
-
@rubenvb It's not just function pointers. It's anytime we use parentheses in the type. – James Kanze Jul 10 '14 at 17:01