在 C++11 中使用严格的混叠时,它是否定义为 _write_ 到 char*,然后从别名的非 char* 读取_
With strict aliasing in C++11, is it defined to _write_ to a char*, then _read_ from an aliased nonchar*?
有很多关于严格混叠的讨论(特别是"什么是严格混叠规则?"和"严格的混叠规则和'char *'指针"(,但这是一个我没有看到明确解决的极端情况。
请考虑以下代码:
int x;
char *x_alias = reinterpret_cast<char *>(&x);
x = 1;
*x_alias = 2; // [alias-write]
printf("x is now %dn", x);
打印的值必须反映 [别名写入] 中的更改吗?(显然有字节序和表示方面的考虑,这不是我关心的问题。
C++11规范中著名的[basic.lval]子句使用了这种语言(强调我的(:
如果程序尝试通过以下类型之一以外的 glvalue 访问对象的存储值,则行为是未定义的:
- 。各种其他条件...
char
或unsigned char
类型。
我无法弄清楚"访问"是指读取操作(从非字符对象读取字符(还是也指写入操作(将字符写入非字符对象(。如果在规范中有"访问"的正式定义,我找不到它,但在其他地方,规范似乎使用"访问"进行读取,使用"更新"进行写入。
这在反序列化时特别有趣;将数据直接从线路引入对象既方便又高效,而不需要中间 memcpy(( 从 char-buffer 到对象中。
它是否定义为_写入_到字符*,然后从别名非字符*_读取_?
是的。
打印的值必须反映 [别名写入] 中的更改吗?
是的。
严格混叠说((un
(signed
(char*
可以混叠任何东西。"访问"一词意味着读取和写入操作。
C89 标准的作者希望允许
例如int thing;
unsigned char *p = &x;
int i;
for (i=0; i<sizeof thing; i++)
p[i] = getbyte();
和
int thing = somevalue();
unsigned char *p = &x;
int i;
for (i=0; i<sizeof thing; i++)
putbyte(p[i]);
但不要求编译器处理给定某些内容的任何可能的别名喜欢:
/* global definitions */
int thing;
double *p;
int x(double *p)
{
thing = 1;
*p = 1.0;
return thing;
}
支持和不支持的情况有两种不同之处:(1( 在要支持的情况下,访问是使用字符类型指针而不是其他类型进行的,以及 (2( 在相关事物的地址转换为另一种类型后,使用该指针对存储的所有访问都是在下一次使用原始 lvalue 进行访问之前进行的。 不幸的是,该标准的作者只认为第一个是重要的,尽管第二个是识别别名可能很重要的情况的更可靠的方法。 如果标准侧重于第二个,则可能不需要编译器识别示例中的别名。 但是,该标准要求编译器在程序使用字符类型时随时识别别名,尽管这会对处理实际字符数据的代码的性能产生不必要的影响。
C和C++的其他标准没有纠正这个根本性错误,而是简单地继续使用相同的错误方法。
- 将"uint8_t"(从套接字读取)隐式转换为"char"安全吗
- 从二进制流中读取时,将双精度变量的地址转换为 char* 意味着什么?
- 通过 char* 缓冲区读取 int 的行为是不同的,无论是正数还是负数
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- 将 ifstream 读取到 char* 以进行 int 和字符串转换
- 是否很好地定义了强制转换为仅由 char[] 组成的结构并从该数组读取?
- char* 如何读取十六进制的这个整数?它在 ostream::write() 中是如何工作的
- 将文本文件读取为 const char* 有时有效,有时无效
- C 通过char读取文件字符串的文件char;崩溃
- 输入重定向读取整数和char C
- C 读取输入,直到线char数组的结束
- 如何通过C 读取CHAR的文件字符
- C 如何读取从文件到char数组的文本行
- 如何使用boost.asio读取整个Char类型的数据
- 交替读取为char*和wchar_t*
- 无法在C++中使用reinterpret_cast<char*>读取数据
- 在 C++11 中使用严格的混叠时,它是否定义为 _write_ 到 char*,然后从别名的非 char* 读取_
- 将二进制文件读入向量<char>读取小于完整文件
- 从char读取命令行
- 从 std::vector<unsigned char> 读取二进制数据的最简单方法?