views:

47

answers:

4
+1  Q: 

const_cast and UB

$5.2.11/7 - "[Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a const-qualifier68) may produce undefined behavior (7.1.5.1). ]"

The wordings of this section (C++03) are surprising to me. What is suprising are two things.

a) Firstly, the use of 'may'. Why is it 'may'? Other places in the Standard are very definitive about the undefined behavior

b) Why is that the casting away the constness of a originally const object not straight away 'undefined behavior'. Why is it that a write is required for UB to be triggered?

+1  A: 

I'd believe that is because a const object can be stored into read-only memory. Thus, writing to it can have many various effects: program crash, segmentation fault, or no effect.

Didier Trosset
+1  A: 

My understanding is that it will only be UB if the object in question is fundamentally a const object rather than a const pointer or reference to an object which was not originally const.

The idea being that data that is fundamentally const could be loaded into a read-only portion of memory, and writing to that just isn't going to work. However, it's guaranteed to work properly if the object in question is fundamentally mutable.

Ex:

const int  x = 4;
const int *y = x;

*const_cast<int*>(x) = 3; // UB - the pointed-to object may 
                          // be in read-only memory or whatever.

int        a = 7;
const int *b = a;

*const_cast<int*>(b) = 6; // Not UB - the pointed-to object is 
                          // fundamentally mutable.
Kaz Dragon
+2  A: 

a) Firstly, the use of 'may'. Why is it 'may'? Other places in the Standard are very definitive about the undefined behavior

Don't look too deeply into the use of the word may here. The point is, casting away constness in this case causes undefined behavior.

The C++ standard uses "may" or "might" often, as in:

1.3.12: Undefined behavior may also be expected when this International Standard omits the description of any explicit definition of behavior.

Emphasis mine. Basically, the standard uses the word "may" as in "is allowed to".

b) Why is that the casting away the constness of a originally const object not straight away 'undefined behavior'. Why is it that a write is required for UB to be triggered?

A write triggers UB because it's possible that const objects can be stored in read-only memory on certain platforms.

Charles Salvia
+2  A: 

For your first question, if something may produce undefined behavior, then that doesn't make it any less undefined.

For the second part, I'd imagine it is for interoperability reasons. For example, C doesn't (or didn't, before C99) have a const keyword, so if you want to pass a const object to a C function, the constness would have to be cast away. So the C++ standard specifies that this is allowed as long as no writes are performed. If the C function is read-only, the constness can be safely cast away.

Even in C++, inconsistent or incomplete const-correctness is pretty common too. So we do occasionally run into situations where we have to cast away const-ness in order to pass a const object to a function which doesn't modify its argument, but takes it by non-const.

jalf
Wait...what? I'm pretty sure C89 has `const`. See section 3.5.3 "Type qualifiers" at http://flash-gordon.me.uk/ansi.c.txt
Charles Salvia
C89 has const, but plenty of old-and/or-crappy-but-useful C (and even C++) APIs don't use it anyhow.
Steve M
Oh, odd. I wonder what gave me the idea that it didn't. I stand corrected. :)
jalf