문제

일부 매크로 서브 루틴을 인라인 함수로 대체하여 컴파일러가 최적화 할 수 있도록하여 디버거가 그 안에 들어갈 수 있도록합니다. 정상 함수로 정의하면 작동합니다. 라코 디스

하지만 인라인으로 정의하면 : 라코 디스

'오류 : 정의되지 않은 외부'라고 표시됩니다.그게 무슨 뜻입니까?어둠 속에서 찌르고 시도했습니다 라코 디스

더 이상 오류가 없습니다.함수 정의 및 함수 호출은 동일한 .c 파일에 있습니다.

누군가 하나는 작동하고 다른 하나는 작동하지 않는 이유를 설명 할 수 있습니까?

(두 번째 관련 질문 : 둘 이상의 .c 파일에서 사용하려면 인라인 함수를 어디에 두어야합니까?)

도움이 되었습니까?

해결책

첫째, 컴파일러는 항상 inline로 표시된 함수를 인라인하지 않습니다. 예를 들어 모든 최적화를 끄면 인라인되지 않을 것입니다.

인라인 함수를 정의 할 때 라코 디스

그 함수를 사용합니다. 동일한 파일에서도 해당 함수에 대한 호출은 컴파일러가 아닌 링커에 의해 해결됩니다. 이는 암시 적으로 "extern"이기 때문입니다. 그러나이 정의만으로는 함수의 외부 정의를 제공하지 않습니다.

inline없이 선언을 포함하는 경우 라코 디스

inline 정의를 볼 수있는 C 파일에서 컴파일러는 함수의 외부 정의를 제공하므로 오류가 사라집니다.

static inline가 작동하는 이유는 해당 컴파일 단위 내에서만 함수를 표시하고 컴파일러가 함수 호출을 확인 (및 최적화)하고 해당 컴파일 단위 내의 함수에 대한 코드를 내보낼 수 있도록하기 때문입니다. 링커는이를 해결할 필요가 없으므로 외부 정의가 필요하지 않습니다.

인라인 함수를 넣는 가장 좋은 위치는 헤더 파일에 있으며 static inline를 선언하는 것입니다. 이렇게하면 외부 정의가 필요하지 않으므로 링커 문제가 해결됩니다. 그러나 이로 인해 컴파일러는 함수를 사용하는 모든 컴파일 단위에서 함수에 대한 코드를 내보내므로 코드가 부 풀릴 수 있습니다. 그러나 함수가 인라인이므로 어쨌든 작을 수 있으므로 일반적으로 문제가되지 않습니다.

다른 옵션은 헤더의 extern inline 정의 하는 것이며, 하나의 C 파일에서 extern 수정 자없이 declaration 을 제공하고 inline를 제공합니다.

gcc 매뉴얼에 다음과 같이 설명되어 있습니다. <인용구>

함수를 인라인으로 선언하면 GCC가 그 기능이 더 빠릅니다. GCC가이를 달성 할 수있는 한 가지 방법은 해당 함수의 코드를 호출자를위한 코드에 추가합니다. 이것은 만든다 함수 호출 오버 헤드를 제거하여 실행 속도를 높입니다. 에 또한 실제 인수 값이 상수 인 경우 알려진 값은 컴파일 타임에 단순화를 허용하여 모든 인라인 함수의 코드가 포함되어야합니다. 에 대한 효과 코드 크기는 예측하기 어렵습니다. 개체 코드는 더 크거나 작을 수 있습니다. 특정 경우에 따라 함수 인라인을 사용합니다. 당신은 할 수 있습니다 또한 GCC에게 "충분히 간단한"기능을 모두 통합하도록 지시합니다. -finline-functions 옵션이있는 호출자

GCC는 함수 선언의 세 가지 다른 의미를 구현합니다. 인라인. 하나는 -std=gnu89 또는 -fgnu89-inline 또는 모든 인라인 선언에 gnu_inline 속성이있는 경우 다른 경우 -std=c99, -std=c1x, -std=gnu99 또는 -std=gnu1x (-fgnu89-inline없이) 세 번째는 C ++를 컴파일 할 때 사용됩니다.

함수를 인라인으로 선언하려면 해당 다음과 같이 선언 : 라코 디스

ISO C90 프로그램에 포함될 헤더 파일을 작성하는 경우 inline 대신 __inline__를 작성하세요.

