8

In C++, to declare an object of a class that has a member variable as const, we must have a user-defined default constructor. The following code illustrates this.

class Some {
    int value;
};

int main() {
    // error: default initialization of an object of const type 'const Some'
    //        without a user-provided default constructor
    const Some some;

    return 0;
}

However, if a member variable owned by a class is qualified as mutable, the compiler will not report any errors. For reference, I compiled using the command clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug. I wonder if this result is due to a bug in the compiler or according to the syntax defined in the C++ language.

class Some {
    mutable int value;
};

int main() {
    const Some some;

    return 0;
}
rosshjb
  • 581
  • 1
  • 8
  • 26
  • 2
    It should be noted that [GCC gives an error about it, and MSVC gives a warning that isn't directly related to it](https://godbolt.org/z/P_6eeU). – Some programmer dude Jan 21 '20 at 08:18
  • 4
    does this answer your question? [Why does C++ require a user-provided default constructor to default-construct a const object](https://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a) – Gaurav Dhiman Jan 21 '20 at 08:25
  • 2
    `mutable` is kind of the opposite of `const`. Why did you expect the same effect? – 463035818_is_not_an_ai Jan 21 '20 at 08:31
  • @ArdentCoder Member variables that are qualified with mutable are no different from variables with no qualifiers, except that they can also be changed in the const function. The link you posted doesn't seem to mention mutable-specific member variables, can you confirm it? – rosshjb Jan 21 '20 at 09:50
  • 1
    @ArdentCoder Even forcing [C++17](https://godbolt.org/z/CAaTm7), gcc produces an error, MSVC a warning, but clang only complains about the unused variables. [Using](https://godbolt.org/z/YRY8uC) somehow that variable, gcc still produces an error, MSVC still warns about the suspicious initialization and clang happily has UB. – Bob__ Jan 21 '20 at 10:43
  • @Bob__ I guess it's a bug because C++17 is very clear about this issue in its documentation. – Ardent Coder Jan 21 '20 at 11:05
  • 2
    Cause it makes no sense initializing an object to a `const`, meaning it can't be changed and having it have uninitialized values, there is no use for this sort of code and that is why it is forbidden. When you use the `mutable` keyword - it means that the value can be later changed, so the code can be used in a predictable manner. – Moshe Gottlieb Jan 21 '20 at 11:29
  • @MosheGottlieb It seems to be a logical and touching answer. thanks! – rosshjb Jan 21 '20 at 11:44
  • Does this answer your question? [Why does C++ require a user-provided default constructor to default-construct a const object?](https://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a) – Oktalist Jan 21 '20 at 13:08
  • 4
    @Does it? The OP are already aware that the first snippet is ill-formed, they wonder why clang accepts the second without any diagnostic. – Bob__ Jan 21 '20 at 13:42

1 Answers1

3

Rewriting my comment as an answer, hope it could helps someone.

It makes no sense declaring a const object if it is not initialized in some form.
Consider the following code:

    const int x;

clang says: error: default initialization of an object of const type 'const int'.
gcc would say: error: uninitialized const ‘x’ [-fpermissive]

The logic behind this is that there is no sense in this type of declaration.
The value of x can never change, and therefore this code would be unpredictable as x would be mapped to uninitialized memory.
In your example, adding the keyword mutable to value means that although the Some instance is constant when declared as:

    const Some some;

It is still possible to change value at a later time.
For example:

    some.value = 8;

This means it is possible to use this code in a predictable manner, since value can be set later, and there are no uninitialized constants.

Moshe Gottlieb
  • 3,963
  • 25
  • 41
  • If so, can we determine that there is a bug in gcc? When I compile the program with gcc, it reports an error even though the member variables are mutable. – rosshjb Jan 22 '20 at 15:26
  • 1
    Sorry @jinbeomhong - I don't know. I can only _guess_ the gcc team interprets the standard differently. – Moshe Gottlieb Jan 22 '20 at 15:42