Zeb*_*ish 1 c++ pointers undefined-behavior dangling-pointer
这里出现了一个问题,当一个指针变得晃来晃去时,问"为什么这个工作".答案是它是UB,这意味着它可能起作用.
我在一个教程中学到了:
#include <iostream>
struct Foo
{
int member;
void function() { std::cout << "hello";}
};
int main()
{
Foo* fooObj = nullptr;
fooObj->member = 5; // This will cause a read access violation but...
fooObj->function(); // Because this doesn't refer to any memory specific to
// the Foo object, and doesn't touch any of its members
// It will work.
}
Run Code Online (Sandbox Code Playgroud)
这相当于:
static void function(Foo* fooObj) // Foo* essentially being the "this" pointer
{
std::cout << "Hello";
// Foo pointer, even though dangling or null, isn't touched. And so should
// run fine.
}
Run Code Online (Sandbox Code Playgroud)
我错了吗?是UB,即使我解释只是调用一个函数而不是访问无效的Foo指针?
你在推理实践中会发生什么.允许未定义的行为执行您期望的操作...但不保证.
对于非静态情况,可以直接使用以下内容中的规则进行证明[class.mfct.non-static]
:
如果为非
X
类型的对象X
或派生类型的对象调用类的非静态成员函数X
,则行为未定义.
请注意,没有考虑非静态成员函数是否访问*this
.该对象只需要具有正确的动态类型,*(Foo*)nullptr
当然也不需要.
特别是,即使在使用您描述的实现的平台上,也可以使用该调用
fooObj->func();
Run Code Online (Sandbox Code Playgroud)
转换为
__assume(fooObj); Foo_func(fooObj);
Run Code Online (Sandbox Code Playgroud)
并且是优化不稳定的.
这是一个与您的期望相反的例子:
int main()
{
Foo* fooObj = nullptr;
fooObj->func();
if (fooObj) {
fooObj->member = 5; // This will cause a read access violation!
}
}
Run Code Online (Sandbox Code Playgroud)
在实际系统上,这可能最终会在注释行上发生访问冲突,因为编译器使用了fooObj
不能为空的事实fooObj->func()
来消除if
其后的测试.
即使您认为自己了解平台的功能,也不要做UB的事情. 优化不稳定是真实的.
此外,您可能会认为标准更具限制性.这也导致UB:
struct Foo
{
int member;
void func() { std::cout << "hello";}
static void s_func() { std::cout << "greetings";}
};
int main()
{
Foo* fooObj = nullptr;
fooObj->s_func(); // well-formed call to static member,
// but unlike Foo::s_func(), it requires *fooObj to be a valid object of type Foo
}
Run Code Online (Sandbox Code Playgroud)
标准的相关部分见于[expr.ref]
:
表达式
E1->E2
转换为等效形式(*(E1)).E2
以及随附的脚注
如果计算了类成员访问表达式,则即使不需要结果来确定整个后缀表达式的值,也会发生子表达式求值,例如,如果id-expression表示静态成员.
这意味着有问题的代码肯定会进行评估(*fooObj)
,尝试创建对不存在的对象的引用.有几个提议允许这样做,并且只允许在这样的引用上允许lvalue-> rvalue转换,但是到目前为止这些已经被拒绝了; 甚至形成参考文献在迄今为止的所有版本的标准中都是非法的.
归档时间: |
|
查看次数: |
182 次 |
最近记录: |