모호한 주장을 조사 하면서이 작은 테스트 프로그램을 작성했습니다noway.c
int proveit()
{
unsigned int n = 0;
while (1) n++;
return 0;
}
int main()
{
proveit();
return 0;
}
이것을 테스트하면 다음을 얻습니다.
$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction ./a.out
왓.
최적화없이 컴파일하면 예상대로 중단됩니다. 나는 어셈블리를 보았고 모든 종소리와 휘파람없이 main
기능은 다음과 같습니다.
_main: ## @main
pushq %rbp
movq %rsp, %rbp
ud2
ud2
명확하게 정의되지 않은 동작에 대한 지침은 어디에 있습니까 ? 앞서 언급 한 모호한 주장 인 "반환하지 않는 함수는 UB이다"는 강조가된다. 그래도 여전히 믿기가 어렵습니다. 정말!? 스핀 루프를 안전하게 작성할 수 없습니까?
그래서 내 질문은 다음과 같습니다.
- 이것은 무슨 일이 일어나고 있는지에 대한 정확한 독서입니까?
- 그렇다면 누군가가 그것을 확인하는 공식 리소스를 알려줄 수 있습니까?
- 이 유형의 최적화가 발생하기를 원하는 상황은 무엇입니까?
관련 정보
$ clang --version
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
3
IIRC, signed int overflow는 UB입니다.
—
wildplasser
int n = 0
unsigned int n = 0;
while (1);
흠 ... 컴파일러 탐색기 clang은 -O gcc.godbolt.org/z/NTCQYT 및 자체 번역없이 자체 대상 점프 명령을 받습니다 . 여러 버전에서 일관된 것으로 보입니다. 그러나 나는 또한 C 표준에 따르면 부작용이 없으면 비 종료가 ub라고 말합니다 (참조하지는 않지만) . Hans Boehm은 이것이 불가능한 특정 컴파일러 최적화를 허용한다고 설명합니다. open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm
—
Gene
정의되지 않은 동작은 무한 루프가 아닌 부호있는 정수 오버플로입니다. 당신은을 사용하여 문제를 해결할 수
—
MM
unsigned int
@ 제네 나는 그렇게 생각하지 않습니다. 비 충돌 제어식이있는 부작용이없는 루프는 종료 된 것으로 간주 될 수 있지만 ( port70.net/~nsz/c/c11/n1570.html#6.8.5p6 ) 사용 중 루프는 양호합니다. UB는 정수 오버플로에 있지만 UD 명령으로 예제를 재현 할 수는 없습니다.
—
PSkocik