19

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?

BeeOnRope
  • 56,602
  • 14
  • 172
  • 343
  • 3
    Indeed, you are safe as long as no write is actually performed. The `const_cast` itself does not result in UB. See also (possible duplicate?): https://stackoverflow.com/questions/29883327/is-it-safe-to-remove-const-via-const-cast-and-invoke-a-non-const-function-that-d – Cody Gray Feb 03 '19 at 15:15
  • 1
    Possible duplicate of [Is it safe to remove const via const\_cast and invoke a non-const function that does not modify the resulting object?](https://stackoverflow.com/questions/29883327/is-it-safe-to-remove-const-via-const-cast-and-invoke-a-non-const-function-that-d) – Passer By Feb 05 '19 at 01:00

2 Answers2

23

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.

  • 7
    Interesting, so [this answer](https://stackoverflow.com/a/19554871/149138) is wrong (or at least imprecise) when it says "You are not allowed to const_cast variables that are actually const." - the actual restriction is that you are not allowed to _modify_ variable that are actually const (and of course casting away const removes the guardrails that would normally prevent that)? – BeeOnRope Feb 03 '19 at 15:18
  • 3
  • 6
    @BeeOnRope Confirming, that quote is incorrect and your interpretation is correct. – Lightness Races in Orbit Feb 03 '19 at 15:28
  • 9
    It's actually amazing how many wrong highly upvoted answers one can find on the subject. Here's another. https://stackoverflow.com/questions/357600/is-const-cast-safe – StoryTeller - Unslander Monica Feb 03 '19 at 15:29
-2

If it compiles, then it is allowed. But it does not mean, it is legal.

#include <iostream>

int main(int argc, char *argv[]) 
{
    const int arr[] = {1, 2, 3};
    int* parr = const_cast<int*>(arr);
    parr[0] = 0;
    for(auto& n : arr)
        std::cout << n << std::endl;
}

The above code compiles in Ubuntu 20.04 g++ compiler. It also runs without problem. But the above code actually is undefined behaviour.

eigenfield
  • 3,221
  • 1
  • 29
  • 32