2011-09-28 4 views
1

예 링커 오류가 발생합니다 : 코드 위왜 컴파일러가 자동으로 자유롭게 정의 된 함수를 인라인하지 않습니까? 대신

// header.h 
void foo() // function definition in the file 
{ 
} 

// file1.cpp 
#include"header.h" 
... 

// file2.cpp 
#include"header.h" 
... 

이 링커 오류가 발생합니다. 컴파일러가 inline foo()을 자동으로 만들면 링커 오류가 발생하지 않는다고 가정합니다.

제 질문은 언어 관점입니다. 왜 컴파일러가 자동으로 inline이되지 않습니까? 어떤 변화가있을 것인가?

다른 질문 : "컴파일러가 정의 된 모든 자유 함수 앞에 inline이 있다고 가정하면 어떤 문제가 발생할 수 있습니까?"

답변

6

머리글은 머리글 텍스트의 복사 붙여 넣기로 처리됩니다. 컴파일러는 소스 파일보다는 헤더에 코드가 있는지 모르기 때문에 오류를 허용하면서 코드를 모두 처리해야합니다. 언어가이를 지정합니다.

+0

모든 무료 함수 앞에 키워드'inline'을 가정하는 컴파일러는 어떻습니까? – iammilind

+5

@iammilind 그런 다음 우연히 같은 이름의 두 가지 (다른) 기능을 사용하자 마자 오류 대신 일관성없는/잘못된 동작이 발생합니다. 헤더에 정의를 넣지 말고 (어쨌든 조직을위한 좋은 방법), 포함 경비원을 추가하십시오 (헤더 당 세 줄임). – delnan

1

글쎄, 대답은 기본적으로 C++ 표준이이 방식으로 동작해야한다는 것입니다. 이 부분은 One Definition Rule의 일부입니다.

실제로 컴파일러는 실제로 다른 곳에서 사용하는 경우 링커 표시 함수를 생성해야합니다. 예를 들어, 다음과 같은 file3.cpp이 작동해야합니다

void foo(); 
void call_foo() { 
    foo(); 
} 

하고 작동하기 위해서는

foo()에 대해 생성 된 코드는 링커에 사용할 수 있어야합니다. 컴파일러는 한 번에 하나의 번역 단위 ( .cpp 파일과 그 안에 포함 된 모든 내용) 만보고 있으므로 실제로 두 번 번역 단위가 생성되었음을 알 수 없습니다. 그렇습니다. 그런 다음 링커가 그것을 잡습니다.

0

inline (단, static이 아니더라도 별도로 기능이 있어야 함)하지만 요점은 누락되었습니다.

컴파일러는 동일한 서명으로 함수를 두 번 정의했다고 봅니다. 그것들은 잠재적으로 다를 수 있습니다. 따라서 연결 단계에서 오류가 발생하여 문제가 있음을 알려줍니다.

헤더 void foo();선언을 넣어 및 CPP 파일의 하나의 기능을 구현합니다.

+0

이것은 컴파일 타임 오류가 아니며 링크 타임 오류입니다. 두 소스 파일 모두 잘 컴파일됩니다. –

+0

미안하지만, 나쁜 표현. –

1

링커 오류가 발생하지 않습니다. 은 링커 오류가 발생하지만 컴파일러는 해당 오류를 catch하지 않아도됩니다.

모듈 간 일관성은 전적으로 프로그래머의 책임입니다. C++ 컴파일러는 클래스 정의가 다른 두 개의 관련없는 파일에서 동일한 클래스 이름을 사용하고 있음을 예를 들어 볼 수 없어도됩니다. 무슨 일이든 그건 네 잘못이야.

일반적으로 C++ 컴파일 모델의 많은 이상한 약점은 한 번에 하나의 모듈 (컴파일 단위) 만보고 C++ 프로그램을 컴파일 할 수 있어야한다는 사실과 관련이 있습니다. 대규모 프로젝트의 경우 컴파일 시간과 공간이 폭발하지 않도록해야합니다.

0

링크 시간에 이 자동으로 인라인 문제가 발생합니다. C가 정의 된 방법을 고려할 때 동일한 이름을 가진 두 개의 다른 함수가있는 경우입니다. 기본 이진 인터페이스는 이러한 충돌을 해결하는 데 필요한 메타 데이터를 유지하지 않습니다. 그런 이름을 가진 함수를 사용하는 (그러나 그 자체를 정의하지는 않는) 세 번째 소스 파일을 던지면, 어떤 파일이 사용되어야할지 모른다.

거기에 몇 가지 실험용 C (또는 더 많은 C 유사) 컴파일러가있을 수 있지만 어떤면에서는 호환성을 깨뜨릴 수 있습니다.

관련 문제