$ 5.2.11/7-“ [注意:取决于对象的类型,通过指针,lvalue或指针的写入操作,由const_cast产生的数据构件,该const_cast将const -qualifier 68铸造出来) 可能 产生不确定的行为(7.1.5.1)。 ]”

本节的措辞(C ++ 03)令我惊讶。令人惊讶的是两件事。

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

b)为什么要铸造最初的const对象的构成,而不是立即“不确定的行为”。为什么要触发UB需要写作?

有帮助吗?

解决方案

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

不要太深入地看待单词的使用 可能 这里。关键是,在这种情况下,抛弃构成会导致不确定的行为。

C ++标准使用“可能”或“可能”,例如:

1.3.12:未定义的行为 可能 当该国际标准省略对行为的任何明确定义的描述时,也可以预期。

强调我的。基本上,该标准使用“ May”一词如“被允许".

b)为什么要铸造最初的const对象的构成,而不是立即“不确定的行为”。为什么要触发UB需要写作?

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

其他提示

我的理解是,只有当所讨论的对象从根本上是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.

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

在标准的§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

因此,这是特别允许的。

对于您的第一个问题,是否有什么 可能 产生不确定的行为,那么这并不能使它变得不那么明确。

对于第二部分,我想这是出于互操作性的原因。例如,C没有(或没有,在C99之前)有一个 const 关键字,因此,如果要将const对象传递给C函数,则必须将constness抛弃。因此,C ++标准指定只要执行任何写作,就可以使用此标准。如果C函数仅读取,则可以安全地抛弃constness。

即使在C ++中,不一致或不完整的const-Correct也很常见。因此,我们偶尔会遇到必须抛弃const-ness的情况,才能将const对象传递给不修改其参数但通过非const的函数。

我相信那是因为 const 对象可以存储到仅读取的内存中。因此,写信给它可能会产生许多不同的效果:程序崩溃,分割故障或无效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top