여기에 뭔가 빠진 것 같아요.
정적 기능?
함수를 static으로 선언하면 컴파일 단위에서 "숨겨집니다".
네임 스페이스 범위 (3.3.6)가있는 이름은 다음과 같은 경우 내부 연결이 있습니다.
— 명시 적으로 정적으로 선언 된 변수, 함수 또는 함수 템플릿
3.5 / 3-C ++ 14 (n3797)
이름에 내부 연결이있는 경우 해당 엔터티는 동일한 번역 단위에있는 다른 범위의 이름으로 참조 될 수 있습니다.
3.5 / 2-C ++ 14 (n3797)
이 정적 함수를 헤더에 선언하면이 헤더를 포함한 모든 컴파일 단위에 자체 함수 사본이 있습니다.
문제는 해당 함수 내에 정적 변수가있는 경우이 헤더를 포함하는 각 컴파일 단위도 고유 한 개인 버전을 갖게됩니다.
인라인 기능?
인라인으로 선언하면 인라인 후보가됩니다 (요즘 C ++에서는 컴파일러가 인라인 여부에 관계없이 키워드 인라인이 존재하거나 없다는 사실을 무시하기 때문에 많은 의미가 없습니다).
인라인 지정자가있는 함수 선언 (8.3.5, 9.3, 11.3)은 인라인 함수를 선언합니다. 인라인 지정자는 호출 지점에서 함수 본문의 인라인 대체가 일반적인 함수 호출 메커니즘보다 선호됨을 구현에 나타냅니다. 호출 시점에서이 인라인 대체를 수행하기 위해 구현이 필요하지 않습니다. 그러나이 인라인 대체가 생략 되더라도 7.1.2에 정의 된 인라인 함수에 대한 다른 규칙은 여전히 준수됩니다.
7.1.2 / 2-C ++ 14 (n3797)
헤더에는 흥미로운 부작용이 있습니다. 인라인 함수는 동일한 모듈에서 여러 번 정의 될 수 있으며 링커는 단순히 "그들"을 하나로 결합합니다 (컴파일러의 이유로 인라인되지 않은 경우).
내부에 선언 된 정적 변수의 경우 표준은 특별히 거기에 하나만 명시합니다.
extern 인라인 함수의 정적 지역 변수는 항상 동일한 객체를 참조합니다.
7.1.2 / 4-C ++ 98 / C ++ 14 (n3797)
(함수는 기본적으로 extern이므로 함수를 정적으로 표시하지 않는 한 해당 함수에 적용됩니다)
이것은 결함이없는 "정적"(즉, 헤더에 정의 될 수 있음)의 장점이 있습니다 (인라인되지 않은 경우 최대 한 번만 존재 함).
정적 지역 변수?
정적 지역 변수에는 연결이 없지만 (범위 밖의 이름으로 참조 할 수 없음) 정적 저장 기간이 있습니다 (즉, 전역 적이지만 구성 및 파괴는 특정 규칙을 따릅니다).
정적 + 인라인?
인라인과 정적을 혼합하면 설명한 결과가 나타납니다 (함수가 인라인 된 경우에도 내부 정적 변수는 그렇지 않으며 정적 함수의 정의를 포함하는 컴파일 단위가있는만큼의 정적 변수로 끝납니다. ).
저자의 추가 질문에 대한 답변
질문을 작성한 이후로 Visual Studio 2008에서 시도해 보았습니다. VS가 표준에 따라 작동하도록하는 모든 옵션을 설정하려고했지만 일부를 놓쳤을 가능성이 있습니다. 결과는 다음과 같습니다.
함수가 단순히 "인라인"인 경우 정적 변수의 복사본이 하나만 있습니다.
함수가 "정적 인라인"이면 번역 단위 수만큼 복사본이 있습니다.
진짜 문제는 이제 일이 이런 식으로 이루어져야하는지 아니면 이것이 Microsoft C ++ 컴파일러의 특이한 것인지 여부입니다.
그래서 나는 당신이 다음과 같은 것을 가지고 있다고 가정합니다.
void doSomething()
{
static int value ;
}
함수 내부의 정적 변수, 간단히 말해서 함수의 범위를 제외한 모든 영역에 숨겨진 전역 변수를 인식해야합니다. 즉, 내부에서 선언 된 함수 만 도달 할 수 있음을 의미합니다.
함수를 인라인해도 아무것도 변경되지 않습니다.
inline void doSomething()
{
static int value ;
}
숨겨진 전역 변수는 하나만 있습니다. 컴파일러가 코드를 인라인하려고한다고해서 전역 숨겨진 변수가 하나뿐이라는 사실이 바뀌지는 않습니다.
이제 함수가 정적으로 선언 된 경우 :
static void doSomething()
{
static int value ;
}
그런 다음 각 컴파일 단위에 대해 "비공개"입니다. 즉, 정적 함수가 선언 된 헤더를 포함하는 모든 CPP 파일에는 전역 숨겨진 변수의 자체 사본을 포함하여 함수의 자체 사본이 있으므로 다음과 같은 많은 변수가 있습니다. 헤더를 포함한 컴파일 단위가 있습니다.
내부에 "정적"변수가있는 "정적"함수에 "인라인"추가 :
inline static void doSomething()
{
static int value ;
}
내부의 정적 변수에 관한 한이 "인라인"키워드를 추가하지 않는 것과 동일한 결과를 가져옵니다.
따라서 VC ++의 동작은 정확하고 "인라인"과 "정적"의 실제 의미를 잘못 이해하고 있습니다.