표준 (ISO / IEC 9899 : 1999) 자체에서 :
부록 J.2 정의되지 않은 동작
- ...
- 외부 연결이있는
inline
함수 는 함수 지정자로 선언 되지만 동일한 변환 단위 (6.7.4)에서도 정의되지 않습니다.
- ...
C99위원회는 근거를 작성했으며 다음 과 같이 말합니다.
6.7.4 함수 지정자
C99의 새로운 기능 :inline
C ++에서 채택 된 키워드 는 함수 선언에서만 사용할 수 있는 함수 지정자 입니다. 호출 사이트에서 볼 수있는 함수 정의가 필요한 프로그램 최적화에 유용합니다. (표준은 이러한 최적화의 특성을 지정하지 않습니다.)
함수에 내부 연결이 있거나 외부 연결이 있고 호출이 외부 정의와 동일한 변환 단위에있는 경우 가시성이 보장됩니다. 이러한 경우 inline
함수의 선언 또는 정의에 키워드 가 존재하는 것은
해당 함수의 호출이 inline
키워드 없이 선언 된 다른 함수의 호출보다 우선적으로 최적화되어야한다는 기본 설정을 나타내는 것 이상의 효과가 없습니다 .
가시성은 호출이 함수의 정의와 다른 변환 단위에있는 외부 연결이있는 함수 호출의 문제입니다. 이 경우 inline
키워드를 사용하면 호출이 포함 된 번역 단위가 함수의 로컬 또는 인라인 정의도 포함 할 수 있습니다.
프로그램에는 외부 정의가있는 번역 단위, 인라인 정의가있는 번역 단위 및 선언이 있지만 함수에 대한 정의가없는 번역 단위가 포함될 수 있습니다. 후자의 번역 단위의 호출은 평소와 같이 외부 정의를 사용합니다.
함수의 인라인 정의는 외부 정의와 다른 정의로 간주됩니다. func
인라인 정의가 표시되는 곳에서 외부 연결이있는 일부 함수에 대한 호출이 발생하면 __func
내부 연결을 사용 하여 다른 함수 (예 :)를 호출 한 것과 동일한 동작이 수행됩니다
. 준수 프로그램은 호출되는 함수에 의존해서는 안됩니다. 이것은 표준의 인라인 모델입니다.
준수 프로그램은 인라인 정의를 사용하는 구현에 의존해서는 안되며 외부 정의를 사용하는 구현에 의존해서는 안됩니다. 함수의 주소는 항상 외부 정의에 해당하는 주소이지만이 주소가 함수를 호출하는 데 사용되는 경우 인라인 정의가 사용될 수 있습니다. 따라서 다음 예제는 예상대로 작동하지 않을 수 있습니다.
inline const char *saddr(void)
{
static const char name[] = "saddr";
return name;
}
int compare_name(void)
{
return saddr() == saddr(); // unspecified behavior
}
구현시 호출 중 하나에 인라인 정의를 saddr
사용하고 다른 호출에 외부 정의를 사용할 수 있으므로 같음 연산이 1 (true)로 평가된다는 보장은 없습니다. 이는 인라인 정의 내에서 정의 된 정적 개체가 외부 정의의 해당 개체와 구별됨을 보여줍니다. 이로 인해 const
이러한 유형 의 비 객체를 정의하는 것에 대한 제약 이있었습니다.
인라이닝은 기존 링커 기술로 구현할 수있는 방식으로 표준에 추가되었으며 C99 인라인의 하위 집합은 C ++와 호환됩니다. 이는 인라인 함수의 정의를 포함하는 정확히 하나의 번역 단위를 함수에 대한 외부 정의를 제공하는 것으로 지정하도록 요구함으로써 달성되었습니다. 해당 사양은 inline
키워드가 없거나 inline
및 둘 다 포함 하는 선언으로 만 구성되기 때문에 extern
C ++ 번역기에서도 허용됩니다.
C99의 인라인은 두 가지 방법으로 C ++ 사양을 확장합니다. 첫째, 함수가
inline
하나의 번역 단위에서 선언 inline
된 경우 다른 모든 번역 단위에서 선언 될 필요가 없습니다 . 예를 들어 라이브러리 내에서 인라인되지만 다른 곳에서 외부 정의를 통해서만 사용할 수있는 라이브러리 함수를 허용합니다. 외부 함수에 래퍼 함수를 사용하는 대신 추가 이름이 필요합니다. 번역자가 실제로 인라인 대체를 수행하지 않으면 성능에 악영향을 미칠 수도 있습니다.
둘째, 인라인 함수의 모든 정의가 "정확히 동일"해야한다는 요구 사항은 호출이 가시적 인 인라인 정의 또는 외부 정의로 구현되는지 여부에 따라 프로그램의 동작이 의존해서는 안된다는 요구 사항으로 대체됩니다. 함수. 이를 통해 특정 번역 단위 내에서 사용하도록 인라인 정의를 전문화 할 수 있습니다. 예를 들어, 라이브러리 함수의 외부 정의에는 동일한 라이브러리의 다른 함수에서 수행 된 호출에 필요하지 않은 일부 인수 유효성 검사가 포함될 수 있습니다. 이러한 확장은 몇 가지 장점을 제공합니다. 호환성에 관심이있는 프로그래머는 더 엄격한 C ++ 규칙을 따를 수 있습니다.
참고가되어 있지 구현 표준 헤더에 표준 라이브러리 함수의 인라인 정의를 제공하기 위해이 일부 레거시 코드를 깰 수 있기 때문에 적절한 그 자신의 헤더를 포함한 후 redeclares는 표준 라이브러리 함수. 이 inline
키워드는 사용자에게 함수 인라인을 제안 할 수있는 이식 가능한 방법을 제공하기위한 것입니다. 표준 헤더는 이식 할 필요가 없기 때문에 구현에는 다음과 같은 다른 옵션이 있습니다.
#define abs(x) __builtin_abs(x)
또는 표준 라이브러리 함수를 인라인하기위한 기타 이식 불가능한 메커니즘.