简体   繁体   English

指向 POD 结构的 C/C++ 指针也指向第一个结构成员

[英]C/C++ Pointer to a POD struct also points to the 1st struct member

Can I assume that a C/C++ struct pointer will always point to the first member?我可以假设 C/C++ 结构指针将始终指向第一个成员吗?
Example 1:示例 1:

typedef struct {
 unsigned char  array_a[2];
 unsigned char  array_b[5];
}test;
//..
test var;
//..

In the above example will &var always point to array_a?在上面的例子中 &var 总是指向 array_a 吗? Also in the above example is it possible to cast the pointer to an unsigned char pointer and access each byte separately?同样在上面的例子中是否可以将指针转换为无符号字符指针并分别访问每个字节?
Example 2:示例 2:

function((unsigned char *)&var,sizeof(test));
//...
//...
void function(unsigned char *array, int len){
 int i;
 for( i=0; i<len; i++){
    array[i]++;
 }
}

Will that work correctly?那会正常工作吗?

Note: I know that chars are byte aligned in a struct therefore I assume the size of the above struct is 7 bytes.注意:我知道字符在结构中是字节对齐的,因此我假设上述结构的大小是 7 个字节。

For C structs, yes, you can rely on it.对于 C 结构,是的,您可以依赖它。 This is how almost all "object orientated"-style APIs work in C (such as GObject and GTK).这就是几乎所有“面向对象”风格的 API 在 C 中的工作方式(例如 GObject 和 GTK)。

For C++, you can rely on it only for "plain old data" (POD) types, which are guaranteed to be laid out in memory the same way as C structs.对于 C++,您只能将它用于“普通旧数据”(POD) 类型,这些类型保证在内存中的布局方式与 C 结构相同。 Exactly what constitutes a POD type is a little complicated and has changed between C++03 and C++11, but the crux of it is that if your type has any virtual functions then it's not a POD. POD 类型的确切构成有点复杂,并且在 C++03 和 C++11 之间发生了变化,但关键是如果您的类型具有任何虚函数,那么它就不是 POD。

(In C++11 you can use std::is_pod to test at compile-time whether a struct is a POD type.) (在 C++11 中,您可以使用std::is_pod在编译时测试结构是否为 POD 类型。)

EDIT: This tells you what constitutes a POD type in C++: http://en.cppreference.com/w/cpp/concept/PODType编辑:这告诉你什么构成了 C++ 中的 POD 类型: http : //en.cppreference.com/w/cpp/concept/PODType

EDIT2: Actually, in C++11, it doesn't need to be a POD, just "standard layout", which is a lightly weaker condition. EDIT2:实际上,在 C++11 中,它不需要是一个 POD,只是“标准布局”,这是一个稍微弱一点的条件。 Quoth section 9.2 [class.mem] paragraph 20 of the standard:引用标准的第 9.2 节 [class.mem] 第 20 段:

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.指向标准布局结构对象的指针,使用 reinterpret_cast 适当转换,指向其初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。 [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. [注意:因此,标准布局结构对象中可能存在未命名的填充,但不是在其开头,这是实现适当对齐所必需的。 — end note ] — 尾注 ]

From the C99 standard section 6.7.2.1 bullet point 13:来自 C99 标准第 6.7.2.1 节第 13 条:

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared.在结构对象中,非位域成员和位域所在的单元的地址按它们声明的顺序增加。 A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa.指向结构对象的指针,经过适当转换,指向其初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。 There may be unnamed padding within a structure object, but not at its beginning.结构对象内可能有未命名的填充,但不是在其开头。

The answer to your question is therefore yes.因此,您的问题的答案是肯定的。

Reference (see page 103)参考(见第 103 页)

The compiler is free to add padding and reorganize the struct how it sees fit.编译器可以自由地添加填充并重新组织它认为合适的结构。 Especially in C++ you can add (virtual) functions and then chances are that the virtual table is hidden before that.尤其是在 C++ 中,您可以添加(虚拟)函数,然后很可能在此之前隐藏虚拟表。 But of course that are implementation details.但当然,这是实现细节。 For C this assumption is valid.对于 C,这个假设是有效的。

For C, it's largely implementation-specific, but in practice the rule (in the absence of #pragma pack or something likewise) is:对于 C,它主要是特定于实现的,但实际上规则(在没有 #pragma pack 或类似的情况下)是:

  • Struct members are stored in the order they are declared.结构成员按它们声明的顺序存储。 (This is required by the C99 standard, as mentioned here earlier.) (这是 C99 标准所要求的,如前所述。)
  • If necessary, padding is added before each struct member, to ensure correct alignment.如有必要,在每个结构成员之前添加填充,以确保正确对齐。

So given a struct like所以给定一个结构

struct test{
char ch;
int i;
}

will have ch at offset 0, then a padding byte to align, i at offset 2 and then at the end, padding bytes are added to make the struct size a multiple of 8 bytes.(on a 64-bit machine, 4 byte alignment may be permitted in 32 bit machines)将在偏移量 0 处有 ch,然后是要对齐的填充字节,在偏移量 2 处有 i,然后在最后添加填充字节以使结构大小成为 8 字节的倍数。(在 64 位机器上,4 字节对齐在 32 位机器中可能允许)

So at least in this case, for C, I think you can assume that the struct pointer will point to the first array.所以至少在这种情况下,对于 C,我认为您可以假设 struct 指针将指向第一个数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM