在一种结构中,使用一个数组字段访问另一个字段是否合法? [英] In a structure, is it legal to use one array field to access another one?

查看:93
本文介绍了在一种结构中,使用一个数组字段访问另一个字段是否合法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为示例,请考虑以下结构:

As an example, consider the following structure:

struct S {
  int a[4];
  int b[4];
} s;

s.a[6]并期望它等于s.b[2]是否合法? 就个人而言,我认为它必须是C ++中的UB,而我不确定C. 但是,我找不到与C和C ++语言标准相关的任何内容.

Would it be legal to write s.a[6] and expect it to be equal to s.b[2]? Personally, I feel that it must be UB in C++, whereas I'm not sure about C. However, I failed to find anything relevant in the standards of C and C++ languages.

更新

有几个答案建议了确保没有填充的方法 字段之间,以使代码可靠地工作.我想强调 如果这样的代码是UB,那么缺少填充是不够的.如果是UB, 那么编译器可以自由地假定对S.a[i]S.b[j]的访问不 重叠,并且编译器可以自由地对这些内存访问进行重新排序.例如,

There are several answers suggesting ways to make sure there is no padding between fields in order to make the code work reliably. I'd like to emphasize that if such code is UB, then absense of padding is not enough. If it is UB, then the compiler is free to assume that accesses to S.a[i] and S.b[j] do not overlap and the compiler is free to reorder such memory accesses. For example,

    int x = s.b[2];
    s.a[6] = 2;
    return x;

可以转换为

    s.a[6] = 2;
    int x = s.b[2];
    return x;

始终返回2.

推荐答案

写s.a [6]并期望等于s.b [2]是否合法?

Would it be legal to write s.a[6] and expect it to be equal to s.b[2]?

.因为无法访问数组,所以在C和C ++中调用了未定义的行为.

No. Because accessing an array out of bound invoked undefined behaviour in C and C++.

C11 J.2未定义行为

  • 在数组对象或整数类型之内或之后添加或减去一个指针所产生的结果指向的对象恰好超出 数组对象,并用作一元*运算符的操作数,该运算符 被评估为(6.5.6).

  • Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that points just beyond the array object and is used as the operand of a unary * operator that is evaluated (6.5.6).

数组下标超出范围,即使对象显然可以通过给定下标访问(如左值表达式中一样) a[1][7]声明为int a[4][5])(6.5.6).

An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).

C ++标准草稿 5.7节加法运算符"第5段说:

C++ standard draft section 5.7 Additive operators paragraph 5 says:

将具有整数类型的表达式添加或减去时 从指针开始,结果具有指针操作数的类型.如果 指针操作数指向数组对象的元素,并且该数组 足够大,结果指向的元素与 原始元素,使得下标的差异 结果数组元素和原始数组元素等于整数表达式. [...] 如果指针操作数和结果都指向元素 相同的数组对象,或者在数组的最后一个元素之后 目标,评估不得产生溢出;否则, 行为是不确定的.

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 pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integral expression. [...] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

这篇关于在一种结构中,使用一个数组字段访问另一个字段是否合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