2017-04-03 108 views
0

快速簡單的問題結構; 這是否C:鑄造具有不同尺寸

typedef struct {int a; int b;} S1; 
typedef struct {int a;} S2; 
((S2*)(POINTER_TO_AN_S1))->a=1; 

總是返回(和分配)的部件結構的?或者它是不確定的行爲?

+0

語言標記是很重要的。 – crashmstr

回答

0

在相符的編譯器,如果兩個結構類型出現的聯合類型,其是可見的,其中所述結構被訪問,並且如果指針的目標正好是該聯合類型的一個實例,行爲會的完整的定義內被定義。請注意,標準並不要求編譯器有任何方式知道指針的目標實際上是該聯合類型的一個對象 - 僅僅是整個聯合類型的聲明是可見的。

注意,但是,GCC不被這裏的標準遵守,除非使用-fno-strict-aliasing標誌。即使在整體聯合類型可見的情況下,編譯器可以看到它實際上處理聯合類型的對象,gcc也會忽略別名。例如,給定:

struct s1 {int x;}; 
struct s2 {int x;}; 
union u { struct s1 s1; struct s2 s2;}; 

int read_s1_x(struct s1 *p) { return p->x; } 
int read_s2_x(struct s2 *p) { return p->x; } 
int write_s1_x(struct s1 *p, int value) { p->x = value; } 
int write_s2_x(struct s2 *p, int value) { p->x = value; } 

int test(union u *u1, union u *u2) 
{ 
    write_s2_x(&u2->s2, 0); 
    if (!read_s1_x(&u1->s1)) 
    write_s2_x(&u2->s2, 1); 
    return read_s1_x(&u1->s1); 
} 

編譯器將決定它沒有也不需要重新讀取的 U1-> s1.x寫入後U2-> s2.x,即使價值完成聯合類型 是可見的,即使編譯器可以看到,無論是U1和U2是 指向工會類型的對象。我不太知道什麼GCC的 筆者認爲地址的運營商應該在 應用於聯合類型,如果結果指針甚至不能被用來 立即訪問該成員類型的對象來表示。當代碼中包含(即幾乎都是在這裏對堆棧溢出)