2

질문을 깊이 읽지 않아도되는 질문은 굵게 표시됩니다.함수 - 로컬 정적 Const 변수 초기화 의미

이것은 this 질문에 대한 후속 조치입니다. 함수에서 정적 변수의 초기화 의미와 관련이 있습니다. 정적 변수는 한 번 초기화해야하며 나중에 내부 상태가 변경 될 수 있습니다. 즉, 연결된 질문에서 I (현재)가 변경됩니다. 그러나 문제의 코드는 기능을 나중에 변수의 상태를 변경하지 않아도됩니다.

문자열 개체의 내부 상태가 변경 될 필요가 없기 때문에 내 위치를 명확하게 설명하겠습니다. 이 코드는 메타 프로그래밍을위한 특성 클래스를위한 것으로, const char * const ptr을 사용하지 않는 것이 좋습니다. 따라서 이상적으로는 로컬 비용 정적 const 변수가 필요합니다. 필자가 생각한 바에 따르면 문제의 문자열은 링크 로더에 의해 메모리에 최적으로 배치되고 코드는보다 안전하고 의도 된 의미로 매핑됩니다.

"C++ 프로그래밍 언어 3 판 - Stroustrup"에는이 문제에 관해 말할 수있는 것이 없습니다. 모든 것은 스레드의 제어 흐름이 처음 코드에 도달 할 때 변수가 한 번 초기화된다는 것입니다. 이것은 다음 코드가 의미가있을 지, 그리고 의도 된 의미가 아닌지 숙고하게 만듭니다.

#include <iostream> 
const char * const GetString(const char * x_in) 
{ 
    static const char * const x = x_in; 
    return x; 
} 

int main() 
{ 
    const char * const temp = GetString("yahoo"); 
    std::cout << temp << std::endl; 
    const char * const temp2 = GetString("yahoo2"); 
    std::cout << temp2 << std::endl; 
} 

"야후"두 번 GCC 및 인쇄에 대한 다음 컴파일합니다. 어느 것이 내가 원하는지 - 그러나 그것은 표준을 준수하지 않을 수도 있습니다 (이것이 내가이 질문을 게시하는 이유입니다). "SetString"과 "String"의 두 가지 기능을 갖는 것이 더 우수 할 수 있습니다. 표준에 부합하는 사람이라면 누군가 부스트 (또는 다른 곳)의 템플릿 구현을 알고 있습니까?

편집 : 나는 시간 정보를 컴파일 인코딩 내 수업에서 위에서 언급 한 게터/세터를 생성하기 위해 다음과 같은 매크로를 사용하고

11 월 2010 년.

#define MACRO_STATIC_SETTING_PTR(name, type)       \ 
    static const type const set_##name (const type const name##_in) { \ 
    static const type const name = name##_in;       \ 
    return name;              \ 
    }                 \ 
    static const type const name() {         \ 
    return set_##name(NULL);           \ 
    } 

#define MACRO_STATIC_SETTING(name, type)        \ 
    static const type set_##name (const type name##_in) {    \ 
    static const type name = name##_in;        \ 
    return name;              \ 
    }                 \ 
    static const type name() {           \ 
    return set_##name(NULL);           \ 
    } 

이러한 매크로는 클래스 선언 안에 있습니다. 예 :

template<class tag> 
class ConfigInstance{ 
public: 
    MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *) 
}; 

다른 사람들에게 유용하게 사용되기를 바랍니다.

+0

'const char * const GetString'에서 두 번째 const는 한정자가 l 값에만 적용되므로 의미가 없습니다. – JRL

+1

첫 번째 const는 포인터가 읽기 전용 메모리를 가리키는 것을 의미하지만 두 번째 const는 포인터 자체를 일정하게 만듭니다 (const는 첫 번째 토큰 일 때를 제외하고는 왼쪽 요소의 왼쪽 요소를 제외하고 왼쪽 요소에 대해 작동합니다). 'char * const GetString'은 쓰기 가능한 메모리에 상수 포인터를 제공하는 반면,'char * GetString'은 상수 메모리에 대한 변수 포인터를 생성합니다. – Rudi

+0

아마도 당신의 예문에 오타가 있지만, temp를 두 번 출력하면 항상 같은 결과가 나옵니다. – stefaanv

답변

4

C++ 표준의 6.7 §4 (선언문)을 살펴 보겠습니다.

구현은 구현 정적 공간 범위의 정적 저장 기간에 객체 를 초기화하도록 허용 동일한 조건 하에서 정적 저장 기간과 다른 로컬 객체 초기 초기화를 수행하는 것이 허용된다. 그렇지 않으면 첫 번째 컨트롤이 선언을 통해 을 전달할 때 이러한 개체가 초기화됩니다. 그러한 객체는 초기화가 완료되면 에 초기화 된 것으로 간주됩니다.우리가 정적 지역 x과 기능을 입력하기 전에

  1. 어느 우리가 지금, 어떤 값을 x이있을 것이다 :

그래서 우리는 두 가지 사례를 가지고있다. 그런 다음 컴파일러는 가능한 빨리 컴파일 타임에 값을 초기화 할 수 있습니다.

  • x의 값은 처음 입력 할 때만 초기화됩니다.
  • 그래서 gcc는 원하는 것뿐만 아니라 표준에도 부합합니다.

    +0

    컴파일러가 옵션 2 (함수를 처음 입력 할 때'x'의 초기화)를 선택할 때, 함수는 ** thread safe가 아니라는 점에 유의할 가치가 있습니다. –