简而言之,我想问的是,以下代码是否仅当/* body */
确实改变了 的值时才调用 UB i
,或者如果没有改变,是否也通过调用对象const
maybeChange
上的非成员函数来调用const
UB。
// header.hpp
struct Foo {
int i;
void maybeChange();
};
void work(Foo const& foo);
// foo.cpp
#include "header.hpp"
void Foo::maybeChange() {
/* body */
}
// work.cpp
#include "header.hpp"
void work(Foo const& foo) {
const_cast<Foo&>(foo).maybeChange();
}
// main.cpp
#include "header.hpp"
Foo const foo{6};
int main() {
work(foo);
}
我确实看到,如果修改真的发生,问题就会存在,因为这违反了编译器可以做出的合法假设,即foo
全局对象不会改变。
但另一方面,http://eel.is/c++draft/dcl.type.cv#4没有展示在被删除的对象const
上调用非成员函数的示例,但这实际上并没有修改它,就像我上面的例子一样。它展示了一些简单的例子,比如const
const
const_cast
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined behavior: modifies a const object
最后一行确实修改了对象*ciq
。
调用函数本身不是 UB。只有当您尝试修改其中一个成员的值或对象本身时才会出现 UB。
如果
foo
没有声明const
,那么即使函数修改了对象或其成员,也不会出现 UB。它与显式函数参数完全相同。您可以将左侧的操作数视为
.
类型为的隐式参数的隐式参数Foo&
。它的行为方式与具有该解释的其他参数相同。正如您在问题中提到的,[dcl.type.cv]/4 是唯一一条由于
const
ness 导致 UB 的规则,您的示例中没有任何内容违反该规则。标准中恰好没有合适的示例,但这并不会改变任何事情。如果您认为这可能有助于理解,您可以建议在此处通过编辑问题添加这样的例子,尽管我不知道有关示例或此类建议的政策。