"정적"함수와 "정적 인라인"함수의 차이점은 무엇입니까?


123

IMO는 둘 다 번역 단위의 범위 만 갖도록 기능을 만듭니다.

"정적"함수와 "정적 인라인"함수의 차이점은 무엇입니까?

inline파일이 아닌 헤더 파일에 넣어야 .c합니까?

답변:


109

inline컴파일러가 실제 호출을 실행하는 대신 호출 코드에 함수 내용 포함 하도록 지시합니다 .

자주 호출되는 작은 기능으로 성능에 큰 차이를 만들 수 있습니다.

그러나 이것은 "힌트"일 뿐이며 컴파일러는이를 무시할 수 있으며, 대부분의 컴파일러는 가능한 경우 최적화의 일부로 키워드가 사용되지 않는 경우에도 "인라인"을 시도합니다.

예를 들면 :

static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};

이 긴밀한 루프는 각 반복에서 함수 호출을 수행하며 함수 내용은 실제로 컴파일러가 호출을 수행하는 데 필요한 코드보다 훨씬 적습니다. inline본질적으로 컴파일러에게 위의 코드를 다음과 같은 코드로 변환하도록 지시합니다.

 int i;
 ....
 for (i=0; i<999999; i = i+1) { /* do something here */};

실제 함수 호출을 건너 뛰고 반환

분명히 이것은 실제 코드가 아닌 요점을 보여주는 예제입니다.

static범위를 나타냅니다. C에서는 함수 / 변수가 동일한 번역 단위 내에서만 사용될 수 있음을 의미합니다.


4
아니요, static범위를 나타냅니다. C에서는 함수 / 변수가 동일한 번역 단위 내에서만 사용될 수 있음을 의미합니다.
littleadv 2011 년

8
인라인으로 선언 된 코드는 헤더에 속하므로 일반 (템플릿이 아닌) 소스 코드는 여러 재정의 오류없이 헤더에 들어갈 수 없습니다. 뭔가 인라인을 선언 할 때 그래서 심지어 컴파일러 선택한다면 그것을 인라인하지 않는 경우에도 표준 위임 다중 재정 피하는 동작은 여전히 존재하는 차기 인치
VoidStar

13
@VoidStar 실제로 static(포함 또는 제외 inline) 헤더에 완벽하게 포함될 수 있습니다. 이유가 없습니다. 템플릿은 C입니다 ++,이 질문은 C.에 관한 것입니다
littleadv

2
@littleadv : 헤더 파일에 함수 정의를 착용하는 주된 이유는, 그들이 inlinable 수 있도록하는 것입니다 그래서 명시 적으로 표시하는 것은 inlineIMO, 좋은 스타일이다
크리스토프

9
실제로 컴파일러에게 인라인 시도를 수행 하도록 지시inline 하지 않습니다 . 프로그래머가 ODR 위반없이 여러 번역 단위에 함수 본문을 포함 할 수 있도록합니다. 이것의 부작용은 컴파일러 가 함수를 인라인 할 때 실제로 이것을 할 수있게한다는 입니다.
Ruslan

96

기본적으로 인라인 정의는 현재 번역 단위에서만 유효합니다.

스토리지 클래스가 extern인 경우 식별자에는 외부 연결이 있으며 인라인 정의는 외부 정의도 제공합니다.

스토리지 클래스가 static인 경우 식별자에는 내부 연결이 있고 다른 번역 단위에서는 인라인 정의가 표시되지 않습니다.

스토리지 클래스가 지정되지 않은 경우 인라인 정의는 현재 번역 단위에서만 볼 수 있지만 식별자에는 여전히 외부 연결이 있으며 외부 정의는 다른 번역 단위에 제공되어야합니다. 현재 번역 단위 내에서 함수가 호출되는 경우 컴파일러는 인라인 또는 외부 정의를 자유롭게 사용할 수 있습니다.

컴파일러는 현재 번역 단위에서 정의가 표시되는 모든 함수를 인라인 (인라인하지 않음) 할 수 있으므로 C 표준이 실제로 설명하지는 않지만 다른 번역 단위에서도 링크 시간 최적화 덕분에 즉), 대부분의 실용적인 목적을 위해 static와 사이에는 차이가 없습니다.static inline 함수 정의 .

inline(등 지정 register저장 클래스)에만 컴파일러 힌트이며, 컴파일러는 완전히 무시 무료입니다. 표준 준수 비 최적화 컴파일러는 부작용 만 고려하면되며 최적화 컴파일러는 명시 적 힌트를 사용하거나 사용하지 않고 이러한 최적화를 수행합니다.

inline그리고 register프로그래머가 불가능 최적화를 만들 것 코드를 쓸 때 컴파일러에 지시합니다 그들이 오류를 던져로하지만, 쓸모없는 : 외부 inline정의 할 수 없습니다 (이 다른 번역 단위에서 사용할 수없는 것처럼) 내부 링크와 참조 식별자 또는 정적 저장 기간으로 수정 가능한 지역 변수를 정의하고 (이들은 번역 단위 간 상태를 공유하지 않기 때문에) register한정된 변수의 주소를 사용할 수 없습니다 .

