0

I'm curious why the compiler doesn't complain if I hand over a const-pointer to a non-const-pointer as parameter in a constructor of a class that itself, which of course is at construction time not const.

#include <iostream>

class A
{
public:
    A(int* v) : v(v) {}

    int* v;
};

class B
{
public:
    B() : o(23), v(&o) {}

    const A cc() const
    {
        return A(v); //expected const to non-cosnt error here, but seems valid
    }

    int o;
    int* v;
};

int main() {
    B b;
    const B* bc = &b;

    A a = bc->cc();

    *(a.v) = 25; // here I'm changing an originally const value

    std::cout << b.o << std::endl;

    return 0;
}

With defining cc() as const I expected the line where the return value is initialized an error message about converting a const to a non-const. The code-snippet compiles fine and in the end I get the output "25" even so that should have been const.

Davidius
  • 11
  • 1
  • 1
    Don't return [const objects](http://stackoverflow.com/questions/12051012/should-i-return-const-objects) – Paolo M Dec 04 '15 at 11:40
  • And by the way, you are not passing a pointer to the constructor of `A` anywhere... – Paolo M Dec 04 '15 at 11:41
  • The memory pointed to by `v` in `B` is not `const` (and can be because the constructor is naturally non-`const` where `o` is not const, too). Inside `cc` `this` is `const B*`, `o` is `const int` and `v` is `int * const`. The members are constant but the memory pointed to by `v` still is not (would mean `int const * const`). The pointer however is never changed inside `cc` but copied into `A`. – Pixelchemist Dec 04 '15 at 11:48
  • @nos Uh, right... the example is pretty awkward though. – Paolo M Dec 04 '15 at 11:51

3 Answers3

2

The A constructor expects a copy of a pointer instead of a reference. It is absolutely legal to copy a int * const into an int*. Therefore, no error occurs.

You should use references instead of pointers when you want a consistent behavior regarding constness. By the way, returning const objects is a bad idea.

Jean-Bernard Jansen
  • 7,544
  • 2
  • 20
  • 17
2

You're confusing int const* (or const int*) and int* const.

Copying a const object into a non-const new object is fine, whether that object is a pointer or not. That's all you're doing here; the pointer itself is const (it's int* const), so you can pretty much do what you like with a copy of it.

What is not ok is copying a int const* into a int*, because now you're saying the thing being pointed to has magically lost its const-protection.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • You are right, I did. Expected `int * const`, but in fact it is `int const *` inside cc(). THanks. PS: There is a typo in your answer. You ment `int *const`but wrote `int const*`. – Davidius Dec 04 '15 at 19:11
  • @Davidius: Where's the typo? – Lightness Races in Orbit Dec 04 '15 at 19:12
  • _"Expected `int * const`, but in fact it is `int const *` inside cc()."_ No! Wrong way around! You [apparently] expected `int const*`, but in fact it is `int* const`. – Lightness Races in Orbit Dec 04 '15 at 19:13
  • You're answer confused me. I had to look it up once again. So I was right in the beginning and didn't confuse it. Inside cc() v is a int const * so I copy by handing it over as parameter into a int*. – Davidius Dec 04 '15 at 19:20
  • @Davidius: I'll say it only one more time. **Inside `cc()`, `v` is a `int* const`.** It's not a "typo", any of the three times I've said it. You seem to be misunderstanding some of the basics of `const`-correctness? Read the first line of my answer again because it's evidently still happening. Feel free to ask specific follow-up questions instead of accusing me of having typos and insisting that you "were right in the beginning". – Lightness Races in Orbit Dec 04 '15 at 19:22
0

constness of an object does not propagate to constness of the pointee of a pointer member. The pointer becomes const but the pointee stays non-const. Even if the pointer is const, you can easily obtain a non-const pointer by simply copying the pointer which is exactly what happens as the pointer is passed by value.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380