2012-01-17 1 views
3

체인 된 정적 함수와 멤버 함수 사이의 인수 평가 순서에 차이가 있는지 궁금합니다. this question의 답변에서 나는 연쇄 함수 호출간에 인수 평가 순서가 무엇인지 명시하지 않는다는 것을 알 수 있습니다. 예를 들어 다음 코드 가지고 : GCC 4.6.2 및 CL 15.00.30729.01 (MSVC 9)의 경우체인 된 정적 함수 호출 간의 인수 평가 순서

#include <iostream> 
class test { 
public: 
    static test& chain_s(test& t, int i) { 
     std::cout << i << " "; 
     return t; 
    } 

    test& chain(test& t, int i) { 
     std::cout << i << " "; 
     return *this; 
    } 
}; 

int main(int, char**) { 
    int x = 2; 
    test t; 
    t.chain(t,++x).chain(t,++x).chain(t,++x); 
    x = 2; std::cout << std::endl; 
    t.chain_s(t,++x).chain_s(t,++x).chain_s(t,++x); 

    return 0; 
} 

을 결과 출력은 그러나 나

5 5 5 
3 4 5 

를 들어, 내가 경우 궁금하다 명세에 어떤 이유가 있거나 왜 정적 함수가 왼쪽에서 오른쪽으로 (인수로) 평가되는지, 그리고 비 정적 함수에 대해 모든 인수가 먼저 (오른쪽에서 왼쪽으로 다른 테스트에서 보았습니다.)

내가 구조체와 함수 포인터를 사용하여 C에서 비슷한 동작을 얻으려고 할 때 동작의 차이점을 먼저 알아 냈으므로이 점을 알아 냈습니다. 나는 이것이 회원 기능을위한 GCC와 MSVC 모두에서 구현 된 최적화라고 강력하게 의심하지만, 여기 누군가가 이것에 대해 좀 더 밝힐 수 있기를 바랍니다.

편집 :
나는 나를 홀수 파업 정보를 하나 개의 중요한 비트를 언급하는 것을 잊었다 : GCC 만 체인 비 정적 기능에 지정되지 않은 행동을 경고하지만,하지 않습니다 정적 기능 :

a.cpp: In function 'int main(int, char**)': 
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point] 

GCC는 두 번째 표현을 놓칠 수있는 경고를 제공 할 의무가 없지만 이것이 내가 흥미로운 일이 일어나고 있다고 생각하게 만듭니다.

+0

분명히 당신이 쓰는 코드에서 아무런 의미가 없어야합니다 ... –

+0

네,하지만 비슷한 코드가있는 경우 왜 어떤 코드는 오류가 있지만 경고를 내지 않는지 알고 싶습니다. – harrbharry

답변

2

이유 불필요 당신이 말했듯이, 그 명령은 그 언어에 의해 불특정합니다.

오른쪽에서 왼쪽 순서를 사용하는 한 가지 이유는 printf과 같이 가변 개수의 매개 변수가있는 함수는 항상 첫 번째 매개 변수를 맨 위에 갖게된다는 것입니다. 그렇지 않으면 상관 없습니다.

+0

컴파일러 출력 메시지가 다른 이유는 무엇입니까? 이것은 또한이 전체 질문을 이끌어 냈습니다. – harrbharry

+0

'printf'를 사용해도, 컴파일러는 인자가 원하는 순서대로 인자를 평가할 수 있고, 심지어 평가를 인터리빙 할 수도 있습니다. 스택 기반 컴퓨터에서 첫 번째 인수는 마지막으로 푸시 된 가능성이 높지만 컴파일러가 스택에 필요한 공간을 예약하고 sp 상대 주소 지정을 사용하여 각 인수를 저장하는 좋은 기회가 있습니다. 그리고 어떤 순서로든 그렇게하면 편리합니다. –

2

코드에 정의되지 않은 동작이 있지만 그 사실을 알고 계실 것입니다. 또한 최적화 플래그에 따라 쉽게 차이를 볼 수 있습니다. 그러나이 경우 일 가능성이있는 이유 중 하나는 이전 호출 결과를 포함하여 정적 함수가 두 개만 필요하며 호출의 결과는 무시된다는 점입니다.