13

Possible Duplicate:
Why isn't the const qualifier working on pointer members on const objects?

Consider the following class that has a pointer member int *a. The const method constMod is allowed by the compiler even though it modifies the pointer data. Why doesn't the compiler make the pointer data const in the context of the const method? If a was just an int we wouldn't be allowed to modify it in a const method.

class ConstTest
{
    public:

    ConstTest(int *p): a(p) {}

    void constMod() const {
        ++(*a);
    }

    int *a;
};

I'm using g++ on linux.

Community
  • 1
  • 1
Matthew Smith
  • 6,165
  • 6
  • 34
  • 35
  • the only answer is "because it's like this", but I think most of us agree it's usually unexpected (at first), even though one can find reasons afterward. – Matthieu M. May 10 '11 at 06:33
  • C++ by default gives a so called bitwise constness - meaning it ensures that no single bit of object has been changed, so it just checks the address of the pointer – rank1 Apr 30 '14 at 16:02

7 Answers7

13

Inside constMod(), the declaration of a is treated as:

int *const a;

which means the pointer has a constant value, not what it points to. It sounds like you are expecting it to be treated as:

const int *a;

which is different.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 1
    Is that not clarifying the question without answering it...? – Tony Delroy May 10 '11 at 05:27
  • So why is that? Why not enforce const everything within a const method? Seems weird to treat pointer data as a side effect. – Matthew Smith May 10 '11 at 05:42
  • @Matt: That's just how C++ is. Imagine it were an integer instead of a pointer, and you cannot change the integer. What that integer means to *you* has nothing to do with its value. (It could be a counter, an age, etc.) Likewise, a pointers value has nothing to do with what it points at (we just happen to agree that a pointers value indicates an address, all the time, instead of various things like an integer can; but the analogy still holds). For what it's worth, the D language acts like you expect. – GManNickG May 10 '11 at 06:03
  • 3
    @Matt: To expand on GMan's analogy, consider if his integer is an index into an array, but the array is not owned by the class [perhaps it is passed into a const function]. Would you not expect `array[i] = 5` to work, even though `i` is const? – Dennis Zickefoose May 10 '11 at 06:09
7

The pointer itself is not modified, only the data pointed. Even if it sounds strange from a human point of view, from a compiler point of view, none of the member of the class are altered.

Bruce
  • 7,094
  • 1
  • 25
  • 42
4

It's just an ownership issue... there's no way the compiler can know if the pointed-to object is logically part of the object or not, so it's left for the programmer to police such issues. const members are allowed to perform operations with side effects, as long as they don't modify their own apparent value. It's not really any different from letting them call say std::cout::operator<<() or some other non-const function....

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
0

What is const in the above case is the pointer itself. You are not allowed to do ++a;. However, it doesn't prevent you from modifying the data being pointed to.

Asha
  • 11,002
  • 6
  • 44
  • 66
0

I believe because here you are trying to change the value where datamember is pointing to. If you try to modify the data member it would be error.

Meaning, you'll get error if you make a point to something else instead of changing the value

Mayank
  • 5,454
  • 9
  • 37
  • 60
0

const member functions will not allow you to modify it's members.

In your example, you have a pointer that points an int.

And in the const method, you are modifying the value that it is pointed to but not the pointer itself.

Try giving, ++a, which will actually modify the pointer value and will not be allowed in your const method.

liaK
  • 11,422
  • 11
  • 48
  • 73
0

Consider

const T immutable_object0;
const T immutable_object1;
const T* mutable_view = ...a condition... ? &immutable_object0 : &immutable_object1;
// then later you reseat
mutable_view = ...another condition... ? &immutable_object0 : &immutable_object1;

or

const int immutable_data[120]
const int* mutable_view = immutable_data;
for(const int* end = immutable_data + 120; mutable_view != end; ++mutable_view) {
  // can't modify *mutable_view
}

It's because pointers don't always have ownership. In some circumstances pointers are views to an object (first example) or are iterators into a raw array (second example). For those cases it doesn't make sense to restrict the operations available on the pointers just because the data pointed to is immutable (or seen as immutable).

The first example is a bit contrived but a valid version of it is when you use a pointer member to implement object association and you don't want the hassle of a reference member. Sometimes the pointed-to types happen to be const.

Luc Danton
  • 34,649
  • 6
  • 70
  • 114