不管代码有多“糟糕”,并且假设对齐等在编译器/平台上不是问题,这是未定义或损坏的行为吗?
如果我有这样的结构:-
struct data
{
int a, b, c;
};
struct data thing;
是吗法律 访问
a
, b
和 c
如 (&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 elementx[i]
of an array objectx
with n elements, the expressionsP + J
andJ + P
(whereJ
has the valuej
) point to the (possibly-hypothetical) elementx[i + j]
if0 ≤ 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/