【发布时间】:2018-05-09 23:06:31
【问题描述】:
C++17 (expr.add/4) 说:
当具有整数类型的表达式被添加或减去时 从一个指针,结果具有指针操作数的类型。如果 表达式 P 指向具有 n 的数组对象 x 的元素 x[i] 元素,表达式 P + J 和 J + P(其中 J 的值为 j) 如果 0≤i+j≤n,则指向(可能是假设的)元素 x[i+j]; 否则,行为未定义。同样,表达式 P - J 如果 0≤i−j≤n,则指向(可能是假设的)元素 x[i−j]; 否则,行为未定义。
struct Foo {
float x, y, z;
};
Foo f;
char *p = reinterpret_cast<char*>(&f) + offsetof(Foo, z); // (*)
*reinterpret_cast<float*>(p) = 42.0f;
标有 (*) UB 的行吗? reinterpret_cast<char*>(&f) 不指向 char 数组,而是指向浮点数,因此它应该根据引用的段落进行 UB。但是,如果是UB,那么offsetof的用处就有限了。
是 UB 吗?如果没有,为什么不呢?
【问题讨论】:
-
@StoryTeller: line (*) 不访问它,它只是一个指针操作。
-
这不是 UB.. 您只是获取变量的地址并将其转换为
char*然后返回其原始类型。它指向一个有效的对象(地址为z)。 -
您将
f与p别名,这已经是允许的。可以按照[intro.object](字符数组或std::byte)中指定的方式查看对象的存储。那么有什么问题呢? -
@StoryTeller 我给出了一个非常特定的连续对象的反例,显然不能将其视为数组。还是我错了,你是说他们可以吗?
标签: c++ language-lawyer