2014-07-25 51 views
3

,不知是否安全根据C99的标准,来解释这样一个结构:类型双关语:INT []和struct {INT ...}

struct my_struct_t { 
    int a; 
    int b; 
    int c; 
}; 

作为int[3]。即这个代码片段是否适合所有ABI?

struct my_struct_t f; 
int *i = &f.a; 
i[0] = 1; // f.a == 1 
i[1] = 2; // f.b == 2 
i[2] = 3; // f.c == 3 

据我理解标准,编译器允许在结构成员之后添加填料,但不能是阵列内部的任何填充。我是否正确? (如果我是,那么代码示例将产生不确定的行为。)

+2

这是官方不安全的,但可能会在任何理智的实现上工作,因为没有理由对结构中的int数组和int字段有不同的填充规则。 –

回答

3

唯一真正的“答案”,这是一个引文:

C11,6.7.2.1:

可能有结构对象内的未命名填充,但不在其开始处。 (第15段)
在结构或联合的末尾可能有未命名的填充。 (第17段)

C11,6.2.5:

数组类型描述了一种连续地分配非空集合与特定的成员对象类型的对象(第20段)

由于下标运算符与指针算术运算完全等价,它不能考虑任何可能存在的填充(无论如何)(在目标对象的类型外部),并且可能存在于结构中。

+0

谢谢!你的报价正是我一直在寻找的! – kay

+1

@Kay基本书签材料:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf – Leushenko

3

由于int s是,很好,int -aligned,我认为它应该在大多数平台上工作(它在我的英特尔x86-64与gcc在Linux上)。

您可以检查它是否工作在编译时:

static_assert(offsetof(struct my_struct_t, c) == 2*sizeof(int)); 

当且仅当这一说法并没有失败,该标准保证你是安全的(如果我没有错得要命,但我可以”没有想到任何使它成为UB的东西)。

+0

+1,静态断言会发现错误。 (我主要关心模糊,廉价的嵌入式系统。:-) – kay

+0

**注意**我重新考虑了这个问题,现在我想(假设静态断言成功),它与“struct hack”一样多。哪个IMO符合要求,但许多人不同意(包括标准委员会),尽管没有合格的实施证明我错了。 – mafso