- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
int main(){
int v = 1;
char* ptr = reinterpret_cast<char*>(&v);
char r = *ptr; //#1
}
在这段代码中,表达式 ptr 指向一个 int 类型的对象,如下所示:
expr.static.cast#13
Otherwise, the pointer value is unchanged by the conversion.
间接 ptr
将产生一个表示对象 ptr
指向的泛左值,根据
expr.unary#op-1
the result is an lvalue referring to the object or function to which the expression points.
根据
,使用允许类型的泛左值访问对象不会导致 UB basic.lval#11
If a program attempts to access ([defns.access]) the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:
- a char, unsigned char, or std::byte type.
看来也没有违反以下规则:
expr#pre-4
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
假设测试环境下char
的宽度为8位,取值范围为[-128, 127]。 v
的值为 1。那么,这是否意味着 #1
处的代码段不会导致 UB?
作为对比,给出下面的例子
int main(){
int v = 2147483647; // or any value greater than 127
char* ptr = reinterpret_cast<char*>(&v);
char r = *ptr; //#2
}
#2
是 UB,对吗?
最佳答案
这两个片段都是实现定义的语言的意图。我相信他们是,直到 C++17 打破了对该语言功能的支持。查看缺陷报告 here .据我所知,这在 C++20 中尚未修复。
目前,访问内存表示的可移植解决方法是使用 std::memcpy
( example ):
#include <cstring>
char foo(int v){
return *reinterpret_cast<char*>(&v);
}
char bar(int v)
{
char buffer[sizeof(v)];
std::memcpy(buffer, &v, sizeof(v));
return *buffer;
}
foo
在技术上是 UB 而 bar
定义明确。原因是 foo
是 UB 被遗漏了。根据定义,标准未定义的任何内容都是 UB,并且标准在其当前状态下无法定义此代码的行为。
bar
使用 gcc 10 生成与 foo
相同的程序集。对于简单的情况,实际拷贝被优化掉。
关于你的理性,除了在我看来,定义一元 operator*
( expr.static.cast#13 ) 的规则在这种情况下没有你期望的效果外,推理似乎是合理的。指针必须指向底层表示,如链接缺陷所描述的那样定义不当。指针值不变的事实并不能减轻它指向不同对象的事实。如果对象的类型不同,C++ 允许对象具有相同的地址,例如标准布局类中的第一个成员与所属实例共享相同的地址。
请注意,作者是缺陷报告,就片段 #1 得出了与您相同的结论,但我不同意。但由于我们正在处理一种语言缺陷,并且与国家意图相冲突,因此很难明确证明一种行为是正确的。众所周知,这些论点所依据的基本规则在这种特殊情况下是有缺陷的。
关于c++ - 使用char类型的glvalue访问另一种类型的对象时是否不必导致UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66782987/
我是一名优秀的程序员,十分优秀!