Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it allowed to cast away const on a const-defined object as long as it is not actually modified?

Is the following allowed:

const int const_array[] = { 42 };

int maybe_inc(bool write, int* array) {
  if (write) array[0]++;
  return array[0];
}

int main() {
  return maybe_inc(false, const_cast<int *>(const_array));
}

In particular, is it OK to cast-away the constness of const_array, which was defined as const, as long as the object is not actually modified, as in the example?

like image 528
BeeOnRope Avatar asked Feb 03 '19 15:02

BeeOnRope


People also ask

Can a const reference be bound to a non const object?

No. A reference is simply an alias for an existing object. const is enforced by the compiler; it simply checks that you don't attempt to modify the object through the reference r .

Can you cast a const?

const_cast can be used to add const ness behavior too. From cplusplus.com: This type of casting manipulates the constness of an object, either to be set or to be removed.

How do I remove a const?

The statement int* c = const_cast<int>(b) returns a pointer c that refers to a without the const qualification of a . This process of using const_cast to remove the const qualification of an object is called casting away constness. Consequently the compiler does allow the function call f(c) .

Is const cast undefined behavior?

const_cast is perhaps the most rarely used cast operator because it is undefined behavior to remove const or volatile from a variable if the variable was declared const or volatile in the first place.


1 Answers

Yes. This is entirely legal. (It is dangerous, but it is legal.) If you (attempt to) modify a an object declared const, then the behaviour is undefined.

From n4659 (which is the last draft of C++17), section 10.1.7.1 [dcl.type.cv] para 4:

Except that any class member declared mutable (10.1.1) can be modified, any attempt to modify a const object during its lifetime (6.8) results in undefined behavior

My emphasis. That is from C++17, but this has been true of all versions of C++.

If you look at the section on const_cast there is a note that

[ 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-qualifier76 may produce undefined behavior (10.1.7.1). — end note ]

Notes are not normative, but this strongly implies that obtaining a non-const reference or pointer to a const object is legal. It is the write that is not allowed.

like image 55
Martin Bonner supports Monica Avatar answered Oct 13 '22 00:10

Martin Bonner supports Monica