c++ - 对结构进行索引是否合法?

标签 c++ c struct

不管代码有多“糟糕”,并且假设对齐等在编译器/平台上不是问题,这是未定义或损坏的行为吗?

如果我有这样的结构:-

struct data
{
    int a, b, c;
};

struct data thing;

是吗法律 访问 a , bc(&thing.a)[0] , (&thing.a)[1] , 和 (&thing.a)[2] ?

在每种情况下,在我尝试过的每个编译器和平台上,我尝试过的每个设置都“有效”。我只是担心编译器可能没有意识到 b 东西[1] 是相同的东西,存储到 'b' 可能会放在寄存器中,而 thing[1] 从内存中读取错误的值(例如)。在每种情况下,我都尝试过它做了正确的事情。 (我当然意识到这并不能证明什么)

这不是我的代码;这是我必须使用的代码,我感兴趣的是这是否是 代码或 splinter 代码因为不同会影响我改变它的优先级:)

标记 C 和 C++ 。我主要对 C++ 感兴趣,但也对 C 感兴趣,如果它不同,只是为了兴趣。

最佳答案

这是非法的 1. 这是 C++ 中的未定义行为。

您以数组方式获取成员,但这是 C++ 标准所说的(重点是我的):

[dcl.array/1]: ...An object of array type contains a contiguously allocated non-empty set of N subobjects of type T...



但是,对于成员来说,没有这样的连续要求:

[class.mem/17]: ...;Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other...



虽然上面的两个引号应该足以暗示为什么要索引到 struct正如你所做的不是 C++ 标准定义的行为,让我们举一个例子:看看表达式 (&thing.a)[2] - 关于下标运算符:

[expr.post//expr.sub/1]: A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall be a glvalue of type “array of T” or a prvalue of type “pointer to T” and the other shall be a prvalue of unscoped enumeration or integral type. The result is of type “T”. The type “T” shall be a completely-defined object type.66 The expression E1[E2] is identical (by definition) to ((E1)+(E2))



深入研究上述引用的粗体文本:关于将整数类型添加到指针类型(注意这里的重点)。

[expr.add/4]: When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i + j] if 0 ≤ i + j ≤ n; otherwise, the behavior is undefined. ...



请注意 的阵列要求如果 条款;否则 否则 在上面的报价中。表达式 (&thing.a)[2]显然没有资格获得如果 条款;因此,未定义的行为。

附带说明:虽然我已经在各种编译器上对代码及其变体进行了广泛的试验,但它们在这里没有引入任何填充,(它有效);从维护的角度来看,代码是极其脆弱的。在执行此操作之前,您仍然应该断言实现是连续分配成员的。并留在界内:-)。但它仍然是未定义的行为......

其他答案提供了一些可行的解决方法(具有定义的行为)。



正如评论中正确指出的那样, [basic.lval/8] ,这在我之前的编辑中不适用。感谢@2501 和@M.M.

1:有关您可以访问的唯一一个法律案例,请参阅@Barry 对此问题的回答 thing.a结构的成员通过这个parttern。

关于c++ - 对结构进行索引是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56877648/

相关文章:

c++ - C++ 中的 copy_if ……有问题

c - 对 argv 中的值进行排序

c - 3求和算法来求方程

通过结构数组中的函数指针调用函数

c++ - 比较 Fortran 和 C++ 汇编程序的 int = floor(sqrt(...))

c++ - 指向 glutDisplayFunc 函数的指针

c++ - 通过语音在字典中查找单词

c - 下面的符号都指向什么?

c++ - 计算结构大小而不填充字节的函数

c - 使用 fwrite 将结构存储在文件中