const_cast const STL 容器,它是未定义的行为
const_cast const STL container, is it undefined behavior?
我知道使用const_cast
不会引入未定义的行为(即使用它是安全的),只要您const_cast
的变量最初没有定义为const
,或者如果它最初被定义为const
您没有通过其const_cast
ed别名对其进行修改。
然而,众所周知,大多数STL容器(例如,std::vector
,std::set
)动态分配其内部缓冲区。基于这一事实,我认为不可能将const
定义的std::vector
放在只读内存中。
当然,如果上述情况成立,我假设这种STL容器即使被定义为const
,例如:
std::vector<int> const v;
const_cast
它们并通过其const_cast
ed别名更改它们是合法的,不会导致任何未定义的行为。
上述假设成立还是我错了?
C++标准明确指出,丢弃通过 new const T
创建的对象的const
并对其进行修改是未定义的行为。
例如,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
标准中的例子是非规范性的,只是例子,可能是错误的。例如,在C++03中,几乎所有使用<iostream>
的例子都是错误的(当时正式有必要也包括<ostream>
,但这不是委员会的意图),而C++03 §5/4中的表达例子是错误的,说行为是未指定的而不是未定义的(这可能反映了原始意图)。但是,上面的例子是正确的。
这表明动态分配的内存不需要是可变的:修改它可能会有未定义的行为。
但是,例如,当创建一个std::string
时,它对缓冲区的分配(如果有的话)发生在构造函数的执行期间,此时对象尚未const
,并且缓冲区未分配为const
。因此,如果分配了一个缓冲区,则最初不是const
的。但是对于这个特定示例,std::string
可以使用小缓冲区优化,其中它直接在对象中使用存储,然后最初将const
存储(可能在只读内存中分配)。这涉及到规则的合理性,即不能修改任何原始const
对象。
除了只读内存方案之外,UB 的基本原理还包括它可以为编译器提供优化可能性。
正如胡安乔潘扎在对这个问题的评论中指出的那样,
"优化器使用它来做各种疯狂的事情,假设
const
对象不会被修改。
通过修改最初const
的对象来打破优化程序的假设,可能会产生灾难性且实际上不可预测的后果。
- 具体来说,标准在哪里规定修改 const 对象是未定义的行为?
- 包括"lvtocon.h",未定义对'operator<<(std::ostream&, char const*)的引用
- 正在通过const-ref未定义的行为捕获新构造的对象
- C++ CMake 构建错误:未定义对"boost::throw_exception(std::exception const&)"的引用
- Cpp 未定义引用 'Apache:: thrift:: transport:: TSocket:: TSocket (std:: string const&, int)'
- 对"displayForStudent(int, int const*, double const*, int)"的未定义引用 collect2.exe:错误:ld 返回 1 个退出状态
- 构建错误:未定义对"cv_bridge::CvImage::toImageMsg() const"的引用
- 对'PreconditionViolatedException::PreconditionViolatedException(std::string const&)'的未定义引用
- Cmake 对 'boost::gregorian::greg_month::as_short_string() const' 的未定义引用
- shared_ptr中对const int的未定义引用
- 对'std::string Helper::ToString<int>(int const&)'的未定义引用
- 错误未定义对"BP::D evice::Create(std::string const&)"的引用
- 对 Stack<int>::p ush(int const&) 的未定义引用
- JsonCpp:未定义的对"Json::Value::operator[](int) const"的引用
- 链接器错误(未定义的引用)与“静态 constexpr const char*”和完美转发
- 在 Ubuntu 14.04 上使用 boost 编译:未定义对 'boost::thread::get_id() const' 的引用
- g++ 4.4 中 std::atomic<const memberfunctionpointer*>::store() 的未定义引用
- 对'icu_56::UnicodeString::UnicodeString(signed char, unsigned short const*, int)' 的未定义引用
- 收到错误"二进制'[':"const typ"未定义此运算符"或"下标需要数组或指针类型
- const_cast const STL 容器,它是未定义的行为