相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

添加到"char*"指针UB,当它实际上没有指向char数组?

C++ 17(expr.add/4)说:

当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型.如果表达式P指向具有n个元素的数组对象x的元素x [i],则表达式P + J和J + P(其中J具有值j)指向(可能是假设的)元素x [i + j]如果0≤i+j≤n; 否则,行为未定义.同样地,如果0≤i-j≤n,则表达式P-J指向(可能是假设的)元素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;
Run Code Online (Sandbox Code Playgroud)

该行标有(*)UB?reinterpret_cast<char*>(&f)不指向char数组,而是指向浮点数,因此根据引用的段落它应该是UB.但是,如果它是UB,那么它offsetof的用处将是有限的.

是UB吗?如果没有,为什么不呢?

c++ language-lawyer

12
推荐指数
3
解决办法
392
查看次数

你可以对指向另一个对象的char*进行算术运算

这是读取普通可复制对象的字节的常用方法

Object obj;
auto p = reinterpret_cast<char*>(&obj);
for(size_t i = 0; i < sizeof(obj); i++)
    consume(p[i]);
Run Code Online (Sandbox Code Playgroud)

问题不在于严格别名,char*而是允许别名.问题出在[expr.add]的这段话

当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型.如果表达式P指向具有元素x[i]的数组对象xn元素,则表达式P + JJ + P(其中J具有值j)指向(可能是假设的)元素x[i + j]if 0 ? i + j ? n; 否则,行为未定义.同样,表达式P - J指向(可能是假设的)元素x[i ? j]if 0 ? i ? j ? n; 否则,行为未定义.

假设元素所指的地方

过去的阵列的最后一个元素的指针xn元素被认为是等效的指针的假想元件x[n]用于此目的的 …

c++ language-lawyer

7
推荐指数
1
解决办法
206
查看次数