fre*_*low 70 c++ pointers language-lawyer dangling-pointer
比较悬空指针是否合法?
int *p, *q;
{
int a;
p = &a;
}
{
int b;
q = &b;
}
std::cout << (p == q) << '\n';
Run Code Online (Sandbox Code Playgroud)
注意如何既p与q点有对象已经消失了.这合法吗?
M.M*_*M.M 57
简介:第一个问题是使用价值是否合法p.
在a被破坏之后,p获取所谓的无效指针值.引自N4430(有关N4430状态的讨论,请参阅下面的"注释"):
当达到存储区域的持续时间的结束时,表示解除分配的存储的任何部分的地址的所有指针的值变为无效的指针值.
使用无效指针值时的行为也在N4430的同一部分中介绍(几乎相同的文本出现在C++ 14 [basic.stc.dynamic.deallocation]/4中):
通过无效指针值间接并将无效指针值传递给释放函数具有未定义的行为.无效指针值的任何其他使用都具有实现定义的行为.
[ 脚注:某些实现可能会定义复制无效指针值会导致系统生成的运行时错误. - 结束脚注]
因此,您需要查阅实现的文档以了解此处应该发生的事情(自C++ 14以来).
上述引号中的术语使用意味着需要进行左值到右值的转换,如C++ 14 [conv.lval/2]:
当对表达式e应用左值到右值转换时,glvalue引用的对象包含无效指针值,该行为是实现定义的.
历史:在C++ 11中,这表示未定义而不是实现定义 ; 它被DR1438改变了.有关完整报价,请参阅此帖子的编辑历史记录.
应用于p == q:假设我们已经在C++ 14 + N4430中接受了评估p和q实现定义的结果,并且实现没有定义硬件陷阱发生; [expr.eq]/2说:
两个指针比较相等,如果它们都是null,都指向相同的函数,或者两者都表示相同的地址(3.9.2),否则它们比较不相等.
由于它的实现定义了何时获得的值p以及q评估,我们无法确定这里会发生什么.但它必须是实现定义的或未指定的.
在这种情况下,g ++似乎表现出未指定的行为; 取决于-O开关,我能够让它说1或者0,对应于相同的存储器地址是否被重新用于b之后a被销毁.
关于N4430的注意事项:这是针对C++ 14的建议缺陷解决方案,尚未被接受.它清理了很多围绕对象生命周期,无效指针,子对象,联合和数组边界访问的措辞.
在C++ 14文本中,它在[basic.stc.dynamic.deallocation]/4及后续段落中定义,使用时会出现无效指针值delete.但是,没有明确说明相同的原理是否适用于静态或自动存储.
在[basic.compound]/3中有一个定义"有效指针"但是它太模糊而不能合理使用.[basic.life]/5(脚注)引用同一文本来定义指向对象的指针的行为.静态存储持续时间,这表明它适用于所有类型的存储.
在N4430中,文本从该部分向上移动一级,以便它明确适用于所有存储持续时间.有附注:
起草说明:这应该适用于可以结束的所有存储持续时间,而不仅仅是动态存储持续时间.在支持线程或分段堆栈的实现上,线程和自动存储的行为方式与动态存储的行为方式相同.
我的观点:除了说p获取无效指针值之外,我没有看到任何一致的方式来解释标准(前N4430).除了我们已经看过的内容之外,其他任何部分似乎都没有涵盖这种行为.所以我很高兴在这种情况下将N4430措辞视为代表标准的意图.
| 归档时间: |
|
| 查看次数: |
2392 次 |
| 最近记录: |