4
이 코드를 고려하십시오. 패딩의 존재가 보장됩니다. 그 static_assert
의와구조체 또는 공용체의 패딩에 액세스하는 것이 안전합니까?
static_assert(_Alignof(char) < _Alignof(double), "Flip!");
static_assert(sizeof(char) < sizeof(double), "Flop!");
struct S {
char c[1];
double d;
};
union U {
char c[1];
double d;
};
static_assert(sizeof(struct S) == _Alignof(double) * sizeof(double), "Fudge!");
static_assert(sizeof(union U) == sizeof(double), "Futz!");
S s; U u;
s.c[1] = 0; // What?
u.c[1] = 0; // What?
, 그것은 패딩 중간이나 끝이 확실합니다. 그것들에 접근하는 것이 안전합니까?
Afaik 컴파일러는 가능할 때마다 디버그 빌드의 배열에 대한 바운드 검사를 수행 할 수 있으므로 UB입니다. punnig 유형에 관해서는 그것에 대한 질문이 있습니다 : [C99에서 un-type union을 통한 유형 - 펀닝이 C11에서 지정 되었습니까? Ask] (https://stackoverflow.com/questions/11639947/is-type-punning-through-a-union-unspecified-in-c99-and-has-it-become-specified) – Ivan
alligbnment는 그리 많지 않습니다. 이웃 필드 때문에 대개 감지되지 않는 배열 오버로드에 이르지 만'c [1]'은 오류입니다 –
패딩에 안정적으로 액세스 할 수 없습니다. 구조체 (유니언) 할당에서 복사중인 패딩에 의존 할 수 없습니다. 거기에 바이트가 있다는 의미에서 액세스하는 것은 "안전"합니다. 의미 있고 신뢰할 수있는 것은 없습니다. 만약 당신이 그런 바이트들을 사용한다면, 명시 적으로 :'struct S2 {char c [1]; 짧은 s; int i; 더블 d; }'(32 비트 Intel x86을 제외한 대부분의 시스템에서는 질문에서'struct S'와 크기가 같습니다). 그리고 첫 번째 정적 어설 션은 32 비트 x86에서 시작됩니다. –