Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CV-qualified base classes in C++

While refactoring some C++11 code, I stumbled upon a strange thing. Namely, it seems to be impossible to define a CV-qualified (const, volatile or const volatile) base class, e.g:

struct A { int a = 0; };
struct B: A const {}; // Error here with Clang and GCC!

However, the following compiles without errors:

struct A { int a = 0; };
using AC = A const;
struct B: AC {};      // NO ERROR HERE!? Qualifiers are ignored.
int main() {
  B b;
  b.a = 42;           // NO ERROR modifying a field of const base.
  return b.a;
}

I have two questions:

  1. What in the C++ standards prohibits defining a CV-qualified base class, if at all?
  2. Why does the second example compile?

PS: Since this is a language-lawyer question, please provide references to the C++ standard.

like image 367
jotik Avatar asked Mar 11 '16 08:03

jotik


2 Answers

  1. The grammar prohibits it. The base classes are specified with the base-clause production specified at the start of section 10 of the standard. It eventually resolves to base-type-specifier, which is class-or-decltype, which is either a decltype construct or a nested-name-specifier[opt] class-name. Note that this leaves no place for a cv-specifier.

  2. The typedef name fits in the grammar. 9.1/5 says "A typedef-name that names a class type, or a cv-qualified version thereof, is also a class-name." The const is simply ignored.

  3. The const is simply ignored. Base class subobjects cannot be const on their own. 9.1/5 says "If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored."

like image 72
Sebastian Redl Avatar answered Oct 18 '22 01:10

Sebastian Redl


It is actually the full object you create that is const or not const, classes are not cv-qualified.

In using AC = A const; the const is simply ignored when used for inheriting.

like image 34
Jojje Avatar answered Oct 18 '22 00:10

Jojje