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

如果我有这样的结构:-

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

struct data thing;

它是法律访问abc(&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/

10-15 05:12