2013-08-26 35 views
4

我在想,是從一個指向一個不完整類型的未定義行爲的指針嗎?這是「類型狡猾」明確嗎?

struct _obj; 
typedef _obj obj; 

typedef struct{ 
    int val; 
} obj_int; 

void print_stuff(obj* o){ 
    printf("%d\n", ((*obj_int)(o)) -> val); 
} 
+0

where'd'obj * o'從哪裏來?另一個演員,或者是'struct _obj'完成,'struct _obj'的實際實例存在,並且'o'是它的地址? –

回答

6

通常。

標準6.3.2.3/7:

一個指向對象或不完整的類型可被轉換成一個指針到一個不同的 對象或不完整的類型。如果生成的指針未針對 指向類型正確對齊,則行爲未定義。否則,當再次轉換時, 結果應與原始指針相等。當一個指向對象的指針被 轉換爲指向字符類型的指針時,結果指向該對象的最低尋址字節 。結果的連續增量,直到對象的大小,產生對象的剩餘字節的指針 。

因此,如果o指向其第一個成員爲int的任何結構對象,那就沒問題。如果它指向從malloc獲得的內存的開始,其中已經寫入int的表示,則表示沒有問題。但是,如果它指向char[sizeof(int)]或某些此類事物,則可能有對齊問題。

+1

我同意「如果'o'指向任何第一個成員是int的結構對象,那麼你很好。目前尚不清楚'int'的表述是怎麼寫的「,它聽起來不像是正確的條件(這是一個'int'或'char'類型的左值被用來存儲值) 。 –

+0

這是哪個版本的標準?在我的副本中,「不完整類型」字樣不會出現在6.3.2.3/7中。 –

+0

@Paul:6.3.2.3,而不是6.2.3.2 –

1

您提供的信息不足以回答您的問題。 如果你施放一個obj_int*obj*,然後傳遞到print_stuff然後你的代碼,因爲你讓一個指針轉換到另一個指針類型和背照C標準是合法的。但是,如果以其他任何方式獲得print_stuff的參數,則表明您的行爲未定義。