Program Tip

C 및 C ++의 문자열 리터럴 유형은 무엇입니까?

programtip 2020. 12. 5. 10:28
반응형

C 및 C ++의 문자열 리터럴 유형은 무엇입니까?


C에서 문자열 리터럴의 유형은 무엇입니까? 그것은인가 char *또는 const char *const char * const?

C ++는 어떻습니까?


C에서 문자열 리터럴의 유형은이다 char[]가 아니다 - const종류에 따라,하지만 내용을 수정하는 정의되지 않은 동작입니다. 또한 동일한 내용 (또는 동일한 내용으로 충분 함)을 가진 두 개의 서로 다른 문자열 리터럴은 동일한 배열 요소를 공유 할 수도 있고 공유하지 않을 수도 있습니다.

C99 표준 6.4.5 / 5 "문자열 리터럴-의미 체계"에서 :

변환 단계 7에서는 문자열 리터럴 또는 리터럴의 결과 인 각 멀티 바이트 문자 시퀀스에 값이 0 인 바이트 또는 코드가 추가됩니다. 그런 다음 멀티 바이트 문자 시퀀스를 사용하여 시퀀스를 포함하기에 충분한 정적 저장 기간 및 길이 배열을 초기화합니다. 문자열 리터럴의 경우 배열 요소는 유형 char을 가지며 멀티 바이트 문자 시퀀스의 개별 바이트로 초기화됩니다. 와이드 문자열 리터럴의 경우 배열 요소는 유형 wchar_t을 가지며 와이드 문자 시퀀스로 초기화됩니다.

요소에 적절한 값이있는 경우 이러한 배열이 구별되는지 여부는 지정되지 않습니다. 프로그램이 이러한 배열을 수정하려고하면 동작이 정의되지 않습니다.

C ++에서 "일반 문자열 리터럴은 'n 배열의 배열 const char'"(2.13.4 / 1 "문자열 리터럴") 유형을 갖습니다 . 그러나 C ++ 표준에는 문자열 리터럴에 대한 포인터를 상수가 아닌 포인터로 쉽게 변환하는 특수한 경우가 있습니다 (4.2 / 2 "Array-to-Pointer conversion").

와이드 문자열 리터럴이 아닌 문자열 리터럴 (2.13.4)은 "문자에 대한 포인터"유형의 rvalue로 변환 될 수 있습니다. 넓은 문자열 리터럴은 "pointer to wchar_t"유형의 rvalue로 변환 될 수 있습니다.

참고로 C / C ++의 배열은 포인터로 쉽게 변환되기 때문에 C / C ++의 모든 배열과 마찬가지로 포인터 컨텍스트에서 문자열 리터럴을 자주 사용할 수 있습니다.


추가 편집 : 다음은 문자열 리터럴 유형과 관련하여 C 및 C ++ 표준이 선택한 근거에 대한 대부분의 추측입니다. 따라서 소금 한 알과 함께 가져 가십시오 (그러나 수정 사항이나 추가 세부 사항이 있으면 의견을 말하십시오) :

C 표준은 리터럴 char을 가리키는 상수가 아닌 포인터 를 사용할 수있을 것으로 예상되는 코드가 너무 많았 기 때문에 문자열 리터럴 비 상수 유형을 선택했다고 생각합니다 . const한정자가 추가 되었을 때 (내가 실수하지 않았다면 ANSI 표준화 시간에 이루어졌지만 K & R C가 기존 코드를 많이 축적 한 지 오래되었습니다) 문자열 리터럴에 대한 포인터 만 할당 할 수있는 경우 char const*캐스트가없는 유형은 존재하는 거의 모든 프로그램을 변경해야합니다. 표준을 받아들이는 좋은 방법이 아닙니다 ...

문자열 리터럴이 const정규화 된다는 C ++의 변경 은 주로 리터럴 문자열이 " char const*"인수를 사용 하는 오버로드와 더 적절하게 일치하도록 지원하기 위해 수행 되었다고 생각합니다 . 유형 시스템에서 인식 된 구멍을 닫고 자하는 욕구도 있다고 생각하지만 배열-포인터 변환의 특수한 경우에 의해 구멍이 크게 열렸습니다.

표준의 Annex D는 "문자열 리터럴 (4.2)에 대한 const에서 non-const 자격으로의 암시 적 변환이 더 이상 사용되지 않음"을 나타냅니다. 그러나 너무 많은 코드가 여전히 깨져서 컴파일러 구현 자나 표준위원회는 실제로 플러그를 뽑을 의향이 있습니다 (다른 영리한 기술이 고안 될 수 없다면-구멍이 다시 돌아올 것입니다. 그렇지 않습니까?).


AC 문자열 리터럴에는 문자열 끝의 암시 적 0을 설명하기 위해 문자 수 + 1과 같은 유형 char [n]n있습니다.

배열은 정적으로 할당됩니다. const아니지만 수정하는 것은 정의되지 않은 동작입니다.

포인터 유형 char *또는 불완전한 유형 char []sizeof있는 경우 예상대로 작동하지 않습니다.

문자열 리터럴을 만드는 const것은 C ++ 관용구이며 C 표준의 일부가 아닙니다.


다양한 역사적 이유로 문자열 리터럴은 항상 char[]C 유형 이었습니다.

초기 (C90에서) 문자열 리터럴을 수정하면 정의되지 않은 동작이 호출된다는 것이 명시되었습니다.

그들은 그러한 수정을 금지하지 않았 const char[]으며 더 의미가있을 문자열 리터럴 만들지 않았습니다 . 이것은 이전 코드와의 역 호환성 때문이었습니다. 일부 오래된 OS (특히 DOS)는 문자열 리터럴을 수정해도 항의하지 않았으므로 이러한 코드가 많이있었습니다.

C는 가장 최근의 C 표준에서도 여전히 이러한 결함을 가지고 있습니다.

C ++는 C에서 동일한 결함을 상속 받았지만 이후의 C ++ 표준에서는 마침내 문자열 리터럴을 만들었습니다 const(C ++ 03에서는 구식으로 표시되고 마지막으로 C ++ 11에서 수정 됨).


그들은 유형 char[]이었습니다. 이제 그들은 유형 const char[]입니다.

참고 URL : https://stackoverflow.com/questions/2245664/what-is-the-type-of-string-literals-in-c-and-c

반응형