5

If I use mutable with const pointer like this:

class Test
{
    public:
    mutable const int* ptr; // OK
};

It's working fine.

But, If I use like this :

class Test
{
    public:
    mutable int * const ptr; // Error
};

An error :

prog.cpp:6:25: error: const 'ptr' cannot be declared 'mutable'
     mutable int * const ptr;
                         ^
prog.cpp: In function 'int main()':
prog.cpp:11:7: error: use of deleted function 'Test::Test()'
  Test t;
       ^
prog.cpp:3:7: note: 'Test::Test()' is implicitly deleted because the default definition would be ill-formed:
 class Test
       ^
prog.cpp:3:7: error: uninitialized const member in 'class Test'
prog.cpp:6:25: note: 'int* const Test::ptr' should be initialized
     mutable int * const ptr;

Why does compiler give an error in second case?

4
  • 4
    What does an error message say? It is probably worth reading. Commented Oct 5, 2017 at 13:08
  • @VTT ide.geeksforgeeks.org/PWB4ti
    – Jayesh
    Commented Oct 5, 2017 at 13:10
  • 2
    Edit your question to include build errors. Copy-pasted verbatim, as text, in full and complete. Commented Oct 5, 2017 at 13:12
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Commented Oct 5, 2017 at 13:18

4 Answers 4

7

const int * ptr;

The first is a pointer to constant data, which means you can change the pointer and where it points to, but you can't change the data it points to.

int * const ptr;

The second is a constant-pointer to non-constant data, which means you must initialize the pointer in your constructor(s) and then you can't make it point anywhere else. The data it points to can be modified though.

The mutable part in both cases applies to the pointer, the actual member variable, not the data it points to. And since the variable can't be both mutable and constant at the same time you should get an error message for that.

5

The 2nd case causes error because mutable and const can't be mixed; mutable can only be used with non-const data member.

applies to non-static class members of non-reference non-const type and specifies that the member does not affect the externally visible state of the class (as often used for mutexes, memo caches, lazy evaluation, and access instrumentation). mutable members of const class instances are modifiable.

BTW the following code causes the same error.

class Test
{
    public:
    mutable const int x; // Error;
    mutable int const x; // ditto;
};

The 1st case is fine, because const int* is not a const pointer, but a pointer to const. That means it's fine to modify the pointer itself, and you can mark it mutable. (But you can't modify the pointee.)

BTW const pointer to const (e.g. mutable const int* const ptr;) causes the same error too.

2
struct Test
{
    const int* ptr;
};

Translation: "The structure has a member. The member is a pointer. The pointer points to an integer which may not be mutated via the pointer."

The pointer itself may be mutated though, to point to a different const int.

It's probably simpler if we pick a non-reference type, so you can separate the types of the member (in your example a pointer), from the type of the pointed-to object.

struct Test1
{
    int value;
};

Now, adding the mutable keyword to get

struct Test2
{
    mutable int value;
};

just means we're allowed to mutate the member even when the structure itself is otherwise const.

In other words, all of this is OK in both cases:

Test1 a { 123 };
Test2 b { 123 };

// now mutate the object through a non-const reference
a.value = 42;
b.value = 42;

but this is different:

const Test1& ca = a;
ca.value = 69; // NO, a member of a const object is const

const Test2& cb = b;
cb.value = 69; // OK, a mutable member of a const object

So, now that we understand how mutable is being applied, the consider the problematic line:

mutable int * const ptr;

This is saying that ptr is both mutable (able to be mutated even when the object it's a member of is otherwise const) and const (not able to be mutated even when the object it's a member of is otherwise non-const).

The two are obviously contradictory.

1

The bugs.eclipse.org say's:

The mutable specifier can be applied only to names of class data members (9.2) and cannot be applied to names declared const or static, and cannot be applied to reference members.

Not the answer you're looking for? Browse other questions tagged or ask your own question.