2013-08-24 4 views
5

호기심에서 벗어나 C++ 문자열 리터럴의 실제 기본 유형이 무엇인지 궁금합니다.C++ 문자열 리터럴 유형

내가 관찰 한 내용에 따라 결과가 달라집니다. 다음과 같은

유형 ID 시험 :

std::cout << typeid("test").name() << std::endl; 

나를 char const[5]을 보여줍니다. 그래서 (주어진 오류를보고)처럼 호환되지 않는 유형의 문자열 리터럴을 할당하려고

:

wchar_t* s = "hello"; 

나는 VS12의 인텔리에서 a value of type "const char *" cannot be used to initialize an entity of type "wchar_t *"를 얻을.

하지만 다음 줄이 VS12에 의해 허용되는대로 const char *을 할 수 표시되지 않습니다 : 나는 그것을 위해이었다로이 전 C++ 11 개 표준에서 허용 된 것을 읽고

char* s = "Hello"; 

s을 수정해도 정의되지 않은 동작이 발생하지만 C와의 호환성은 유지됩니다. 이 VS12는 아직 C++ 11 표준을 모두 구현하지 않았으며이 줄은 일반적으로 오류가 발생한다고 가정합니다.

C99 표준 (from here, 6.4.5.5)를 읽기

는 배열되어야한다고 제안한다 : 멀티 바이트 시퀀스는 다음 정적 저장 기간과 길이 배열을 초기화하는 데 사용되는

단지 시퀀스를 포함하는 것이 좋습니다.

그래서 C++ 문자열 리터럴 아래에 어떤 문자가 있습니까?

감사합니다.

+5

VS12는 C++과 비슷하지만 동일하지 않은 이상한 언어를 사용합니다. –

답변

8

문자열 리터럴의 유형은 실제로 const char[SIZE]입니다. 여기서 SIZE은 null 종결 문자의 길이입니다.

종종 const char*이 표시된다는 사실은 일반적인 배열 대 포인터 감쇠 때문입니다.

하지만 다음 줄이 VS12에 의해 허용되는대로 const char *을 할 수 있는지 볼 수 없습니다 : char* s = "Hello";

이 일반적인 예외로 C++ 03 (올바른 행동이었다 const-correctness rules)하지만 이후로는 사용되지 않습니다. C++ 11 호환 컴파일러는 해당 코드를 허용해서는 안됩니다.

+2

모든 컨텍스트에서 "일반적인 배열 - 포인터 감쇠"가 발생하지 않습니다. C에서는 배열 표현식이 단항'&'또는'sizeof'의 피연산자가 아니거나 배열 (하위) 객체를 초기화하는 데 사용되는 이니셜 라이저의 문자열 리터럴이 아니면 발생합니다. C++에는 더 많은 예외가 있습니다. –

+0

올바른 용어는 _Array-to-pointer Conversion_이며, 이는 최신 C++ 표준의 4 절에 설명 된 _ 표준 변환입니다. 대충 말하면 표준 컨버전은 특정 상황에서 컴파일러가 표현식에 암시 적으로 적용 할 수 있습니다. –

5

문자열 리터럴 유형은 char const[N]입니다. 여기서 N은 종료 널 문자를 포함하는 문자 수입니다. 이 유형은 이 아니지만char*으로 변환되지만 C++ 표준에는 문자열 리터럴을 char*에 할당 할 수있는 절이 포함됩니다.이 절은 특히 const이없는 C 코드의 호환성을 지원하기 위해 추가되었습니다.

보통 문자열 상수와 UTF-8 스트링 리터럴 또한 좁은 문자열 상수라고 :

표준의 유형에 대한 관련 절 2.14.5은 [lex.string] 제 8이다. 좁은 문자열 리터럴은 "array of n const char"형식을 갖습니다. 여기서 n은 아래 정의 된 문자열의 크기이고 정적 저장 기간 (3.7)입니다.

+1

이 exceptional 절은 이제 더 이상 사용되지 않으며'char *'에 문자열 리터럴을 할당하려고하면 컴파일 타임 오류가 발생합니다. – syam

+0

@syam - "비추천"은 여전히 ​​합법적이지만 향후에 사라질 수 있음을 의미합니다. 문자열 리터럴을 char *로 변환하는 것은 C++ 03에서 더 이상 사용되지 않습니다. C++ 11에서는 유효하지 않게되었습니다. 그러나 언어 정의에는 "컴파일 타임 오류"가 필요하지 않습니다. 진단 가능한 제약 조건 위반의 경우 유일한 요구 사항은 컴파일러가 진단을 실행하는 것입니다. 코드를 컴파일하는 일은 무료입니다. 이것이 구현에 특화된 확장 기능입니다. 컴파일러가 코드 컴파일을 거부해야하는 상황은 오직 하나뿐입니다 :'# error' 지시어. –

-1

먼저 오프 리터럴 C++ 문자열 유형 Nconst char의 배열이다. 둘째, 문자열 리터럴을 사용하여 wchar_t를 초기화하려면 다음과 같이 코딩해야합니다.

wchar_t* s = L"hello" 
+0

이것은 유효한 코드가 아니며, 주어진 오류를보기위한 테스트 일뿐입니다. 하지만이 표준은 실제로 배열처럼되어야한다고 생각합니다. –

+7

아니요, 문자열 리터럴은 다른 답변에서 설명한대로 'const char *'가 아니라 'const char [SIZE]'입니다. -1 – syam

+1

그런 다음'sizeof "hello, world"가 13이되는 이유를 설명하십시오. –