2010-06-23 5 views
3

최근 내 프로젝트에서 문제가 발생했습니다. 필자는 보통 gcc-4에서 컴파일하지만 gcc-3에서 컴파일을 시도한 후에 인라인 함수의 다른 처리를 발견했습니다. 이를 설명하기 위해 나는 간단한 예제를 만들었습니다gcc - 2 버전, 인라인 함수의 다른 처리

을 main.c :

#include "header.h" 
#include <stdio.h> 

int main() 
{ 
    printf("f() %i\n", f()); 
    return 0; 
} 

file.c 이것은

#include "header.h" 
int some_function() 
{ 
    return f(); 
} 

header.h가 나는 컴파일

inline int f() 
{ 
    return 2; 
} 

gcc-3.4.6의 코드는 다음과 같습니다.

gcc main.c file.c -std=c99 -O2 

-O2 플래그를 제거하면 링커 오류 (f의 다중 정의)가 발생합니다. 나는 컴파일러가 원하지 않는다면 컴파일러가 인라인 할 필요가 없다는 것을 안다. 그래서 나는 main.cfile.c의 경우 다중 인라인 정의 오류가 발생했을 때 인라이닝 대신 객체 파일에 f를 배치했다고 가정했다. 분명히 f을 정적으로 만든 다음 최악의 경우에는 이진 파일에 f을 넣음으로써이 문제를 해결할 수 있습니다.

하지만 함께 GCC-4.3.5이 코드를 컴파일 시도 : 바이너리에 어떤 기능 f

gcc main.c file.c -std=c99 -O2 

그리고 모든 것이 잘 작동, 그래서 나는 새로운 GCC는 두 경우 모두 f을 인라인 가정하고 있었다 전혀 (gdb에서 확인하고 나는 옳았다).

그러나 -O2 플래그를 제거하면 int f()에 대한 정의되지 않은 참조가 2 개 있습니다. 그리고 여기서, 나는 정말로 무슨 일이 일어나고 있는지 이해하지 못합니다. gcc가 f이 인라인 될 것으로 가정 했으므로 오브젝트 파일에 추가하지 않았지만 나중에 (-O2이 없었기 때문에) 인라인 대신 이러한 함수에 대한 호출을 생성하기로 결정했기 때문에 링커 오류가 발생했습니다 .

이제 컴파일러에서 문제없이 두려워하지 않고 프로젝트 전체에서 사용할 수 있도록 인라인으로 원하는 단순하고 작은 함수를 어떻게 정의하고 선언해야합니까? 그리고 그들 모두를 정적으로 만드는 것이 옳은 일입니까? 또는 gcc-4가 손상되어 정적이 아닌 한 몇 가지 번역 단위로 인라인 함수를 여러 번 정의해서는 안됩니다.

답변

5

예, 동작이 gcc-4.3 이상에서 변경되었습니다. gcc 인라인 문서 (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html)에 자세한 내용이 나와 있습니다.

짧은 이야기 : 일반 인라인은 gcc (이전 버전의 어쨌든)가 동일한 파일 범위에서 인라인을 호출하는 것뿐입니다. 그러나 그것은 gcc에게 파일 범위의 모든 호출자가 이라고 알려주지 않으므로 gcc는 인 f()의 링크 가능 버전을 유지합니다. 위의 중복 된 심볼 오류를 설명합니다.

Gcc 4.3에서는이 동작을 c99와 호환되도록 변경했습니다.

그리고는, 특정 질문에 답 :

지금 질문에 온다 : 그들은없이 프로젝트 전반에 걸쳐 사용할 수 있도록 어떻게 정의하고 내가 인라인을 원하는 간단하고 작은 기능을 선언해야 다양한 컴파일러에서의 문제에 대한 두려움? 그리고 그들 모두를 정적으로 만드는 것이 옳은 일입니까? 또는 gcc-4가 손상되어 정적이 아닌 한 몇 가지 번역 단위로 인라인 함수를 여러 번 정의해서는 안됩니다.

gcc 버전간에 이식성을 원할 경우 정적 인라인을 사용하십시오.

+0

감사합니다. –

관련 문제