다음 동작의 근본 원인을 이해하는 데 도움을주십시오. 파일 a.cpp
에서인라인 함수 정의가 다른 함수 객체의 인스턴스화는 연결 순서에 따라 다릅니다.
내가 가진 : 파일 b.cpp
에서
namespace NS {
struct Obj {
void pong(){ cout << "X in "__FILE__ << endl; }
double k;
};
X::X() { Obj obj; obj.pong(); }
void X::operator()() { cout << "X says hello" << endl; }
}
내가 가진 :
namespace NS {
struct Obj {
void pong(){ cout << "Y in "__FILE__ << endl; }
bool m;
};
Y::Y() { Obj obj; obj.pong(); }
void Y::operator()() { cout << "Y says hello" << endl; }
}
내 main
는 X, y를을 만들고 자신의 연산자()의 호출
int main(int argc, char *argv[])
{
NS::X x;
x();
NS::Y y;
y();
return 0;
}
을
이 프로그램의 출력은,210 또는 b.cpp
먼저 컴파일 얻는다 : 첫 번째 경우에서 a.cpp
Obj
는 b.cpp
에서 Obj
가 NS::X
및 NS::Y
모두 인스턴스화 제 경우 NS::Y
의 생성자 내에 인스턴스화되어있다.
% g++ b.cpp a.cpp main.cpp
% ./a.out
X in a.cpp
X says hello
Y in b.cpp
Y says hello
% g++ b.cpp a.cpp main.cpp
% ./a.out
Y in b.cpp
X says hello
Y in b.cpp
Y says hello
Linux 또는 Visual Studio (2005)에서 경고 메시지가 표시되지 않습니다. 내가 구조체의 선언 외부에 Obj::pong()
을 정의하면 Obj :: pong 함수가 여러 번 정의되었다는 링커 오류가 발생합니다.
제가 조금 더 실험했는데, 원인이 인라인 여부와 관련이 있어야한다는 것을 알게되었습니다. 왜냐하면 -O3으로 컴파일하면 각 객체가 자신의 번역 단위에서 Obj를 사용하기 때문입니다.
그런 다음 질문이 변경됩니다. 최적화되지 않은 컴파일 중에 인라인 함수의 두 번째 정의는 어떻게됩니까? 그들은 조용히 무시 당하고 있습니까?
감사합니다. 상황을 해결하는 방법을 알고 있었지만, 컴파일러가 그런 상황에서하는 일에 관심이 있습니다. –
@andreas buykx, 컴파일러는 하나의 정의를 제외하고 모두 버립니다. 더 이상 말할 수있는 것이 확실하지 않습니다. 특히 관심이있는 것은 무엇입니까? –
컴파일러는 각 cpp 파일과 별도로 작동하기 때문에이 결정을 내리는 컴파일러가 될 수 없습니다. 링커는 사용할 구현을 결정하고, 분명히 첫 번째를 선택합니다. –