const_cast 和 UB

发布于 2024-09-29 08:06:11 字数 333 浏览 5 评论 0原文

$5.2.11/7 - “[注:取决于 对象的类型,写操作 通过指针、左值或指针 到由 a 产生的数据成员 const_cast 抛弃 a const-qualifier68) 可能 产生 未定义的行为 (7.1.5.1)。 ]"

这一部分(C++03)的措辞让我感到惊讶。令人惊讶的是两件事。a

)首先,'may'的使用。为什么是'may'?标准中的其他地方很关于未定义行为的明确

b) 为什么要放弃原始 const 对象的常量而不是直接“未定义行为”?为什么需要写入才能触发 UB?

$5.2.11/7 - "[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-qualifier68) may produce
undefined behavior (7.1.5.1). ]"

The wordings of this section (C++03) are surprising to me. What is suprising are two things.

a) Firstly, the use of 'may'. Why is it 'may'? Other places in the Standard are very definitive about the undefined behavior

b) Why is that the casting away the constness of a originally const object not straight away 'undefined behavior'. Why is it that a write is required for UB to be triggered?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

又爬满兰若 2024-10-06 08:06:11

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

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

例如:

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

所以这是特别允许的。

My understanding is that it will only be UB if the object in question is fundamentally a const object rather than a const pointer or reference to an object which was not originally const.

The idea being that data that is fundamentally const could be loaded into a read-only portion of memory, and writing to that just isn't going to work. However, it's guaranteed to work properly if the object in question is fundamentally mutable.

Ex:

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.

For a comment below, because code looks terrible in comments:

In §7.1.​5.1/4 of the standard, the example given is:

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

So this is specifically allowed.

时光与爱终年不遇 2024-10-06 08:06:11

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

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

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

1.3.12:当此国际化时,可能未定义的行为
标准省略了任何描述
行为的明确定义。

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

b) 为什么要抛弃
原始 const 对象的常量
不是立即“未定义”
行为'。为什么写是
需要触发 UB 吗?

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

a) Firstly, the use of 'may'. Why is
it 'may'? Other places in the Standard
are very definitive about the
undefined behavior

Don't look too deeply into the use of the word may here. The point is, casting away constness in this case causes undefined behavior.

The C++ standard uses "may" or "might" often, as in:

1.3.12: Undefined behavior may also be expected when this International
Standard omits the description of any
explicit definition of behavior.

Emphasis mine. Basically, the standard uses the word "may" as in "is allowed to".

b) Why is that the casting away the
constness of a originally const object
not straight away 'undefined
behavior'. Why is it that a write is
required for UB to be triggered?

A write triggers UB because it's possible that const objects can be stored in read-only memory on certain platforms.

耶耶耶 2024-10-06 08:06:11

对于你的第一个问题,如果某些东西可能产生未定义的行为,那么这并不会使其变得不那么不确定。

对于第二部分,我想这是出于互操作性的原因。例如,C 没有(或者在 C99 之前没有)const 关键字,因此如果要将 const 对象传递给 C 函数,则必须放弃 const 性。因此,C++ 标准规定,只要不执行写入操作,就允许这样做。如果 C 函数是只读的,则可以安全地放弃常量性。

即使在 C++ 中,不一致或不完整的常量正确性也很常见。因此,我们偶尔会遇到这样的情况:我们必须放弃 const 性,以便将 const 对象传递给不修改其参数但以非 const 方式接受它的函数。

For your first question, if something may produce undefined behavior, then that doesn't make it any less undefined.

For the second part, I'd imagine it is for interoperability reasons. For example, C doesn't (or didn't, before C99) have a const keyword, so if you want to pass a const object to a C function, the constness would have to be cast away. So the C++ standard specifies that this is allowed as long as no writes are performed. If the C function is read-only, the constness can be safely cast away.

Even in C++, inconsistent or incomplete const-correctness is pretty common too. So we do occasionally run into situations where we have to cast away const-ness in order to pass a const object to a function which doesn't modify its argument, but takes it by non-const.

挖鼻大婶 2024-10-06 08:06:11

我相信这是因为 const 对象可以存储到只读内存中。因此,写入它可能会产生多种影响:程序崩溃、分段错误或无效。

I'd believe that is because a const object can be stored into read-only memory. Thus, writing to it can have many various effects: program crash, segmentation fault, or no effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文