简体   繁体   中英

Should I use const_cast?

So I'm doing some parsing of C-strings in a function that looks like this:

void parse(const char** params, int numParams);

I wanted to pull some information out of one of the strings stored in params, so I wrote code that looked like this:

char* charPointer;
charPointer = params[0];

The compiler didn't like this and told me that it can't convert from a const char* to a char*. I understand the reasoning behind this (in theory I could write to the address pointed to by charPointer but not by params[0] if it let me) but what I don't understand is how I should be getting around it. I know of two ways to fix this error but I don't know which one is "proper" or really what the differences are between them. The first is:

const char* charPointer;
charPointer = params[0];

And the second method is:

char* charPointer;
charPointer = const_cast<char*>(params[0]);

So which is better and why?

So which is better and why?

const char* charPointer;
charPointer = params[0];

is certainly better, than forcibly removing a restriction using the

char* charPointer;
charPointer = const_cast<char*>(params[0]);

Parsing the character array usually shouldn't need to change it, thus its best to leave it const .

const_cast is safe only, if pointer is really pointing to something which is non-const, so modifying it is not a problem. If the value is originally const , then using const_cast to get rid of the constness and then writing to it is basically undefined behaviour (for example, other parts of the code may assume value does not change, so your modification only takes effect sometimes).

So definitely use this version:

const char* charPointerr = params[0];

In general, if you need to resort to const_cast , you are probably doing something... if not wrong, then at least ugly. And if you are not sure if it is just ugly or outright wrong, then it's probably wrong.


Example of something where things can go horribly wrong due to undefined behaviour like this:

const bool do_it = true;
bool *ptr = const_cast<bool*>(&do_it);
*ptr = false;

// optimizer probably thinks this is always true
if (do_it) initiate_nuclear_first_strike(); 

While developing using debug build, everything seems to work. Then, release build is deployed (without testing, of course, because in hurry), and BOOM , end of the world. UB is dangerous like that (a side note: effects of UB can also be totally obscure and not as easily understandable as this example).

Casting is almost always a code smell. The only legitimate use I've ever found for const_cast is to pass const data to a legacy library function which you know won't modify the data, but was written in the ancient days without the const specifier.

Why would you want to cast it away, anyway? In this instance, you don't need to. Const correctness is a great boon to writing correct code. I've found that making everything const that doesn't need to change is a good thing.

const_cast is safe only if you're casting a variable that was originally non-const. For example, if you have a function that takes a parameter of a const char *, and you pass in a modifiable char * , it's safe to const_cast that parameter back to a char * and modify it. However, if the original variable was in fact const, then using const_cast will result in undefined behavior

const char* charPointer = params[0];

is the better way to do that and also better to initialize and declare in the same line.

Casting a pointer to const to a pointer to non-const allows you to write to constant objects through the pointer.

Writing to constant objects is undefined behaviour .

The C++ language specification is very explicit about what happens when you invoke undefined behaviour - the entire logic of the program becomes undefined, the compiler is under no obligation to behave reasonably , and it becomes impossible to reason about how the program will behave - at all - even in unrelated parts of the program.

Knowing this, ask yourself the question again. :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM