엄격한 앨리어싱 위반에 대한 내 코드를 확인하려고하는데, 은 엄격한 앨리어싱 규칙을 이해하려고 시도하는 동안 무언가를 놓친 것처럼 보입니다.GCC : 엄격한 앨리어싱 경고의 정확성
#include <stdio.h>
int main(void)
{
unsigned long l;
l = 0;
*((unsigned short *)&l) = 1;
printf("%lu\n", l);
return 0;
}
클래식 및 기본 예제 :
다음 코드를 상상해보십시오. GCC 4.9 (-Wall -fstrict-aliasing -Wstrict-aliasing -O3
)로, 실제로는 오류보고 :
dereferencing type-punned pointer will break strict-aliasing rules
을하지만 다음 잘 컴파일 :
나의 이해에서#include <stdio.h>
int main(void)
{
unsigned long l;
unsigned short * sp;
l = 0;
sp = (unsigned short *)&l;
*(sp) = 1;
printf("%lu\n", l);
return 0;
}
는 두 번째 예는 구조체 앨리어싱 규칙을 위반하는 것입니다.
그럼 왜 컴파일됩니까? GCC의 정확성 문제입니까, 아니면 엄격한 앨리어싱이 적용된 을 놓쳤습니까? Why are no strict-aliasing warnings generated for this code?
-Wstrict-aliasing=2
또는 -Wstrict-aliasing=3
는 차이가 없습니다로 컴파일 :
그러나
-Wstrict-aliasing=1
은 두 번째 예에서 오류를보고합니다.
GCC 문서는 그래서 여기에 무슨 일이 일어나고 있는지
... 레벨 3이 가장 정확한 동안 레벨 1은 정확하고 가장, 그리고 잘못된 반응을 많이 을 생산할 수 있다고? 내 자신의 이해에 문제가 있거나 GCC에 문제가 있습니까?보너스 질문
난 보통 내 프로젝트에 대한 GCC를 통해 연타/LLVM을 선호하지만 연타 엄격한 앨리어싱에 대한 경고를하지 않는 것 같다.
이유를 아는 사람이 있습니까?
위반을 감지 할 수 없기 때문에 또는 코드를 생성 할 때 규칙을 따르지 않아서입니까?
컴파일러는 두 번째 예제에서 'l'의 값이 일정하다고 가정 할 수 있기 때문에 문제가 발생합니다. – Macmade
에일리어싱 위반이있는 것은 코드 자체를 실행하지 않고도 상황에 따라 탐지하기 어렵다는 것입니다.이것이 제약 조건 위반 (모든 컴파일러에서 감지해야하는 오류)이 아닌 "just"동작이 정의되지 않은 이유입니다.이 문제에 대해 보증 할 수있는 최적화 컴파일러를 작성하는 것이 악몽이기 때문입니다. 그러한 포인터 캐스트로 프로그램하는 유효한 이유는 거의 없으며 중간 '유니온 (union)'을 사용하거나 'unsinged char *'에 캐스트하지 않는 것입니다. –
여기서 -Wstrict-aliasing = 1은 "may", -Wstrict-aliasing = 2는 경고를 "will"으로, -Wstrict-aliasing = 3은 경고를주지 않습니다. – AProgrammer