如果其他成员跟在结构成员的末尾,则写入/读取该末尾
Write/read past the end of structure member if another member follows it
假设我有一个结构:
struct Foo{
char a[4];
char b[4];
//...some other members
} foo, foo2;
让我们假设a
和b
之间没有填充,所以offsetof(Foo, a) == 0
和offsetof(Foo, b) == 4
,并且Foo
是POD。
标准如何定义以下内容?
putc(foo.a[4]);
// Am I allowed to read past the `a` array?
foo.a[4] = 0;
// What is (foo.b[0]) ?
memcpy(foo.a, "ABCDEFGH", 8);
// Is foo.b equals "EFGH"?
memcpy(foo2.a, foo.a, 8);
// Is foo2.b equals foo.b?
在我的理解中,如果我从以下法律表达开始:
*((char*)&foo + offsetof(Foo, b))
我可以应用一系列替换:
*((char*)&foo + 4)
*((char*)&foo + 0 + 4)
*((char*)&foo + offsetof(Foo, a) + 4)
*(foo.a + 0 + 4)
*(foo.a + 4)
foo.a[4]
另外两个是合法的,因为foo.a
等价于(char*)&foo
,如果我们足够小心的话,我们可以memcpy
的一部分结构。
不允许读取或写入foo.a[4]
。
如[dcl.array]/6中所述,
类型为"的对象;CCD_ 10CCD_;由类型为
U
的N
子对象的连续分配的非空集合组成,称为阵列的元素,编号为0
至N-1
。
foo.a
中没有元素4。
现在,【basic.compound】/3确实声明:
[…]为了进行指针算术(7.6.6)和比较(7.6.9、7.6.10)n元素的数组
x
的最后一个元素被认为等价于指向假设数组的指针x
的元素n和不是数组元素的T
类型的对象被认为属于数组具有一个类型为CCD_ 20的元件。[…]
这使得表达式foo.a + 4
定义良好;它是指向";假设的";索引为4的元素。然而,没有实际的这样的对象,因此没有什么可读取或写入的。
你可能会反对";在那里有一个对象:CCD_ 22";。然而,这种解释与〔basic.compound〕/3:中给出的指针值分类法相矛盾
〔…〕指针类型的每个值都是以下值之一:
- 指向对象或函数的指针(据说该指针指向指向对象或函数),或
- 一个指针经过对象的末尾(7.6.6),或
- 该类型的空指针值,或者
- 无效的指针值
[…]
因为指针foo.a + 4
是经过foo.a
末尾的指针,所以它也不能是指向foo.b[0]
的指针,即使它们表示的地址值可能相同(假设a
和b
之间没有填充)。它只能分为四类中的一类。
对于将一元*
运算符应用于过去的结束指针值是否实际合法,该标准在措辞上存在差距。[expr.unary.op]/1表示一元CCD_;产生表示操作数所指向的对象或函数的CCD_ 30类型的左值"如果没有这样的对象,则不清楚行为是否定义明确;你得到一个";"lvalue through the end";,还是你得了UB?然而,所有已知的实现都将其视为不是UB(它们允许在常量表达式求值期间使用它)。只有当你尝试阅读或写作时,行为才是不明确的。
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 从 XML 中读取未指定结构的每个数据成员
- 错误:"shared_mutex"不是使用读取器锁定 = std::shared_lock<std::shared_mutex> 的"std"的成员;
- 多个线程可以读取同一个类成员变量吗?
- C++模板以从成员变量或成员函数中读取值
- 从C++代码中直接读取成员属性
- 无法使用 InFile 正确地从文件读取到结构成员中
- C++从 csv 文件中读取,然后将数据分配给类成员
- 为什么C++编译器不优化对结构数据成员的读取和写入,而不是不同的局部变量?
- 从结构传递数组成员会导致访问读取冲突
- C :从TXT文件读取和写入的成员函数
- 为仅读取成员分配值-C
- 如果其他成员跟在结构成员的末尾,则写入/读取该末尾
- 如何在 c++ 中使用二进制文件输入/输出读取/写入结构的字符串类型成员
- 如何从另一个类读取结构成员
- C++ 将数组传递给函数并读取其成员
- 读取文本文件并将数据存储在类的私有成员变量中-C++
- 将非零矢量成员读取为阵列和输出点产品
- Valgrind 抱怨通过指向结构的指针访问结构成员时读取无效
- 尝试使用成员函数访问动态分配的成员变量时读取访问冲突