mas*_*cai 4 c++ strict-aliasing language-lawyer
这段代码中是否存在严格别名规则违规?我认为int
->char
和int
->std::byte
都可以,但是呢int8_t
?
int main() {
int arr[8] = {1, 1, 1, 1, 1, 1, 1, 1}; // Little endian: 10000000 | 10000000 ....
int8_t *ptr = (int8_t*)arr; // Do we have a violation of the Strict Aliasing rule in this cast?
ptr += 3; // 100[0]0000 ....
cout << (int)*ptr << endl; // outputs 0
return 1;
}
Run Code Online (Sandbox Code Playgroud)
\n\nRun Code Online (Sandbox Code Playgroud)\nint8_t *ptr = (int8_t*)arr;\n
这完全没问题,相当于reinterpret_cast
.\n强制转换本身从来都不是严格的别名冲突;所指向对象的访问权限是。请参阅什么是严格的别名规则?更多细节。
\n\nRun Code Online (Sandbox Code Playgroud)\ncout << (int)*ptr << endl; // outputs 0\n
这是未定义的行为 ( [basic.lval] p11int
),因为您正在通过 类型的泛左值访问 an int8_t
。\n只有 、 和 的例外char
,unsigned char
并且std::byte
很int8_t
可能是 的别名signed char
。
\n\nRun Code Online (Sandbox Code Playgroud)\nptr += 3;\n
这是未定义的行为:
\n\n\n\n对于加法或减法,如果表达式 P 或 Q 的类型为 \xe2\x80\x9c 指向 cv T\xe2\x80\x9d 的指针,其中 T 和数组元素类型不相似,则行为未定义。
\n
\n[示例 1 :Run Code Online (Sandbox Code Playgroud)\nint arr[5] = {1, 2, 3, 4, 5};\nunsigned int *p = reinterpret_cast<unsigned int*>(arr + 1);\nunsigned int k = *p; // OK, value of k is 2 ([conv.lval])\nunsigned int *q = p + 1; // undefined behavior: p points to an int, not an unsigned int object\n
\xe2\x80\x94结束示例]
\n
您所做的实际上是相同的,只是使用int8_t
而不是unsigned int
.
\n\n我是这么想的
\nint -> char
,int -> std::byte
但是那又怎样呢int8_t
?
强制转换本身总是好的,但只有std::byte
或char
具有也使(1)p += 3
有效的特殊属性。
int8_t
很可能是 的别名,与和signed char
相比,它的魔力要少得多。\n有关魔力的摘要,请参阅此答案的附录。unsigned char
std::byte
(一)标准措辞有缺陷且不支持的;请参阅添加到“char *”指针 UB,但它实际上并未指向 char 数组?。
\n 归档时间: |
|
查看次数: |
147 次 |
最近记录: |