C++17 Standard - Cast away const of static
Asked Answered
E

1

6

Recently I decided to dive into the C++ Standard and check whether certain code snippets are well defined and where to find those definitions in the standard. Since the standard is rather hard to get right (especially if you are not used to it) I wanted to verify if my assumption is right.

I came across the following example (which is obviously a bad idea). It compiles just fine (using g++ 8.2.1) but SEGFAULTs during execution:

#include <iostream>

static const int staticInt = 23;

int main () {
    int &localInt = const_cast<int &>(staticInt);
    localInt = 11;
    std::cout << staticInt << std::endl;
    return 0;
}

So, I searched through the standard (I use the working draft on open-std btw) and found paragraph 6.8.10:

Creating a new object within the storage that a const complete object with static, thread, or automatic storage duration occupies, or within the storage that such a const object used to occupy before its lifetime ended, results in undefined behavior.

Am I right, that this paragraph is applicable for the given example? If I am not, where else should I look at?

Encounter answered 18/2, 2019 at 10:6 Comment(3)
Your code does not create a new object within the storage of staticInt, so it can't possibly apply.Marylnmarylou
The sections relevant to this problem is the ones about const variables. You attempt to modify a const variable, which leads to UB. End of story. That it is static or in the global scope or that you use a reference to the variable or that the reference is in a different scope is irrelevant.Magnesia
@Marylnmarylou Assignment of a trivial type does create a new object in some cases. Not sure what those cases should be...Coseismal
A
10

This is undefined behavior because of the attempt to modify a const variable after using a const_cast on it.

Citations from n4659, the final working draft of C++17 . The relevant passage in this case is:

8.2.11 Const cast [expr.const.cast]
...
6 [ 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-qualifier may produce undefined behavior. —end note ]

Also of relevance is this section related to const objects:

10.1.7.1 The cv-qualifiers [dcl.type.cv]
...
4 Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.

Abm answered 18/2, 2019 at 10:11 Comment(6)
Well, that seems a lot more reasonable. Thanks for your answer.Encounter
I think the 7.1.7.1p4 is more explicit: ...., any attempt to modify a const object during its lifetime results in undefined behavior.Irishirishism
@KamilCuk: Just added that. Thanks for mentioning it.Abm
I'd swap your two quotes. [dcl.type.cv]/4 is the reason OP's snippet is UB, [expr.const.cast]/6 is "also relevant" ;)Generalship
@YSC: I wanted to do too that but then I realized that the code would not even compile without the const_cast. So I addressed that bit first.Abm
IMO it doesn't make much sense. With the same reasoning, the code wouldn't compile without [basic.def] or most of the standard actually. Anyway, it's not that important, nice answer ;)Generalship

© 2022 - 2024 — McMap. All rights reserved.