빠른 간단한 질문; 는이C : 다른 크기의 구조로 캐스팅
typedef struct {int a; int b;} S1;
typedef struct {int a;} S2;
((S2*)(POINTER_TO_AN_S1))->a=1;
항상 구조의 멤버를 반환 (및 지정)합니까? 아니면 정의되지 않은 동작입니까?
빠른 간단한 질문; 는이C : 다른 크기의 구조로 캐스팅
typedef struct {int a; int b;} S1;
typedef struct {int a;} S2;
((S2*)(POINTER_TO_AN_S1))->a=1;
항상 구조의 멤버를 반환 (및 지정)합니까? 아니면 정의되지 않은 동작입니까?
준수 컴파일러에서 구조체가 액세스되는 곳에서 볼 수있는 공용체 형식의 완전한 정의 내에 두 구조체 형식이 모두 나타나고 포인터의 대상이 해당 공용체 형식의 인스턴스가 된 경우 정의되어야한다. 표준에서는 컴파일러가 포인터의 대상이 실제로 해당 공용 형식의 개체인지 알 수있는 방법이 필요하지 않습니다. 단순히 전체 공용 형식 선언이 표시 될 수 있습니다.
그러나 -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);
}
컴파일러가 더 U1-> s1.x는 기록 후 U2-> s2.x, 비록의 값을 다시 읽어 필요가 없다고 결정하는 것 완전한 조합 유형 이 표시되며 컴파일러에서 u1과 u2가 모두 유니온 유형의 객체에 대한 포인터임을 알 수 있습니다. 나는 gcc의 저자가 이 결과 포인터가 심지어 해당 멤버 유형의 객체에 액세스하는 데 사용될 수없는 경우에도 공용체 유형에 적용될 때 address-of 연산자가 의미한다고 생각하는지 확실하지 않습니다.
언어 태그는 코드가 관련되어있을 때 중요합니다 (즉, 스택 오버플로에서 거의 항상 여기에 있음). – crashmstr