[英]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::vector
, std::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.