2013-05-26 3 views
1

C++의 내부 및 외부 연결을 이해하기 위해 코드를 가지고 놀았습니다. 링크가있는 순서에 따라 코드가 다를 수 있습니다.C++에서 인라인 함수를 사용하는 지정되지 않은 출력


test1.cpp

#include<iostream> 
using namespace std; 
inline int c() 
{ 
    static int p=0; 
    p++; 
    return p; 
} 
void a() 
{ 
    cout<<"\nIn function a() , c = "<<c(); 
} 


test2.cpp

#include<iostream> 
using namespace std; 

inline int c() 
{ 
    static int p=12; 
    p++; 
    return p; 
} 

void b() 
{ 
     cout<<"\nIn function b() , c = "<<c(); 
} 


driver.cpp

012,351 6,
#include<iostream> 
using namespace std; 

void a(); 
void b(); 
int c(); 

int main() 
{ 
    b(); 
    a(); 
    a(); 
    b(); 
    cout<<"\nIn function main() = , c "<< c(); 
    cout<<"\n"; 
} 

출력 1 - test1.cpp 정의 상기 출력

when compiles as follows :- 

bash#>g++ -c test1.cpp 
bash#>g++ -c test2.cpp 
bash#>g++ -c driver.cpp 

bash#>g++ -o out driver.o test1.o test2.o 
bash#>./out 

In function b() , c = 1 
In function a() , c = 2 
In function a() , c = 3 
In function b() , c = 4 
IN main() , c = 5 

, 컴파일러 고려 C()

출력 2 - test1.o의 순서를 변경 및 test2.o 연결하는 동안. 상기 출력

bash#>g++ -o out driver.o test2.o test1.o 

In function b() , c = 13 
In function a() , c = 14 
In function a() , c = 15 
In function b() , c = 16 
IN main() , c = 17 

, 컴파일러 test2.cpp 정의 C()를 고려

내가되는 코드에 작은 변화를 만들 때 다음 I가 당황했다

-
1) I 만약 연결하면서 test2.cpp]

//test1.cpp changes 
void a() 
{ 
    cout<<"\nIn function a() , c = "; // not calling c() 
} 

//test2.cpp changes 
void b() 
{ 
    cout<<"\nIn function b() , c = "; // not calling c() 
} 

I가 다음 오류 얻을 funciton B의 기능 A에서 C() [test1.cpp] 및 C를()()를 호출하지 않는다 : -

bash#>g++ -o out driver.o test1.o test2.o 
driver.o: In function `main': 
driver.cpp:(.text+0x1f): undefined reference to `c()' 
collect2: ld returned 1 exit status 

2) test1.cpp 또는 test2.cpp의 파일 중 하나에서 c()를 호출하면 링커 오류가 발생합니다.

누구든지이 동작을 이해할 수 있도록 도와 주시겠습니까?

미리 감사드립니다.

+0

링커 문제를 피하려면'inline' 함수를 헤더 파일로 옮기십시오. –

답변

3

프로그램이 정의 된 규칙을 위반하여 정의되지 않은 동작을합니다. 두 개의 다른 번역 단위가 동일한 이름과 서명을 가진 함수를 정의하지만 다른 본문이 있습니다.

[...] 주어 D다음 하나 이상의 변환 부 정의라는 그러한 엔티티

: 문단 C++ 11 표준 3.2/6 당

- D의 각 정의는 동일한 토큰 시퀀스로 구성됩니다. 및

[...기능 c()test1.cpptest2.cppinline로 선언되어 있기 때문에]

은 여러분의 프로그램은 아니지만 driver.cpp에서, 잘못을 형성한다. 단락 당 7.1.2/4

외부 링크 기능은 하나 개의 변환 장치에 inline을 선언되면

는 [...], 이는 그것이 존재하는 모든 번역 단위 inline 선언한다; 진단이 필요하지 않습니다. [...]

은 "에는 진단가 필요하지 않다"비트 컴파일러 (또는 링커) 또는이 규칙의 위반 오류를보고하지 않을 수 있음을 의미한다. 그것은 당신이 그것을 깨뜨리기 위해 매우 조심해야한다는 것을 의미합니다.

+1

그리고 그는 모든 TU가'inline'으로 선언되지는 않는 인라인 함수를 가지고 있습니다. +1 –

+0

@ JohannesSchaub-litb : 나는 그것을 놓쳤다. 언급 해 주셔서 감사합니다. –

+0

편집 해 주셔서 감사합니다. 내 게시물에있는 포인트 (2)의 이유는 무엇입니까? – user1057741