루프가 있고이 루프 내부에 새 스택 변수를 만들면 (힙에 할당하지 않고 루프 본문 내부에 선언 된 변수를 유지하지 않음), 다음 반복이 시작되기 전에이 객체의 소멸자가 호출 될 수 있습니다. 컴파일러에 의해 루프 언 롤링이 그것에 대해 뭔가를 변경 하시겠습니까?
루프가 있고이 루프 내부에 새 스택 변수를 만들면 (힙에 할당하지 않고 루프 본문 내부에 선언 된 변수를 유지하지 않음), 다음 반복이 시작되기 전에이 객체의 소멸자가 호출 될 수 있습니다. 컴파일러에 의해 루프 언 롤링이 그것에 대해 뭔가를 변경 하시겠습니까?
답변:
보낸 사람 n4800
:
6.3.3 블록 범위 :
블록 (8.3)에 선언 된 이름은 해당 블록의 로컬 이름입니다. 블록 범위가 있습니다. 잠재적 인 범위는 선언 지점 (6.3.2)에서 시작하여 블록 끝에서 끝납니다. 블록 범위에서 선언 된 변수는 로컬 변수입니다.
§10.3.6 소멸자 :
객체가 생성 된 블록이 종료되면 소멸자가 암시 적으로 [...] 호출됩니다 (8.7).
§4.1.1 초록 머신 :
이 규정은“만약”규칙이라고도하며, 그 결과는 관찰 가능한 행동에서 결정될 수있는 한 , 요구 사항이 준수 된 것처럼 결과가이 문서의 요구 사항을 자유롭게 무시할 수 있기 때문 입니다. 프로그램 .
[엠파 시스 광산]
예. 변수는 루프의 끝 (블록)에서 범위를 벗어나므로 프로그램의 동작을 관찰하는 사람이 말할 수 있는 한 소멸자가 호출 됩니다 .
call
. 또는 그들이 (있는 그대로) 아무 것도 효과적으로하지 않으면, 그러한 소멸자를위한 어셈블리가 없을 수도 있습니다.
예. 변수를 선언하는 "블록"을 고려할 때 (예 : 괄호 쌍 사이) 시각화하기가 더 쉽습니다. 루프 자체는 블록이며 다음 반복 전에 닫기 브래킷에 도달하면 루프에 선언 된 자동 저장 변수의 모든 소멸자가 호출됩니다.
컴파일러에 의한 루프 언 롤링이 그것에 대해 무언가를 바꿀 수 있습니까?
일반적으로 컴파일러는 최적화하는 작업에 관계없이 프로그램의 동작을 보장해야하기 때문에 컴파일러가 최적화 할 대상을 생각하지 않습니다. 이 경우 루프 언 롤링은 이러한 효과가 발생하더라도 아무 것도 변경하지 않습니다.
[class.copy.elision]
for(...) X x{};
및 x
개체 +는 각각의 반복에서 파괴 구축 할 것입니다. 라이브 데모 . 관련 표준 섹션은 stmt.iter / 2 입니다.
[stmt.iter]
이 (강조 광산) 순수 등가의 "반복 문에서 하위 문 단일 문장이 아닌 화합물 문 경우 가 함유 화합물 문으로 재기록 된 것과 같다 원래 진술. ". 본질적으로 하나의 문장에 중괄호가 있거나없는 것은 정확히 동일한 것을 의미하며 중괄호는 암시 적입니다. 명확성을 위해 생략했습니다.
소멸자는 모든 반복마다 호출됩니다. 따라서 어떤 경우 에는 루프 대신 루프 외부 에서 변수를 선언하는 것이 더 빠릅니다 . 다음과 같은 경우를 가정하십시오.
std::string temp;
for(int i = 0; i < 10; ++i){
temp = arr[i];
doSomething(temp);
}
루프를 사용할 때 소멸자가 호출되지 않습니다. 그냥 무시 temp
합니다.
그러나 std::string temp = arr[i]
생성자 를 사용 하면 각 반복마다 소멸자가 호출됩니다. 루프가 매우 자주 실행되는 경우 비트 런타임이 추가된다고 생각합니다.
물론 dtor는 반복이 끝날 때 호출되며 루프 언 롤링은 의미가 의심스러운 객체 생성을 제거 할 수있는 일종의 RVO 등을 제외하고 다른 최적화 (프로그램 최적화는 프로그램 동작을 수정해서는 안 됨)와 같이이 동작을 수정해서는 안됩니다. .