7

I'm learning c++ and came across this const_cast operator. Consider the following example:

class Test
{  
  private:
    char name[100];
  public:
    Test(const char* n) { std::strncpy(name, n, 99); name[99]=0; }
    const char* getName() const { return name; }
}

Now a user can do

Test t("hi");
const_cast<char*>(t.getName())[0] = 'z'; //modifies private data...

Is this fine ? I mean modifying private data since the purpose of return const char* was to prevent changing private data. How do I prevent this ? (without using std::string)

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
user803563
  • 408
  • 3
  • 11
  • 6
    The reason why casts have such a hideous syntax in C++ is to discourage people from using them (seriously!). `const` only works as long as people don't intentionally circumvent it, but it's not meant to do that. The purpose is to avoid accidential modification, and it does that just fine. There is nothing you can do to prevent someone from maliciously breaking your code if they want. They could also write `#define private public` and there is nothing you could do. – Damon Jun 20 '11 at 23:14
  • 1
    You can invent much simpler examples of `const_cast` being used incorrectly. For example, `const char *str = "foo"; const_cast(str)[0] = 'b';`. – Oliver Charlesworth Jun 20 '11 at 23:20
  • 2
    As a sideways (and more "C++") solution, don't expose pointers to private data members, instead store a private `std::string`, and if you really really don't want anyone to modify it expose it by copy (as const-references could also be const-cast away). – Kerrek SB Jun 20 '11 at 23:40
  • @Oli `str` is of type `char*` and I don't think there is any need of `const_cast`. Also, isn't it that you are trying to modify the constant string literal whose behavior is undefined? – user803563 Jun 21 '11 at 00:12
  • @user803563 : If you understand that his example causes UB, how do you not also understand that _your_ example causes UB? :-P – ildjarn Jun 21 '11 at 00:24
  • @idjarn. My example doesn't modify `const` data. It only changes the pointer type. – user803563 Jun 21 '11 at 01:30
  • 1
    @user803563: `str` is of type `char const[4]` which decays to `char const*`. It is deprecated to use `char*` to point to a statically allocated string and it is undefined behavior to try and modify it (with or without `const`). – Matthieu M. Jun 21 '11 at 06:31
  • BTW, accessing `const` members has some usage if you're doing debugging or for unit testing. – MDman Apr 23 '13 at 08:12

2 Answers2

8

No this is not 'fine'. Though it is possible. But C++ doesn't force good behavior on programmers. It mainly allows you to declare things in a way that show their intended use. If a programmer decides to trick around that protection he should know what he is doing.

Bjarne Stroustrup: Yes. That's the new cast syntax. Casts do provide an essential service. The new syntax is an improvement over the C-style casts because it allows the compiler to check for errors that it couldn't with the old syntax. But the new syntax was made deliberately ugly, because casting is still an ugly and often unsafe operation.

thorsten müller
  • 5,621
  • 1
  • 22
  • 30
  • 4
    "C++ tries to guard against Murphy, not Machiavelli" - (attributed alternatively to Bjarne Stroustrup, Herb Sutter, perhaps others). @user803563: there are many other ways to do evil things to private data. `reinterpret_cast(&t)[0] = 'z'` – Lambdageek Jun 20 '11 at 23:18
5

No, it's not fine, but that's the whole point of const_cast. Generally, when a programmer overrides const a whole bunch of bad things may happen, and it is not advised to do that. I'm not sure if you can prevent someone from doing that though, because the point of const_cast is to override the protection generally provided by const.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
littleadv
  • 20,100
  • 2
  • 36
  • 50
  • I would also add that `const` is only there to "help to develop better and safer code" at compile time. The generated code is identical and nothing prevents these `const variables` to be constants. – Alexis Paques May 25 '20 at 12:06