Adr*_*ian 2 c++ pointers member-functions language-lawyer
考虑以下代码:
int main()
{
struct EmptyStruct{
void nonstatic_mf() const { std::cout <<"EmptyStruct\n"; }
};
EmptyStruct *esptr = nullptr;
esptr->nonstatic_mf();
}
Run Code Online (Sandbox Code Playgroud)
这是一个合法的 C++(它似乎在 gcc 和 clang 中工作)?
即使结构为空,它的大小也非零。必须有一些内存作为它的存储。
不,这始终是 UB。如果您不需要实例,请将其设为静态。静态函数仍然可以使用点.语法调用。
为什么?因为您不能取消引用空指针。调用与此等效的成员函数:
EmptyStruct *esptr = nullptr;
(*esptr).nonstatic_mf();
Run Code Online (Sandbox Code Playgroud)
如您所见,空指针是被延迟的,也就是UB。
标准对此有何规定?来自[class.mfct.non-static]/2:
如果为非 X 类型或从 X 派生的类型的对象调用类 X 的非静态成员函数,则行为未定义。
空指针不指向 的有效实例EmptyStruct。仅此一项就足以使行为未定义
来自[expr.ref]/2:
对于第一个选项(点),第一个表达式应为泛左值。对于第二个选项(箭头),第一个表达式应为具有指针类型的纯右值。表达式
E1->E2被转换为等价形式(*(E1)).E2;[expr.ref]的其余部分将仅解决第一个选项(点)。
Soesptr->nonstatic_mf()等效于(*esptr).nonstatic_mf(),并且取消引用空指针是未定义的行为。
所以有两种方式未定义此代码。
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |