그것은 나에게 같습니다 그러나null 포인터가 정의되지 않은 동작에 대해 산술 연산을 수행하고 있습니까? 다음 프로그램이 잘못된 포인터를 계산처럼 <code>NULL</code> 평등에 대한 할당 및 비교하지만 아무것도 좋은 없기 때문에
#include <stdlib.h>
#include <stdio.h>
int main() {
char *c = NULL;
c--;
printf("c: %p\n", c);
return 0;
}
, 그것은 GCC의 경고 또는 측정 장치의 아무도 나처럼 보인다 정의되지 않은 행동을 목표로 한 Clang은 이것이 실제로 UB라고 말합니다. 그 산술은 실제로 유효하고 나는 너무 pedantic인지, 또는 이것은 내가보고해야하는 그들의 점검 메커니즘의 결핍인가? 테스트
는 :
$ clang-3.3 -Weverything -g -O0 -fsanitize=undefined -fsanitize=null -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff
$ gcc-4.8 -g -O0 -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff
이 연타로 사용하고 충분히 공정 그래서 GCC가 나쁜 포인터 역 참조에 더 초점을 맞추고으로 꽤 잘 AddressSanitizer 것을 문서화 것으로 보인다. 그러나 다른 검사는 그것을 잡을하지 않는 중 : -/
편집 : 나는이 질문이 -fsanitize
플래그 생성 된 코드에서 잘 definedness의 동적 검사를 가능하게한다는 것이다 요청 이유의 일부. 그들이 잡았어야 할 것인가?
배열의 일부가 아닌 포인터에 대해 산술 연산을 수행하는 것은 UB입니다 (배열이 아닌 포인터의 경우 one-past-the-end에 대해 +1은 예외입니다). – chris
컴파일러는 한 번에 한 줄만 봅니다. 따라서 c가 NULL이라는 단서가 없습니다. LINT와 같은 것이 이것을 잡을 것입니다. 이 프로그램의 경우에는 C 변수를 역 참조하지 않으므로 무효화되지 않습니다. 이렇게하는 것이 좋습니다. 이점은 모든 f로 인해 64 비트 시스템에서 실행되고 있음을 볼 수 있다는 것입니다. (아마도 프로그램의 요점입니까?) –
@ c.fogelklou : 당신은 완전히 그 지점을 놓쳤습니다. 다른 사람이 올린 내용을 아주 조심스럽게 읽어야합니다. 그들은 그 포인터를 형성하는 것이 정의 된 행동이 아니라는 것을 확인합니다 컴파일러는 실제로 않습니다. – Novelocrat