简体   繁体   English

const_cast const STL容器,它是未定义的行为吗?

[英]const_cast const STL container, is it undefined behavior?

I know that use of const_cast won't introduce undefined behaviour (ie, it's safe to use), as long as the variable you're const_cast ing wasn't originally defined as const or if it was originally defined as const you're not modifying it via its const_cast ed alias. 我知道使用const_cast不会引入未定义的行为(即可以安全使用),只要您要const_cast ing的变量最初未定义为const或如果最初定义为const而不是通过其const_cast ed别名对其进行修改。

However, It is also known that most STL containers (eg, std::vector , std::set ), allocate their internal buffers dynamically. 但是,众所周知,大多数STL容器(例如std::vectorstd::set )都是动态分配其内部缓冲区的。 Based on this fact I think that is impossible for a const defined std::vector to be placed in read-only memory. 基于这个事实,我认为将const定义的std::vector放置在只读内存中是不可能的。

Naturally, if the above holds I come to the assumption that such kind of STL containers even if they're defined as const , eg,: 自然地,如果上述情况成立,我就假设即使将STL容器定义为const ,例如:

std::vector<int> const v;

const_cast ing them and altering them via their const_cast ed alias is legitimate and won't cause any undefined behavior. const_cast并通过其const_cast ed别名对其进行更改是合法的,不会引起任何未定义的行为。

Does the above assumption holds or I'm wrong? 以上假设成立还是我错了?

The C++ standard explicitly points out that casting away const for an object created via new const T , and modifying it, is Undefined Behavior. C ++标准明确指出,将通过new const T创建的对象抛弃const并对其进行修改是未定义行为。

Eg, the C++11 standard contains this example in its §7.1.6.1/4: 例如,C ++ 11标准在其§7.1.6.1/ 4中包含以下示例:

 const int* ciq = new const int (3); // initialized as required int* iq = const_cast<int*>(ciq); // cast required *iq = 4; // undefined: modifies a const object 

Examples in the standard are non-normative, just examples, and can be wrong. 标准中的示例是非规范性的,仅是示例,可能是错误的。 For example, in C++03 nearly all examples that used <iostream> were wrong (at that time it was formally necessary to also include <ostream> , but that was not the intention of the committee), and the expression examples in C++03 §5/4 were wrong, saying the behavior was unspecified rather than undefined (which might have reflected an original intention). 例如,在C ++ 03中,几乎所有使用<iostream>示例都是错误的(当时正式需要同时包含<ostream> ,但这并不是委员会的意图),而C语言中的表达式示例++ 03§5/ 4是错误的,表示该行为是未指定的,而不是未定义的(这可能反映了最初的意图)。 However, the above example is correct. 但是,以上示例是正确的。

This shows that dynamically allocated memory needs not be mutable: that modifying it, can have Undefined Behavior. 这表明动态分配的内存不必是可变的:对其进行修改可以具有未定义的行为。

However, when eg a std::string is created, its allocation of a buffer (if any) occurs during execution of a constructor, at which point the object is not yet const , and the buffer is not allocated as const . 但是,当创建例如std::string ,其对缓冲区(如果有)的分配发生在构造函数执行期间,此时该对象还不是const ,并且该缓冲区未分配为const So the buffer, if one is allocated, is not originally const . 因此,如果分配了缓冲区,则缓冲区最初不是const But regarding this particular example the std::string may use the small buffer optimization where it uses storage directly in the object, which would then be originally const (potentially allocated in read only memory). 但是对于这个特定的示例, std::string可以使用小型缓冲区优化,在这种情况下,它直接在对象中使用存储,然后该对象将最初为const (可能在只读内存中分配)。 And this goes to the rational for the rule that no originally const object can be modified. 而这个去理性的, 没有原来的规则const对象可以被修改。


In addition to the read-only memory scenario, the rationale for UB includes that it can give compilers optimization possibilities. 除了只读内存方案外,UB的基本原理还包括可以为编译器提供优化的可能性。

As juanchopanza notes in a comment to the question , 正如juanchopanza对问题的评论中指出的那样,

Optimizers use this to do all kind of crazy stuff that assumes const objects won't be modified. 优化程序使用此方法来做各种疯狂的事情,这些事情假设const对象不会被修改。

Breaking the assumptions of the optimizer by modifying an originally const object, can have disastrous and effectively unpredictable consequences. 通过修改原始const对象来破坏优化程序的假设,可能会带来灾难性的后果,并且实际上是不可预测的后果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM