2013-01-06 5 views
1

main의이 몸을 고려해 그 잘 정의 여부에 대해랜덤 루프 종료 조건을 갖는 것이 잘 정의되어 있습니까?

std::srand(std::time(nullptr)); 
while (std::rand()); 

놀랍게도, 나는 그것이 구글에 사양에 수 있는지, 무엇을 찾거나이 웹 사이트에 없습니다. 규격에 같이

[참고 : 반복 제표 조건 요구 6.4에서 설명

N3485 § 6.5/4 는 [stmt.iter]은 조건에 대해 이것을 말한다. - 끝말]

그러나 6.4에서 보았을 때 나는이 시나리오를 언급하지 않았습니다. 이론적으로 루프는 사실상 영원히 지속될 수 있지만 실제로는 보통 5ms의 실행 시간을 가지며 모든 테스트 실행에서 한 번은 22ms입니다.

변경 (의사) 난수에서 루프 종료 조건을 기반으로하는 것은 잘 정의 된 동작입니까? 그렇지 않은 경우 어떤 행동입니까?

+6

왜 이것이 특별한 경우입니까? 이것은 사용자 입력에 따라 달라지는 루프와 어떻게 다른가? (둘 다 비 결정적입니다.) –

+0

@OliCharlesworth, 좋은 지적, 결코 저에게 일어난 일이 아닙니다. 그러나 그 스펙은 그것이 유효하다고 어디에서 말합니까? 나는 6.4를 다시 읽고, 아마도 나는 명백한 것을 놓치고 있지만 그것을 데리러 가지 않았다. – chris

+4

그러나 왜 표준이 특별히이 문제를 해결해야하는지 잘 모르겠습니다 ... –

답변

7

std::rand()이 반복 될 때마다 호출 할 것입니다, 다음 루프는 반환 값에 따라 또는하지 갈 것입니다.

여기에 정의되지 않은 동작이있을 이유가 없습니다. 이 경우이 특별하다고 생각되는 이유는 무엇

그것은이

while (my_vector.empty()); 

같은 일을 다른 아니에요?

+0

다른 좋은 지적입니다. 나는 그것이 무한 루프 일 수 있다는 사실에 매달려 있었다. 그러나 둘 다 단순히 정의 된 작업을하고있다. – chris

+0

@chris : 절대로 무한 루프가 아닙니다. 'while (true)'와는 달리 (수십억 년이 걸린다해도) 결국 끝내도록 효과적으로 보장됩니다. –

+0

@LightnessRacesinOrbit 이론적으로나 실제적으로 무한 루프 일 수 있습니다. 이론적으로 완전한 RNG가 주어진다면 확률은 매우 작지만 0과 같지 않습니다. 실질적으로,'rand()'는 값의 유한 한 사이클을 생성하는 의사 RNG이고, 그 사이클은 0을 포함하지 않을 수도 있습니다. – bames53

-1

이 경우 srand의 초기화는 항상 동일하므로 while의 동작은 각 실행마다 동일합니다. 임의의 데이터를 시간 내에 넣으려고하면 실행 시간의 변화를 볼 수 있습니다. 나는 우리가 "이 법률은"의 경우를 적용했다 확신 동안

+2

나는 그것을 말하고 싶지 않지만 내 정신 상태는 행동이 프로그램이 실행될 때마다 다를 것이라고 여전히 말하기에 충분합니다. 'srand'는 시드가 올라가면 한 번만 호출되기 때문에 두 번째 패스가있을 때까지 실행되는 동안 동일 할 수 있습니다. – chris

+0

실제로 srand()는 각 실행마다 다른 결과를 제공합니다. 그러나 동일한 루트 시퀀스의 난수는 동일합니다. 루프는 srand()가 0을 생성 할 때까지 실행될 것입니다. 이것은 시퀀스 난수 생성의 루트가 일정하면 while 루프가 실행되는 동안 동일하다는 것을 의미합니다. – user1929959

1

, 나는 그것이 시간의 임의의 [1] 양을 기다리는이 특정 방법을 사용하는 아주 좋은 생각 모르겠어요.

나는

int delay = constant + rand() * factor; 
usleep(delay); 

의 라인을 따라 뭔가를 사용하는 것이 훨씬 더 나은 선택이 될 것이라고 생각합니다. CPU 부하를 줄이고 정의 된 범위를 제공합니다. rand()가 처음 gazillion 호출 내에서 0을 제공한다는 보장이 없으므로 지연이 상당히 크게 달라질 수 있습니다.

[1]() 적절하게 변화하는 번호가 부여됩니다부터 srand 가정 - 잘 모르겠어요 "시간()"저를 달성하는 가장 좋은 방법입니다. 하루에 한 번 다시 초기화하면 문제가 없지만 같은 초에 여러 번 시작하는 코드가 있으면 모두 동일한 시드가됩니다.

+0

좋아요,하지만'usleep'은 C++에는 존재하지 않습니다.:) –

+0

사실입니다. 대부분의 운영체제는 비교적 짧은 시간 동안 잠들 수있는 것을 가질 것입니다. ... –

+0

POSIX에서'usleep'을 좋아합니다. 그러나 이것이 C++ 언어의 질문이라고 생각합니다. –

3

while (std::rand()); 

의 동작은 확실하게, 잘 정의이다. 즉, 컴파일러는이 루프는 결국 [인트로 그래피 (종료한다 가정 할 수 있기 때문에, 단 0

반환 어디에 어떤 상태로 내장 된 의사 랜덤 넘버 생성기의 상태를 변경하는 것을 의미한다.multithread]/24), 지연을 인식하지 못하거나 지연 후 (디버그가 무서운 컴파일러 인 경우) 프로그램에서 보이는 효과가 나타날 수 있습니다.

1

다른 답변을 추가하려면 컴파일러에서 루프가 종료된다고 가정하는 표준 절의 이유는 무한 루프가 정의되지 않도록하는 것이 아니라 컴파일러가있는 상황에서도 최적화가 수행되도록 허용하는 것입니다 루프가 종료할지 결정할 수 없습니다. 이 상황

while(rand()) f(); 

에서 예를 들어

, 컴파일러가 어느 랜드도 f는 부작용을 가지고 결정할 수있는 경우, 컴파일러는 그 랜드가됩니다 증명할 수없는 경우에도 전체 루프를 제거 할 수 결국 0을 반환합니다.

+0

왜 표준은 정의되지 않은 동작 (WRT 무한 루프)의 측면에서 말할 필요도 모르겠지만, 단순히 컴파일러가 임의의 코드 조각을 처음 관찰 할 수있는 효과가 나타날 때까지 사용하고, 무한하더라도 코드를 실행하는 데 필요한 시간은 "관찰 가능한 효과"로 간주되지 않습니다. 변수가 종료되거나 종료되지 않고 다른 부작용이없는 루프에 변수가 설정되어 있고 다른 코드가 변수를 읽거나 읽을 수없는 경우 컴파일러는 해당 변수가 아니면 그 변수가 끝날 때까지 코드 실행을 연기 할 수 있습니다 필요합니다. – supercat

+0

문제의 변수가 필요 없다는 것이 밝혀지면, 그 밖의 모든 것이 먼저 발생할 때까지 순환 루프의 실행이 연기 될 수 있습니다. 문제 없어. – supercat