`static const`와`const`의 C ++ 시맨틱


149

C ++에서 구체적으로 예를 들어 다음과 같은 의미 론적 차이점은 무엇입니까?

static const int x = 0 ;

const int x = 0 ;

모두 static링키지 및 스토리지 클래스 지정자 (즉, 내부 및 외부 기능) 등.


7
static아마도 C ++에서 가장 많이로드 된 키워드 일 것입니다. 코드의 의미는 네임 스페이스 범위, 클래스 범위 또는 함수 범위에 따라 크게 다릅니다. 당신은 그것을 명확히하고 싶을 수도 있습니다.
sbi

1
@ sbi : 나는 이미 생각했다. 함수 범위 (스토리지 클래스 지정자) 및 파일 범위 (링크 지정자 인 경우) 클래스 멤버와 네임 스페이스 범위 변수는 특히이 질문과 관련하여 걱정하지 않지만 누군가가 흥미로운 차이점이 있다고 생각하면 자유롭게 커버하십시오.
Clifford

@Clifford : 마지막 말을 간과해서 죄송합니다. 그러나 이것은 사용자의 오해를 드러 냈습니다. C ++에서 파일 범위 네임 스페이스 범위입니다. 네임 스페이스 외부에 무언가를 선언하면 단순히 글로벌 네임 스페이스에 속하며 앞에 ::식별자가없는 접두사 를 통해 액세스 할 수 있습니다 . 전역 네임 스페이스와 중첩 된 네임 스페이스 사이의 의미있는 차이점을 알지 못합니다. 확실히 static객체 에 관한 것은 없습니다 .
sbi

1
연결가시성 과 다릅니다. 그것들을 상호 교환하여 사용하면 대화하는 사람들과 아마도 자신을 혼란스럽게 할 것입니다.
Ben Voigt

1
@Ben, @sbi : 파일 범위정적 연결 이 동일하다고 제안하지 않았으며 , 정적 연결 이 파일 범위를 의미한다는 것입니다 . 이러한 의미에서 범위 (또는 가시성)는 정적 및 외부 연결의 속성이며 동의어가 아닙니다. 나는 원래의 질문이 명확하고 잘 구성되어 있으며, 우리는 sbi의 다소 혼란스러운 발언에 대한 의견을 논의하고 있다고 생각합니다. 우리는 내 이해가 아닌 여기에서 영어의 부정확 한 의미론에 대해 논의하고 있으므로 중단 할 수 있다고 생각합니다.
Clifford

답변:


128

파일 범위에서 C ++에는 차이가 없습니다. const내부 연결을 기본값으로 만들고 모든 전역 변수는 정적 수명을 갖습니다. 그러나 첫 번째 변형은 C에서 동일한 동작을 가지므로이를 사용해야하는 좋은 이유가 될 수 있습니다.

함수 내에서 두 번째 버전은 매개 변수에서 계산할 수 있습니다. C 또는 C ++에서는 다른 언어와 같이 컴파일 타임 상수 일 필요는 없습니다.

클래스 내에서 기본적으로 함수와 동일합니다. ctor-initializer-listconst 에서 인스턴스 값을 계산할 수 있습니다 . A 는 시작 초기화 중에 설정되며 나머지 프로그램에서는 변경되지 않습니다. (참고 : 선언과 초기화가 분리되어 있기 때문에 멤버 코드 는 약간 다르게 보입니다.)static conststatic

C에서 + +, 기억 const수단이 읽기 전용 이 아닌 상수 . 포인터가 있으면 const프로그램의 다른 부분이 보이지 않는 동안 값을 변경할 수 있습니다. 변수가로 정의 된 경우 const초기화 후 아무도 변수 를 변경할 수 없지만 초기화는 여전히 복잡 할 수 있습니다.


1
파일 범위라는 것이 있습니까? 방금 $ 3.3을 확인하고 가장 가까운 것이 '네임 스페이스 범위'라고 생각합니다. 내 이해가 맞습니까? C ++ 03 표준은 Appendices
Chubsdad

