2011-04-05 2 views
39

GCC가 이 아닌 경우이 "정의되지 않은 참조"링크를 만들 때 오류 메시지를 보냈습니까?GCC는 정의되지 않은 참조에 대해 불평하지 않을 수 있습니까?

예를 들어,이 C 코드를 GCC에 의해 컴파일 및 링크 된 상황 : 심지어 made_up_function_name 불구하고 ...

void function() 
{ 
    made_up_function_name(); 
    return; 
} 

는 코드에서 어디 (안 헤더, 소스 파일이 존재하지 않습니다 선언, 또는 제 3 자 라이브러리).

실제 코드를 건드리지 않고도 특정 조건에서 GCC가 승인하고 컴파일 할 수 있습니까? 그렇다면 어느 것입니까?

감사합니다.

EDIT : made_up_function_name에 대한 이전 선언이나 언급이 그 밖의 다른 곳에 존재하지 않습니다. 전체 파일 시스템 중 grep -R인 경우에만이 코드의 정확한 단일 행을 표시한다는 것을 의미합니다.

+0

C++을 컴파일하지 않는 한 C++을 컴파일 할 수 있습니다. 너는 무엇을 성취하려고 노력하고 있니? –

+0

나는 아무것도하려고하지 않고있다. 벌써 일어나고 있으며, 그것이 가능한 이유를 알고 싶다. made_up_function_name은 실제로 "-g"를 사용하고 텍스트 편집기로 파일을 편집하면 링크 된 최종 바이너리에 있습니다. – STenyaK

+1

이유는 다음을 참조하십시오. http://stackoverflow.com/questions/4914589/c-prototype-functions/4914683, http://stackoverflow.com/questions/4800102/not-including-stdlib-h-does-not - 생성 - 모든 - 컴파일러 오류/4800138 # 4800138, 그리고 아마도 꽤 더 있습니다. –

답변

68

그래, --unresolved-symbols 링커 옵션을 사용하여 정의되지 않은 참조를보고하는 것을 피할 수 있습니다.

g++ mm.cpp -Wl,--unresolved-symbols=ignore-in-object-files 

man ld 가입일

--unresolved - 심볼 = 방법

미해결 된 심볼들을 처리하는 방법을 결정한다. - [아니 -] - 수 shlib-정의되지 않은 옵션

 ignore-all 
      Do not report any unresolved symbols. 

     report-all 
      Report all unresolved symbols. This is the default. 

     ignore-in-object-files 
      Report unresolved symbols that are contained in shared 
      libraries, but ignore them if they come from regular object 
      files. 

     ignore-in-shared-libs 
      Report unresolved symbols that come from regular object 
      files, but ignore them if they come from shared libraries. This 
      can be useful when creating a dynamic binary and it is known 
      that all the shared libraries that it should be referencing 
      are included on the linker's command line. 

자신의 공유 라이브러리에 대한 동작은 또한에 의해 제어 될 수 있습니다 방법에 대한 네 수있는 값이 있습니다.

일반적으로 링커는 각각 보고 된 미해결 기호에 대해 오류 메시지를 생성하지만 --warn-unresolved-symbols 옵션은 경고로 바꿀 수 있습니다.

3

함수를 사용하기 전에 프로토 타입을 선언하면 컴파일됩니다. 어쨌든 링크하는 동안 오류가 남아 있습니다. function()가 호출되지 않은 경우

void made_up_function_name(); 
void function() 
{ 
    made_up_function_name(); 
    return; 
} 
+0

이것을 반영하기 위해 편집 된 질문 : 예제에 표시된 통화 회선 이외의 다른 기능에 대해서는 언급하지 않았습니다. – STenyaK

1

, 그것은 실행 파일에 포함되지 않을 수 있습니다, 그리고 그것에서 호출 한 함수 중 하나를 검색하지 않습니다.

+0

그래서 프로토 타입을 선언하지 않고도 컴파일 할 수 있습니다. 적어도 프로토 타입을 선언해야한다고 생각합니다. 그렇지 않으면 구문 분석 오류가 발생합니다. 맞습니까? – Heisenbug

+0

@ 0verbose - 사용하는 C 표준에 따라 다릅니다. 원래 프로토 타입은 필요하지 않았습니다. 그리고 나중에 int가 아닌 매개 변수 유형이있는 경우에만. –

0

그리고 나서 GCC에 전달 된 -D 플래그와 함께이 nastiness가 있습니다.

$cat undefined.c 
void function() 
{ 
    made_up_function_name(); 
    return; 
} 


int main(){ 
} 

$gcc undefined.c -Dmade_up_function_name=atexit 
$ 

그냥 아직 아무 표시없는 코드에서 "일을"made_up_function_name-의 정의를 찾고 상상한다. 코드에서이 정확한 작업을 수행 할 좋은 이유를 생각할 수 없습니다.

-D 플래그는 컴파일 타임에 코드를 변경하기위한 강력한 도구입니다.

+0

'-D' 플래그는 * compile * 시간에 코드를 변경합니다. 그러면 링크 할 때'-Wl, -wrap'과 같은 것들이 있습니다. –

+0

그리고'-D'와 전처리 토큰 병합을 결합하면'make_up_function_name' 텍스트는 어떤 makefile이나 빌드 스크립트에서도 마찬가지 일 필요는 없습니다. –

2

TL; DR 불평 할 수는 없지만가 원하지 않는 . 링커가 문제를 무시하도록 강요하면 코드가 충돌합니다. 그것은 역효과가 될 것입니다.

이 코드는 고대 C (C99 이전) 함수가 사용 지점에서 암시 적으로 선언되도록 허용합니다. 코드는 다음 코드와의미와 같습니다 :

void function() 
{ 
    int made_up_function_name(...); // The implicit declaration 

    made_up_function_name(); // Call the function 
    return; 
} 

링커는 정당 컴파일 된 function()이 들어있는 오브젝트 파일이 다른 곳에서는 찾을 수 없습니다 상징을 의미 불평. made_up_function_name()으로 수정하거나 무의미한 전화을 제공하여 해결해야합니다. 그게 전부입니다. 링커 - 바이올린 관련 없음.

0

POSIX 링커가 작동하는 "표준"알고리즘은 코드가 오류없이 컴파일되고 링크 될 가능성을 열어 둡니다. 자세한 내용은 여기를 참조하십시오. https://stackoverflow.com/a/11894098/187690

function (f.o이라고합시다) 파일을 포함하는 개체 파일을 라이브러리에 저장해야합니다. 그 라이브러리는 컴파일러 (및/또는 링커)의 명령 행에 언급되어야하지만, 그 순간에는 function 또는 f.o에있는 다른 함수를 호출하면 안된다. 이러한 상황에서 링커는 라이브러리에서 f.o을 검색 할 이유가 없습니다. 링커는 f.o을 완전히 무시하고 function을 완전히 무시하므로 made_up_function_name을 완전히 무시합니다. made_up_function_name이 정의되지 않은 경우에도 코드가 컴파일됩니다.

1

링커 플래그 -r 또는 --relocatable으로 빌드하면 "정의되지 않은 참조"링크 오류 메시지가 생성되지 않습니다.

이것은 -r이 새로운 개체 파일에 다른 개체를 연결하여 나중에 연결하기 때문입니다.

관련 문제