考慮下面的示例方案:轉換一個指針到一個結構到其第一構件
$ gcc -std=c99 -O2 -Wall -Werror -pedantic -o main main.c
預期的輸出是:
$ ./main
a: 4, b: 2
a: 4, b: 2
的C99
#include <stdio.h>
struct base {
int a, b;
};
struct embedded {
struct base base;
int c, d;
};
struct pointed {
struct base* base;
int c, d;
};
static void base_print(struct base* x) {
printf("a: %d, b: %d\n", x->a, x->b);
}
static void tobase_embedded(void* object) {
base_print(object); // no cast needed, suitably converted into first member.
}
static void tobase_pointed(void* object) {
struct base* x = *(struct base**) object; // need this cast?
base_print(x);
}
int main(void) {
struct embedded em = {{4, 2}};
struct pointed pt = {&em.base};
tobase_embedded(&em);
tobase_pointed(&pt);
return 0;
}
編譯時標準說這是關於結構的第一個成員:
C99 6.7.2.1(13): 指向結構對象的指針,經適當轉換後,指向其初始成員...反之亦然。 在結構對象中可能有未命名的填充,但不在其開頭。
在示例程序中的指針struct embedded
而不需要顯式的轉換被轉換爲指針struct base
(通過void*
)。
如果代替第一個成員是指向基地的指針,如struct pointed
會怎樣?我不確定tobase_pointed
內的演員。沒有投射垃圾被打印,但沒有編譯警告/錯誤。通過演員表輸出base.a
和base.b
的正確值,但如果存在未定義的行爲,則這並不意味着太多。
是否將struct pointed
轉換爲其第一個成員struct base*
是否正確?
'struct pointed'的第一個成員是一個指向'struct base'的指針。這將需要解引用'void * object'。但你不能提領'無效*'沒有告訴編譯器如何取消引用指針,因此需要投。 – alvits