2017-04-03 1 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

適合するコンパイラで、両方の構造体型が、構造体がアクセスされる場所で表示される共用体型の完全な定義内に現れ、ポインタのターゲットがその共用体型のインスタンスであった場合、定義される。 Standardは、ポインタのターゲットが実際にその共用体型のオブジェクトであることをコンパイラが知る方法を必要としないことに注意してください。単なる完全な共用体型の宣言が見えるだけです。

しかし、-fno-strict-aliasingフラグが使用されていない限り、gccはここに記載されている規格を遵守していないことに注意してください。完全な共用体型が可視で、コンパイラが実際に共用体型のオブジェクトを処理していることがわかる場合でも、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); 
} 

コンパイラはU2-> s2.x書き込みをした後、それは何にもかかわらず、 U1-> s1.xの再読み込み値を必要としないことを決定していないだろう完全なユニオンタイプ が表示され、コンパイラはu1とu2の両方がユニオンタイプのオブジェクトへのポインタ であることを認識することができます。私は、 gccの作者が、 が結果のポインタを使用しても使用できない場合に、そのメンバ型のオブジェクトにすぐにアクセスすると、address-of演算子が意味すると考えていることを確信していません。

関連する問題