업데이트, 아래 참조!
C ++ 0x를 사용하면 컴파일러가 다음 스 니펫에 대해 "Hello"를 인쇄 할 수 있습니다.
#include <iostream>
int main() {
while(1)
;
std::cout << "Hello" << std::endl;
}
분명히 스레드 및 최적화 기능과 관련이 있습니다. 이것은 많은 사람들을 놀라게 할 수 있다고 생각합니다.
누군가 이것이 왜 이것이 허용되어야했는지에 대해 잘 설명하고 있습니까? 참고로 가장 최근의 C ++ 0x 초안은6.5/5
for 문의 경우 for-init-statement 외부에있는 루프
- 라이브러리 I / O 함수를 호출하지 않으며
- 휘발성 개체에 액세스하거나 수정하지 않으며
- 동기화 작업 (1.10) 또는 원 자성 작업 (원인 29)을 수행하지 않습니다
구현에 의해 종료 될 것으로 가정 될 수있다. [참고 : 이것은 종료를 증명할 수없는 경우에도 빈 루프 제거와 같은 컴파일러 변환을 허용하기위한 것입니다. — 끝 참고]
편집하다:
이 통찰력있는 기사 는 표준 텍스트에 대해 말합니다.
불행히도, "정의되지 않은 행동"이라는 단어는 사용되지 않습니다. 그러나 표준에서 "컴파일러가 P를 가정 할 수 있음"이라고 말하면 속성이 P가 아닌 프로그램에 정의되지 않은 의미가 있음을 의미합니다.
맞습니까? 컴파일러가 위 프로그램에 대해 "Bye"를 인쇄 할 수 있습니까?
여기에 더 많은 통찰력있는 스레드가 있습니다 .이 스레드 는 Guy가 위의 링크 된 기사를 시작한 C와 비슷한 변화에 관한 것입니다. 다른 유용한 사실 중에서도 C ++ 0x에도 적용되는 솔루션을 제시합니다 ( 업데이트 : n3225에서는 더 이상 작동하지 않습니다-아래 참조).
endless:
goto endless;
컴파일러는 루프를 최적화하는 것이 아니라 루프가 아니기 때문에 최적화 할 수 없습니다. 다른 사람은 C ++ 0x 및 C201X의 제안 된 변경 사항을 요약합니다.
루프를 작성하여, 프로그래머는 주장한다 중 루프가 표시 동작에 무언가 (행한다 I / O, 휘발성 액세스 개체 또는 수행 동기 원자 또는 동작)을 수행하는 것이, 또는 그것이 결국 종료있다. 부작용없이 무한 루프를 작성하여 그 가정을 위반하면 컴파일러에 거짓말을하고 프로그램의 동작이 정의되지 않습니다. 운이 좋으면 컴파일러에서 경고를 표시 할 수 있습니다. 언어는 눈에 보이는 동작없이 무한 루프를 표현할 수있는 방법을 제공하지 않습니다 (더 이상 제공하지 않습니까?).
n3225로 3.1.2011 업데이트 :위원회에서 텍스트를 1.10 / 24로 이동하고
구현시 모든 스레드가 결국 다음 중 하나를 수행한다고 가정 할 수 있습니다.
- 끝내다,
- 라이브러리 I / O 함수를 호출하고
- 휘발성 개체에 액세스하거나 수정하거나
- 동기화 작업 또는 원자 작업을 수행합니다.
goto
트릭은 것 없습니다 더 이상 작동!
int x = 1; for(int i = 0; i < 10; ++i) do_something(&i); x++;
수 for(int i = 0; i < 10; ++i) do_something(&i); int x = 2;
있습니까? 또는 다른 방법으로 루프 전에 x
초기화됩니다 2
. 그것은 말할 수 do_something
의 가치에 대해 상관하지 않는다 x
는 완벽하게 안전하고 최적화하므로, 경우에 do_something
발생하지 않습니다의 값 i
이 무한 루프에서 생을 마감하도록 변경할 수 있습니다.
main() { start_daemon_thread(); while(1) { sleep(1000); } }
백그라운드 스레드에서 데몬을 실행하는 대신 즉시 종료 할 수 있습니까?
while(1) { MyMysteriousFunction(); }
신비한 기능의 정의를 모른 채 독립적으로 편집 할 수 있어야합니까? 그렇다면 라이브러리 I / O 함수를 호출하는지 어떻게 알 수 있습니까? 다시 말해서, 첫 번째 글 머리표를 사용할 수 있다는 것은 분명히 함수를 호출하지 않습니다 .