c++ - 是否使用定义的任意、文字、非零值初始化指针?
问题描述
考虑:
struct T{};
int main() {
T* p = (T*)0xDEADBEEF;
}
使用无效指针是实现定义的。取消引用它是未定义的行为。我的问题不在于这些。
我的问题是,是否只p
定义了 的初始化。
如果您认为您已经掌握了回答此问题所需的所有信息(或者如果您发现这是重复的),则无需进一步阅读。以下是基于我的发现的一些喃喃自语:
C 标准(C++ 标准所基于)说:
6.3.2.3 指针
5 整数可以转换为任何指针类型。除非前面指定,结果是实现定义的,可能没有正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。
这暗示它可能是实现定义的。
C++ 标准仅定义(据我所知)无效指针值的任何使用都是实现定义的。脚注特别重要,因为它似乎表明仅复制此类值已经是对指针的使用。(或者它是否意味着指向的价值?我很困惑)
6.7 储存期限
4 当一个存储区域的持续时间结束时,代表该存储区域任何部分地址的所有指针的值将变为无效指针值(6.9.2)。通过无效指针值的间接传递以及将无效指针值传递给释放函数具有未定义的行为。无效指针值的任何其他使用都具有实现定义的行为。37
37 一些实现可能会定义复制无效指针值会导致系统生成的运行时错误
这种符合C标准。问题是我不相信这是一个无效指针值的例子,因为标准清楚地表明这种类型的值是由到达该地址的存储持续时间结束引起的(这显然从未发生过)。
还有许多指针算术实例是Undefined Behavior TM,但显然这里没有对指针的值进行算术或操作。这仅仅是一个初始化。
解决方案
您的 C 风格演员正在表演reinterpret_cast
; 像这样强制转换任意整数值是实现定义的:
8.5.1.10 重新解释演员表
5 整数类型或枚举类型的值可以显式转换为指针。转换为足够大小的整数(如果实现中存在这样的整数)并返回相同指针类型的指针将具有其原始值;指针和整数之间的映射是由实现定义的。[注意:除了[basic.stc.dynamic.safety]中描述的以外,这种转换的结果不会是安全派生的指针值。——尾注]
如果结果是(被实现认为是)无效的指针值,那么它可能再次由实现定义,当它存储在变量中时会发生什么,但这不太清楚:
6.6.4 储存期限
4 当一个存储区域的持续时间结束时,表示该存储区域任何部分地址的所有指针的值都变为无效指针值。通过无效指针值的间接传递以及将无效指针值传递给释放函数具有未定义的行为。无效指针值的任何其他使用都具有实现定义的行为。
推荐阅读
- python - Python:从数据趋势中找出异常值
- flutter - 使用 Future 时无法将值存储到颤振/飞镖中的类变量
- c# - C# 在 Enumerable.All 扩展中使用带有 return bool 的异步 lambda 表达式
- docker - 如何在 dockerized 环境中使用 webdriverio 测试节点应用程序 (ERR_SSL_PROTOCOL_ERROR)
- scala - 在 scala 数据框中操作数据表连接
- powershell - 将同一文件复制到多个目的地
- c# - 在我的 .NET c# 应用程序上实现 Postek 打印机
- react-native - react-native-image-slider-box 与图像上方的 dotStyle 滑块不起作用
- laravel - 如何在 Laravel 8 中使用 jetstream-inertia 安装 Vuetify?
- node.js - 如何在rabbitmq(rascal.js)上管理每个请求的发布连接