2012-01-03 3 views
-1

코드가 있습니다.이 코드가 컴파일되는 이유는 무엇입니까?

class A 
{ 
public: 
    int foo(int i) 
    { 
     return i; 
    } 
}; 

int foo(int i) 
{ 
    return i; 
} 

int (A::*ptrFoo)(int) = NULL; 
int (*_foo)(int) = NULL; 

int main() 
{ 
    ptrFoo = &A::foo; 
    _foo = foo; 

    (*_foo)++++++++++++++(10); //This dont compile... 

    A a; 
    (a.*ptrFoo)+++++++++++++++++(10); //This compiles ???? 

} 

무엇이 있는지 알려주세요. 정의되지 않은 행동 또는 무엇 ??? 나는 VS2008에서 그것을 컴파일했습니다. 이상하게도 코드의 마지막 줄이 성공적으로 컴파일됩니다.

+2

'+++++++++++++++ '는 7 개의 후행 증가 연산자입니다. 아마도 컴파일러는 절반에 휩싸 일 것입니다. –

+0

C 및 C++ 모두로 컴파일하셨습니까? 또는 두 태그를 모두 포함시킨 이유는 무엇입니까? –

+0

나는 그것을 C++ (VS2008)에서 컴파일했다. "C"태그를 제거 할 것이다. – YAHOOOOO

답변

2

두 표현식 모두 컴파일해야합니다. C++에서는 함수 나 멤버 함수 또는 함수 유형이나 멤버 함수에 대한 포인터에 대해 산술 연산을 수행 할 수 없습니다. 프로그램의 두 표현식은 각각 함수와 멤버 함수에서 산술 연산을 수행합니다.

컴파일러가 두 번째 표현식을 허용하면 컴파일러의 버그로 인한 것입니다.

1

먼저 에 대한 포인터는에 대한 포인터와 과 다릅니다.

첫 번째 예는 일반적인 기능을 가리키는 포인터입니다. 함수의 실제 메모리 주소를 포함합니다. 역 참조 할 때 ((*_foo)) 함수 자체를 얻고 함수 (함수 포인터)에 ++을 비롯한 산술 연산은 의미가 없습니다.

두 번째 이야기는 클래스의 멤버 함수에 대한 포인터가 함수의 주소를 메모리에 가지고 있지 않습니다. 실제로 컴파일러가 멤버 함수를 관리하는 방법은 구현에 따라 다릅니다. 멤버 함수에 대한 포인터는 일부 주소 또는 일부 컴파일러 관련 정보를 포함 할 수 있습니다. 이 유형의 산술도 의미가 없습니다.

그러므로 우리는 (a.*ptrFoo)의 가치가 무엇인지 모르지만, 귀하의 경우 MSVC2008은 버그 또는 디자인으로 인해 컴파일러를 관리합니다.

그런데 GCC는 두 명령문 중 하나를 컴파일하지 않으며 두 명령문 모두에 오류를 던졌습니다.

위의 내용은 + 또는 홀수의 짝수를 넣었는지 여부에 관계없이 적용됩니다. 우리는 어쨌든 산술을하고 있습니다. (+의 홀수 인 경우 함수 호출이 없습니다. 두 번째 예제에서 함수를 8 번 증분 한 다음 마지막 남은 숫자는 +이므로 결과에 10이 추가됩니다. 함수/멤버 함수 포인터를 변경하려고합니다.)

+0

"컴파일러가 멤버 함수를 관리하는 방법은 구현에 따라 다릅니다."비 멤버 함수의 구현 또한 구현 세부 사항입니다. –

+0

@JamesMcNellis : 네 말이 맞아.하지만 모든 일반 함수는 메모리에 명시 적 주소를 가지고 있지? 그러나 멤버 함수의 '주소'는 우리가 아는 것이 아닙니다. 각 컴파일러에는 클래스 구현에 대한 자체 패러다임이 있습니다. – Hossein

관련 문제