2011-04-20 3 views
2
#include "stdio.h" 

class C { 
public: 
    ~C() { printf("~C\n"); } 
}; 

int I(const C& c) { printf("I\n"); return 0; } 
void V(int i) { printf("V\n"); } 

int main() { 
    V(I(C())); 
    return 0; 
} 

출력 신 :개체 수명과 관련하여 정의되지 않은 동작이 실행됩니까?

내가 기대 한 것이 무엇
I 
V 
~C 

:

I 
~C 
V 
+0

왜 그렇게 생각하십니까? I()가 const C &를 반환하면 어떻게됩니까? 임시의 수명은 최소한 그것이 포함 된 표현의 지속 시간이어야합니다. – mcmcc

+0

@mcmcc :'C()'가 내장 된 표현식은'I (C())'입니다. 전체 행은 표현식 * 문 *입니다. – BCS

+0

업데이트 된 답변보기 이제 완전히 맞습니다. – Nawaz

답변

4
V(I(C())); 

C() 전체 식 완료까지 지속되는 일시를 생성하고, 전체 식의 완료 (즉 세미콜론) ;이다. 그래서 제 생각에 출력물이 잘 정의되어 있다는 것을 알 수 있습니다. 표준에서 제 §12.2/3 판독

,

[...] 임시 개체 전체 식 (1.9) 평가의 마지막 단계에서 파괴 즉 (어휘)가 포함되어있다 그들이 만들어진 지점. 예외가 throw 될 때 평가가 끝난 경우에도 마찬가지입니다.

그냥이 예에서는 임시의 수명이 기능 I()참조 또는 const를 참조 매개 변수와는 아무 상관이 없습니다 강조합니다. I()의 서명이 경우에도 :

int I(C c); //instead of : int I(const C & c); 

임시은 전체 식의 완료까지 지속될 것입니다 그리고 당신은 정확히 같은 출력을 볼 것입니다. 전체 표현 전에 V 반환에 대한 호출이 완전히 평가 된 http://www.ideone.com/RYWhy

1

이유는 무엇입니까? 임시적인 삶은 완전한 표현이 끝날 때까지 계속된다.

+0

직접 포함 식만 평가 한 후 임시를 법적으로 삭제할 수있는 경우 해당 스택 공간을 사용하여 나머지 식을 계산할 수 있습니다. 표현 평가에 대한 역사적으로 느슨한 규칙이 주어지면 합리적인 것처럼 보입니다. – BCS

1

표시되는 동작은 표준에서 요구하는 동작입니다. 임시 개체는 전체 식 끝에 만들어집니다.

이전에는 또 다른 동작이 발생했으며 일부 컴파일러에서는 여전히 사용할 수 있습니다. 블록의 끝에있는 파괴. 귀하의 경우에는 파멸을 더 지연시키기 때문에 차이가 없었을 것입니다.

3

:

이를 참조하십시오. 그리고 V이 반환되면, 물건을 인쇄 할 것입니다 (V에서 돌아 오기 전에 시퀀스 포인트가 있습니다).

임시 C()은 완전한 전체 표현식을 평가 한 후에 만 ​​파기됩니다.

+0

사실, 임시의 수명은 직접 둘러싸는 표현식 (이 경우'I (C))')이 아닌 모든 둘러싼 표현식의 범위입니다. – BCS

+0

@BCS : 예. 내 게시물과 표준의 인용문을보십시오. :-) – Nawaz

+0

@ Nawaz 당신의 대답에 따르면 평생은 전체 표현의 끝까지 길다는 말은 참조에 묶여 있기 때문입니다. 그러나 실제로는 참조와 관련이 없습니다. 임시는 모든 참조와 관계없이 완전한 표현이 끝날 때까지 생깁니다. –