【发布时间】:2018-05-27 01:37:27
【问题描述】:
考虑:
struct T{};
int main() {
T* p = (T*)0xDEADBEEF;
}
使用无效指针是实现定义的。取消引用它是未定义的行为。我的问题不在于这些。
我的问题是 p 的初始化是否按原样定义。
如果您认为自己已经掌握了回答此问题所需的所有信息(或者如果您发现这是重复的),则无需进一步阅读。以下是基于我的发现的一些喃喃自语:
C 标准(C++ 标准所基于)说:
6.3.2.3 指针
5 整数可以转换为任何指针类型。除先前规定外, 结果是实现定义的,可能没有正确对齐,可能不指向 引用类型的实体,可能是陷阱表示。
哪些提示可能是实现定义的。
C++ 标准仅定义(据我所知)无效指针值 的任何使用都是实现定义的。脚注特别重要,因为它似乎表明这种值的仅仅 copy 已经是指针的使用。 (或者它是指指向的值?我很困惑)
6.7 保存期限
4 当一个存储区域的持续时间结束时,表示该存储区域任何部分地址的所有指针的值将变为无效指针值 (6.9.2) .通过无效指针值的间接传递以及将无效指针值传递给释放函数具有未定义的行为。对无效指针值的任何其他使用都具有实现定义的行为。37
37 一些实现可能会定义复制无效指针值会导致系统生成的运行时错误
这种符合C标准。问题是我不相信这是一个无效指针值的例子,因为标准清楚地表明这种类型的值是由到达该地址的存储持续时间结束引起的(这显然从未发生过)。
还有许多指针算术实例是未定义行为TM,但显然没有算术或在这里对指针的值进行操作。这只是一个初始化。
【问题讨论】:
-
@RichardCritten 虽然我的问题非常接近那个问题(它实际上是由与 OP 就该问题进行的讨论引起的!),但略有不同:该问题已经确定分配的值/根据标准中的措辞,初始化 from 是一个无效的指针值。在这个问题上使用的 literal 是一个非常重要的细节,不清楚(至少对我而言)是否应该以同样的方式对待它。
-
C 标准段落的等价物是[expr.reinterpret.cast/5]:“整数类型或枚举类型的值可以显式转换为指针。转换为足够大小的整数的指针(如果有的话)这样存在于实现中)并返回相同的指针类型将具有其原始值;指针和整数之间的映射是由实现定义的。”我认为您展示的初始化是实现定义的。
-
C 标准的文本与此完全无关;建议从您的问题中删除它。
-
“以任何方式使用无效指针是实现定义的”也不正确。
标签: c++ pointers language-lawyer