Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ const cast, unsure if this is secure

Tags:

c++

const-cast

It maybe seems to be a silly question but i really need to clarify this:

Will this bring any danger to my program?

Is the const_cast even needed?

If i change the input pointers values in place will it work safely with std::string or will it create undefined behaviour?

So far the only concern is that this could affect the string "some_text" whenever I modify the input pointer and makes it unusable.

std::string some_text = "Text with some input";

char * input = const_cast<char*>(some_text.c_str());

Thanks for giving me some hints, i would like to avoid the shoot in my own foot

like image 826
Oliver Avatar asked Apr 24 '12 07:04

Oliver


2 Answers

As an example of evil behavior: the interaction with gcc's Copy On Write implementation.

#include <string>
#include <iostream>

int main() {
    std::string const original = "Hello, World!";
    std::string copy = original;

    char* c = const_cast<char*>(copy.c_str());
    c[0] = 'J';

    std::cout << original << "\n";
}

In action at ideone.

Jello, World!

The issue ? As the name implies, gcc's implementation of std::string uses a ref-counted shared buffer under the cover. When a string is modified, the implementation will neatly check if the buffer is shared at the moment, and if it is, copy it before modifying it, ensuring that other strings sharing this buffer are not affected by the new write (thus the name, copy on write).

Now, with your evil program, you access the shared buffer via a const-method (promising not to modify anything), but you do modify it!

Note that with MSVC's implementation, which does not use Copy On Write, the behavior would be different ("Hello, World!" would be correctly printed).

This is exactly the essence of Undefined Behavior.

like image 107
Matthieu M. Avatar answered Sep 30 '22 19:09

Matthieu M.


To modify an inherently const object by casting away its constness using const_cast is an Undefined Behavior.

string::c_str() returns a const char *, i.e: a pointer to a constant c-style string. Technically, modifying this will result in Undefined Behavior.

Note, that the use of const_cast is when you have a const pointer to a non const data and you wish to modify the non-constant data.

like image 44
Alok Save Avatar answered Sep 30 '22 17:09

Alok Save