세 가지 유형의 인라인은 다음 두 가지 중요한 경우에서 유사하게 작동합니다. inline 키워드가 다음과 같이 inline 함수에 사용되는 경우 위의 예와 함수가 처음 선언 된 경우 static 키워드는 다음과 같이 inline로 정의됩니다. 라코 디스

이 두 가지 일반적인 경우에 프로그램은 속도를 제외하고는 inline 키워드를 사용하지 않았습니다.

함수가 인라인 및 유전자 태그 코드 인 경우 함수는 호출자에 통합되고 함수의 주소는 사용하지 않은 경우 함수 자체는 다음과 같습니다.

sembler 코드는 결코 참조. 이 경우 GCC는 실제로 어셈블러 코드를 출력하지 않습니다. 옵션을 지정하지 않는 한 inline. 일부 통화는 다양한 이유 (특히 함수의 정의에 선행하는 호출 통합 할 수 없으며 둘 다 내부에서 재귀 호출을 할 수 없습니다. 정의). 통합되지 않은 호출이있는 경우 함수는 다음과 같습니다. 평소와 같이 어셈블러 코드로 컴파일됩니다. 함수는 또한 프로그램이 주소를 참조하면 평소와 같이 컴파일됩니다. 인라인 될 수 없습니다.

함수 정의의 특정 용도는 인라인 대체에는 적합하지 않습니다. 이러한 용도는 다음과 같습니다. varargs, alloca 사용, 가변 크기 데이터 유형 사용, 계산 된 goto 사용, 로컬이 아닌 goto 및 중첩 함수 사용. static를 사용하면 -fkeep-inline-functions로 표시된 함수가 다음을 수행 할 수 없을 때 경고합니다. 대체되고 실패 이유를 알려줍니다.

ISO C ++에서 요구하는대로 GCC는 그렇지 않은 경우에도 인라인으로 표시 할 클래스의 본문 -Winline 키워드로 명시 적으로 선언되었습니다. 이것을 재정의 할 수 있습니다. inline로.

GCC는 최적화하지 않을 때 어떤 함수도 인라인하지 않습니다. 다음과 같이 함수에 대한 inline 속성을 지정하십시오. 라코 디스

이 섹션의 나머지 부분은 GNU C90 인라인에 한정됩니다.

인라인 함수가 -fno-default-inline가 아닌 경우 컴파일러는 다른 소스 파일에서 호출이있을 수 있다고 가정합니다. 글로벌 이후 기호는 모든 프로그램에서 한 번만 정의 할 수 있습니다. 다른 소스 파일에 정의되어 있으므로 그 안의 호출은 통합. 따라서 non-always_inline 인라인 함수는 항상 일반적인 방식으로 자체적으로 컴파일됩니다.

함수 정의에 staticstatic를 모두 지정하면 그런 다음 정의는 인라인에만 사용됩니다. 어떤 경우에도 주소를 참조하더라도 자체적으로 컴파일 된 함수 명시 적으로. 이러한 주소는 마치 귀하가 함수를 선언하고 정의하지 않았습니다.

이 유전자 코디 세 태그 코드와 유전자 라 코디 세 태그 코드의 조합은 거의 다음과 같은 효과가 있습니다. 매크로. 그것을 사용하는 방법은 헤더에 함수 정의를 넣는 것입니다 이 키워드로 파일을 만들고 정의의 다른 사본을 넣으십시오. (inlineextern가 없음) 라이브러리 파일에 있습니다. 정의 헤더 파일은 함수에 대한 대부분의 호출이 인라인되도록합니다. 기능의 사용이 남아있는 경우 단일 사본을 참조합니다. 도서관에서.

다른 팁

inline 함수가 C99에서 작동하려면 (언어로만 제공됨) 헤더 파일에 정의를 제공해야합니다. 라코 디스

그리고 하나 컴파일 단위 (일명 .c)에 일종의 "인스턴스화"를 배치합니다. 라코 디스

inline없이

여러 파일에서 사용하려면 헤더 파일에 넣어야합니다.

그리고 링커 오류의 경우 : 함수의 기본 선언은 함수가 "extern"임을 의미하지만 인라인되므로 링커가 컴파일러 생성 기호 스텁을 찾을 수 있으므로 오류가 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top