2
파일 범위 는 컴파일러가 아닌 링커의 인공물이므로 언어 ​​표준에 큰 관심을 기울이지 않을 것을 제안합니다 . 엄밀히 말하면 아마도 "컴파일 단위 범위"일 것입니다.
Clifford

8
"const는 상수가 아니라 읽기 전용을 의미합니다"라는 문구에 +1, 즉 "컴파일러,이 const를 수정하려는 사람이 있으면 매우 크게 짖습니다." 이것이 무엇인가가 동시에 구성적이고 일시적 일 수있는 이유입니다.
Dan

5
"컴파일러, 만약 당신이이 const를 수정하려고한다면 (또는 다른 누군가에게 그렇게하도록 허락 해 주어야한다)", 매우 큰 소리로 짖는다. 대부분의 상황 const에서 변수 자체가 아닌 변수의 뷰에 적용되며 다른 사람 const이 동일한 변수를 볼 수 없으며 컴파일러는 변수를 수정할 때 매우 조용합니다.
Ben Voigt

1
@Ben : C ++ 0x는 특정 사용을 제거하지 않지만 대신 const새로운 constexpr시나리오를 사용할 수 있습니다 (다른 시나리오에서도). 실제로 C ++ 0x 표준 const은 해당 시나리오에서 사용할 수있는 기능 을 비 통합 "리터럴 유형"으로 확장합니다. constexpr어쨌든 pre-C ++ 0x 컴파일러와의 호환성을 깨뜨릴 수 있기 때문에 그러한 경우에 사용하는 것을 선호한다고 생각 합니다.
Michael Burr

4

C ++ 17 표준 초안 은 파일 범위 에서 const암시 static합니다.

https://stackoverflow.com/a/3709257/895245 에서 언급 한 내용에 대한 인용문입니다.

C ++ 17 n4659 표준 초안 6.5 "프로그램 및 링크":

3 네임 스페이스 범위 (6.3.6)를 가진 이름은 이름이

  • (3.1) — 명시 적으로 정적으로 선언 된 변수, 함수 또는 함수 템플릿; 또는,
  • (3.2) — 명시 적으로 extern으로 선언되지 않았거나 외부 연결을 갖도록 선언되지 않은 비 휘발성 const 한정 타입의 비 인라인 변수 또는
  • (3.3) — 익명 공용체의 데이터 멤버.

부록 C (정보) 호환성, C.1.2 6 절 : "기본 개념"은 이것이 C에서 변경된 이유에 대한 근거를 제공한다.

6.5 [또한 10.1.7]

변경 : 명시 적으로 선언 된 const이고 명시 적으로 extern으로 선언되지 않은 파일 범위의 이름에는 내부 연결이 있지만 C에서는 외부 연결이 있습니다.

이론적 근거 : const 객체는 C ++로 변환하는 동안 값으로 사용될 수 있으므로이 기능을 사용하면 프로그래머가 각 const 객체에 대해 명시적인 초기화를 제공해야합니다. 이 기능을 통해 사용자는 const 객체를 둘 이상의 번역 단위에 포함 된 소스 파일에 넣을 수 있습니다.

원래 기능에 미치는 영향 : 잘 정의 된 기능의 의미로 변경합니다.

변환의 어려움 : 의미 론적 변환.

얼마나 널리 사용됩니까?

참조 : const가 C에없는 경우 const가 C ++의 내부 연결을 의미하는 이유는 무엇입니까?

헤더 대신 할 일

에서 자세히 설명 : 무엇 CONST 정적 '평균 C 및 C ++합니까?

  • pre C ++ 17 : extern헤더, cpp 파일의 정의
  • post C ++ 17 : 헤더의 인라인 변수

고맙지 만 C ++ 98과 비교했을 때 C ++ 17에서는 기회가 아니라고 생각하며 2010 년에 질문을 받았습니다. 또한 귀하의 답변은 링크 지정자로 정적을 처리합니다 (네임 스페이스 범위). 질문은 다른 맥락에서 의미론에 대해 구체적으로 질문했습니다.
Clifford

@Clifford 네, C ++ 17보다 확실히 나이가 들었습니다. 모든 표준을 읽기가 게으 릅니다. ;-) 파일 범위 부분을 명확히합니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.