itsource

GCC는 정의되지 않은 참조에 대해 불만을 제기하지 않을 수 있습니까?

mycopycode 2022. 8. 21. 19:55
반응형

GCC는 정의되지 않은 참조에 대해 불만을 제기하지 않을 수 있습니까?

어떤 상황에서 GCC가 작성된 함수를 호출하려고 할 때 "정의되지 않은 참조" 링크 오류 메시지를 보내지 않을 수 있습니까?

예를 들어 이 C코드가 GCC에 의해 컴파일 및 링크된 경우:

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

...비록...그럼에도 불구하고.made_up_function_name는 코드의 어디에도 존재하지 않습니다(헤더, 소스 파일, 선언, 서드파티 라이브러리도 아닙니다).

그런 종류의 코드는 GCC가 실제 코드를 건드리지 않고 특정 조건 하에서 받아들이고 컴파일할 수 있습니까?만약 그렇다면, 어느 쪽입니까?

고마워요.

편집:은 이전에 어떤 포고문이나 언급 편집에:이전 선언또는 언급 없음.made_up_function_name또 다른 곳에 줄 것.다른곳이라면 어디든지 존재합니다.뜻은 즉, a가grep -R전체 파일 시스템의 정확한 코드 한 줄만 표시합니다.

네, 확실하지 않은 참조 보고를 피하기 위해 어떤 예를 사용하여, 정의되지 않은 참조가 보고되지 않도록 할 수 있습니다(사용:가능하다.--unresolved-symbols링커 옵션입니다.링커 옵션

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

부터부터man ld

--resolved-paramed=프로세서

해결되지 않은 기호를 처리하는 방법을 결정합니다.method에는 다음 4가지 값이 있습니다.

       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.

공유 라이브러리의 동작은 --[no]allow-shlib-undefined 옵션으로 제어할 수도 있습니다.

일반적으로 링커는 보고된 미해결 심볼마다 오류 메시지를 생성하지만 --warn-unresolved-symbols 옵션은 이를 경고로 변경할 수 있습니다.

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() 또는 무의미한 콜을 삭제해 주세요.거기에 있는 것이 전부예요.링커 피딩은 관여하지 않습니다.

당신이 링커 깃발과 맺링커사용하여 빌드하는 경우 플래그를.-r ★★★★★★★★★★★★★★★★★」--relocatable아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.

그 이유는-r새로운 오브젝트 파일의 다른 오브젝트를 링크하여 나중에 링크합니다.

그리고 GCC에 전달된 -D 플래그를 사용한 악질도 있습니다.

$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 플래그는 컴파일 시 코드를 변경하는 강력한 도구입니다.

함수를 사용하기 전에 프로토타입을 선언하면 함수는 컴파일을 할 수 있습니다.어쨌든, 링크중의 에러는 남습니다.

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

한다면function()는 호출되지 않으며 실행 파일에 포함되지 않을 수 있으며 호출된 함수도 검색되지 않습니다.

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정의되어 있지 않습니다.

언급URL : https://stackoverflow.com/questions/5555632/can-gcc-not-complain-about-undefined-references

반응형