不管代码有多“糟糕”,并且假设对齐等在编译器/平台上不是问题,这是未定义或损坏的行为吗?
如果我有这样的结构:-
struct data
{
int a, b, c;
};
struct data thing;
它是法律访问
a
,b
和c
为(&thing.a)[0]
,(&thing.a)[1]
和(&thing.a)[2]
?在每种情况下,在我尝试过的每个编译器和平台上,我尝试过的每个设置都“有效”。我只是担心编译器可能没有意识到 b 和 thing[1] 是相同的东西,并且可能从内存中读取错误的值并存储在内存中例如)。在每种情况下,我都尝试过它做了正确的事情。 (我当然意识到这并不能证明什么)
这不是我的代码;这是我必须使用的代码,我想知道这是 坏 代码还是 损坏的 代码,因为它改变了我的优先级代码:
标记 C 和 C++ 。我主要对 C++ 感兴趣,但也对 C 感兴趣,如果它不同,只是为了兴趣。
最佳答案
这是非法的 1. 这是 C++ 中的未定义行为。
您以数组方式获取成员,但这是 C++ 标准所说的(重点是我的):
但是,对于成员来说,没有这样的连续要求:
虽然上面的两个引号应该足以暗示为什么索引到 struct
不是 C++ 标准定义的行为,让我们举一个例子:看看表达式 (&thing.a)[2]
- 关于下标运算符:
深入研究上述引用的粗体文本:关于将整数类型添加到指针类型(注意这里的重点)。
请注意 if 子句的数组要求;否则 否则 在上面的报价中。表达式 (&thing.a)[2]
显然不符合 if 子句;因此,未定义的行为。
附带说明:虽然我已经在各种编译器上对代码及其变体进行了广泛的试验,但它们在这里没有引入任何填充,(它有效);从维护的角度来看,代码是极其脆弱的。在执行此操作之前,您仍然应该断言实现是连续分配成员的。并留在界内:-)。但它仍然是未定义的行为......
其他答案提供了一些可行的解决方法(具有定义的行为)。
正如评论中正确指出的那样, [basic.lval/8] 不适用。感谢@2501 和@M.M.
1:请参阅@Barry 对此问题的回答,了解唯一一种可以通过此部件访问结构体的 thing.a
成员的法律案例。
关于c++ - 对结构进行索引是否合法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40590216/