[c++] 루프 내에서 로컬 객체의 소멸자가 다음 반복 전에 호출되도록 보장됩니까?

루프가 있고이 루프 내부에 새 스택 변수를 만들면 (힙에 할당하지 않고 루프 본문 내부에 선언 된 변수를 유지하지 않음), 다음 반복이 시작되기 전에이 객체의 소멸자가 호출 될 수 있습니다. 컴파일러에 의해 루프 언 롤링이 그것에 대해 뭔가를 변경 하시겠습니까?



답변

보낸 사람 n4800:

6.3.3 블록 범위 :

블록 (8.3)에 선언 된 이름은 해당 블록의 로컬 이름입니다. 블록 범위가 있습니다. 잠재적 인 범위는 선언 지점 (6.3.2)에서 시작하여 블록 끝에서 끝납니다. 블록 범위에서 선언 된 변수는 로컬 변수입니다.

§10.3.6 소멸자 :

객체가 생성 된 블록이 종료되면 소멸자가 암시 적으로 […] 호출됩니다 (8.7).

§4.1.1 초록 머신 :

이 규정은“만약”규칙이라고도하며, 그 결과는 관찰 가능한 행동에서 결정될 수있는 한 , 요구 사항이 준수 된 것처럼 결과가이 문서의 요구 사항을 자유롭게 무시할 수 있기 때문 입니다. 프로그램 .

[엠파 시스 광산]

예. 변수는 루프의 끝 (블록)에서 범위를 벗어나므로 프로그램의 동작을 관찰하는 사람이 말할 수 있는 한 소멸자가 호출 됩니다 .


답변

예. 변수를 선언하는 “블록”을 고려할 때 (예 : 괄호 쌍 사이) 시각화하기가 더 쉽습니다. 루프 자체는 블록이며 다음 반복 전에 닫기 브래킷에 도달하면 루프에 선언 된 자동 저장 변수의 모든 소멸자가 호출됩니다.

컴파일러에 의한 루프 언 롤링이 그것에 대해 무언가를 바꿀 수 있습니까?

일반적으로 컴파일러는 최적화하는 작업에 관계없이 프로그램의 동작을 보장해야하기 때문에 컴파일러가 최적화 할 대상을 생각하지 않습니다. 이 경우 루프 언 롤링은 이러한 효과가 발생하더라도 아무 것도 변경하지 않습니다.


답변

소멸자는 모든 반복마다 호출됩니다. 따라서 어떤 경우 에는 루프 대신 루프 외부 에서 변수를 선언하는 것이 더 빠릅니다 . 다음과 같은 경우를 가정하십시오.

std::string temp;
for(int i = 0; i < 10; ++i){
    temp = arr[i];
    doSomething(temp);
}

루프를 사용할 때 소멸자가 호출되지 않습니다. 그냥 무시 temp합니다.

그러나 std::string temp = arr[i]생성자 를 사용 하면 각 반복마다 소멸자가 호출됩니다. 루프가 매우 자주 실행되는 경우 비트 런타임이 추가된다고 생각합니다.


답변

소멸자는 다음 반복 전에 호출됩니다.


답변

물론 dtor는 반복이 끝날 때 호출되며 루프 언 롤링은 의미가 의심스러운 객체 생성을 제거 할 수있는 일종의 RVO 등을 제외하고 다른 최적화 (프로그램 최적화는 프로그램 동작을 수정해서는 안 됨)와 같이이 동작을 수정해서는 안됩니다. .


답변