개인적으로, 나는 마크에 규칙을 사용 static또한 헤더 내에서 함수 정의 inline헤더 파일에 함수 정의를 착용하는 주된 이유로하는 것은, 그들이 inlinable 확인하는 것입니다.

일반적으로 헤더 내의 선언 외에 static inline함수 및 static const객체 정의 만 사용 합니다 extern.

.NET inline과 다른 스토리지 클래스 로 함수를 작성한 적이 없습니다 static.


8
이것은 정답입니다. inline실제로 인라이닝에 적용된 것처럼 말하는 모든 답변 은 오해의 소지가 있으며 틀림없이 정확합니다. 어떤 현대 컴파일러도이를 인라인하기위한 힌트로 사용하거나 함수 인라인을 활성화하기 위해이를 요구하지 않습니다.
Tyg13

1
"정적 함수 정의를 헤더에 인라인으로 표시하는 규칙을 사용하십시오"에 대해 찬성되었습니다.
John Z. Li

나는 전체 답을 읽고 난 여전히 사이의 의미 적 차이를하지 않습니다 staticstatic inline. 둘 다 다른 번역 단위에서 정의를 보이지 않게 만듭니다. 그래서 static inline대신 쓰는 합리적인 이유 는 static무엇입니까?
user541686

21

GCC 내 경험에서 나는 것을 알고 staticstatic inline방식으로 어떻게 다른지 사용되지 않는 기능에 대한 컴파일러 문제 경고. 보다 정확하게 static함수 를 선언 하고 현재 번역 단위에서 사용되지 않을 때 컴파일러는 사용하지 않는 함수에 대한 경고를 생성하지만 static inline.

따라서 나는 그것이 static번역 단위에서 사용되어야 한다고 생각하고 사용하지 않는 함수를 찾기 위해 컴파일러가하는 추가 검사의 이점을 얻는다. 그리고 static inline경고를 발행하지 않고 인라인 될 수있는 (외부 링크가 없기 때문에) 함수를 제공하기 위해 헤더 파일에서 사용되어야합니다.

불행히도 그 논리에 대한 증거를 찾을 수 없습니다. GCC 문서에서도 inline사용하지 않는 함수 경고 를 금지 한다는 결론을 내릴 수 없었습니다 . 누군가가 그것에 대한 설명에 대한 링크를 공유하면 감사하겠습니다.


1
음은 여전히 가지고 warning: unused function 'function' [clang-diagnostic-unused-function]A의 static inline건물 때 기능을 clang-tidy다른 번역 단위에 사용된다 (v8.0.1에서). 그러나 이것은 static& inline! 를 결합하는 가장 좋은 설명이자 이유 중 하나입니다 .
DrumM

6

C에서 static정의한 함수 또는 변수는이 파일 (즉, 컴파일 단위)에서만 사용할 수 있음을 의미합니다.

따라서이 static inline파일에서만 사용할 수있는 인라인 함수를 의미합니다.

편집하다:

컴파일 단위번역 단위 여야합니다 .


2
또는 공상적인 말로 : 내부 연결이 있습니다.
K-ballo

@AlokSave : 컴파일 단위번역 단위 사이에 차이가 있습니까? 그렇다면 C ++ 언어의 맥락에서 어느 것이 더 적절합니까?
legends2k 2013 년

나는 내가 the compile unit잘못 쓴 것이라고 믿습니다. 그런 것은 없습니다. 실제 용어는translation unit
shengy

귀하의 답변은 대부분 헤더 파일, 전체 번역 단위에서 사용되기 때문에 완전하지 않습니다.
DrumM

5

한 가지 차이점은 언어 수준이 아니라 널리 사용되는 구현 수준입니다. 특정 버전의 gcc는 static inline기본적으로 출력에서 참조되지 않은 함수를 제거 하지만 static참조되지 않더라도 일반 함수 는 유지 합니다. 나는 확실히이 적용되는 버전 아니지만, 실용적인 관점에서 항상 사용하는 것이 좋습니다 수 있습니다 의미 inline에 대한 static헤더 기능을합니다.


inline정의에서 사용하는 것은 어떻습니까? extern기능 에도 사용하지 않는다는 의미 입니까?
new_perl

최신 버전의 GCC에서도 마찬가지입니까? 예를 들어 GCC 버전을 나열하면 대답이 훨씬 더 흥미로울 것입니다.
Z boson 2015

@Zboson : 저는 그 정보를 쉽게 구할 수 없으며 현재 많은 gcc 버전을 설정하고 테스트 할 시간이 없지만 유용한 정보가 될 것이라는 데 동의합니다. gcc가 처음에 사용되지 않는 정적 함수 / 객체를 최적화하기 시작했을 때 attribute((used))asm이 참조되지 않은 static함수 및 데이터 를 참조 할 수 있도록 허용하는 사용 내역 과 사용을 살펴보면 알 수 있습니다.
R .. GitHub의 STOP 돕기 ICE
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.