const_cast和UB

Chu*_*dad 5 c++ const-cast undefined-behavior

$ 5.2.11/7 - "[注意:根据对象的类型,通过指针,左值或指向数据成员的指针进行写入操作会导致const-qualifier68的const_cast)可能会产生未定义的行为(7.1. 5.1).]"

本节的措辞(C++ 03)对我来说是令人惊讶的.令人惊讶的是两件事.

a)首先,使用'可能'.为什么'可能'?标准中的其他地方对未定义的行为非常明确

b)为什么抛弃原始const对象的常量而不是直接'未定义的行为'.为什么要触发UB需要写入?

Cha*_*via 6

a) 首先,使用“可能”。为什么是“可能”?标准中的其他地方对未定义的行为非常明确

在这里不要太深入地研究可能这个词的用法。关键是,在这种情况下抛弃常量会导致未定义的行为。

C++ 标准经常使用“may”或“might”,例如:

1.3.12:未定义行为可能在本国际标准忽略了行为的任何明确定义的描述也可以预期。

强调我的。基本上,该标准使用“可以”一词作为“允许”。

b) 为什么抛弃最初的 const 对象的常量性而不是立即“未定义的行为”。为什么要触发 UB 需要写操作?

写入会触发 UB,因为 const 对象可能会存储在某些平台上的只读内存中。


Kaz*_*gon 5

我的理解是,只有当所讨论的对象从根本上是一个 const 对象而不是一个 const 指针或对最初不是 const 的对象的引用时,它才会是 UB。

这个想法是,基本上是 const 的数据可以加载到内存的只读部分,而写入它是行不通的。但是,如果所讨论的对象从根本上是可变的,它就可以保证正常工作。

前任:

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.
Run Code Online (Sandbox Code Playgroud)

对于下面的评论,因为代码在评论中看起来很糟糕:

在标准的 §7.1.?5.1/4 中,给出的例子是:

int i = 2;
const int * cip; // pointer to const int
cip = &i;        // OK: cv-qualified access path to unqualified
...
int* ip;
ip = const_cast <int *>( cip ); // cast needed to convert const int* to int*
*ip = 4;                        // defined: *ip points to i, a non-const object
Run Code Online (Sandbox Code Playgroud)

所以这是特别允许的。