Hailiang Zhang
Hailiang Zhang

Reputation: 18870

why a C++ "const" function can modify its pointer-type member?

I have the following codes that failed compilation due to invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]

#include <iostream>
#include <stdlib.h>

using namespace std;

#define N 3

void f(int *p) 
{
    *p=8;
}

class A
{
    private:
        int a;
    public:
        void init() const;
        void print() const {cout<<a<<endl;}
};

void A::init() const
{
    f(&a);
}

int main()
{
    A a;
    a.init();
    a.print();
}

This is not surprising at all because of the "const" qualifier of the "init" function.

However, the following codes compiled and ran smoothly,

#include <iostream>
#include <stdlib.h>

using namespace std;

#define N 3

void f(void **pp)
{
    *pp = new int[N];
}

class A
{
    private:
        int * p;
    public:
        void init() const;
        void assign() {for (size_t i=0; i<N; i++) p[i]=i;}
        void print() const {for (size_t i=0; i<N; i++) cout<<p[i]<<" "; cout<<endl; }
        ~A(){delete [] p;} 
};

void A::init() const
{
    f((void**)&p);
}

int main()
{
    A a;
    a.init();
    a.assign();
    a.print();
}

Question: in the second case, why a "const" function (init) can modify its member (p)?

Upvotes: 0

Views: 198

Answers (1)

Ben Voigt
Ben Voigt

Reputation: 283664

Your C-style cast is doing a const_cast (among other things), which allows you to obtain a writable view of a non-const object even if all you had was a read-only view.

However, it can break horribly (cause undefined behavior) if you aren't careful. Consider:

const A a;
int main()
{
    a.init();
    //a.assign();
    a.print();
}

This could fail spectacularly at runtime, if your toolchain put a into read-only memory.

const in C++, like private, does not provide security. It is part of the type system, and leverages the compiler's type checker to help you catch coding errors. But typing information can always be overridden with casts.

Finally, if you don't want to accidentally cast away const, don't use C-style casts. If you used static_cast or reinterpret_cast the compiler would have caught the mistake.

Upvotes: 5

Related Questions