String literal
목차 |
구문
"
s-char-seq
(선택적)
"
|
(1) | ||||||||
R"
d-char-seq
(선택적)
(
r-char-seq
(선택적)
)
d-char-seq
(선택적)
"
|
(2) | (C++11부터) | |||||||
L"
s-char-seq
(선택적)
"
|
(3) | ||||||||
LR"
d-char-seq
(선택적)
(
r-char-seq
(선택적)
)
d-char-seq
(선택적)
"
|
(4) | (C++11부터) | |||||||
u8"
s-char-seq
(선택적)
"
|
(5) | (C++11부터) | |||||||
u8R"
d-char-seq
(선택적)
(
r-char-seq
(선택적)
)
d-char-seq
(선택적)
"
|
(6) | (C++11부터) | |||||||
u"
s-char-seq
(선택적)
"
|
(7) | (C++11부터) | |||||||
uR"
d-char-seq
(선택적)
(
r-char-seq
(선택적)
)
d-char-seq
(선택적)
"
|
(8) | (C++11부터) | |||||||
U"
s-char-seq
(선택적)
"
|
(9) | (C++11부터) | |||||||
UR"
d-char-seq
(선택적)
(
r-char-seq
(선택적)
)
d-char-seq
(선택적)
"
|
(10) | (C++11부터) | |||||||
설명
| s-char-seq | - | 하나 이상의 s-char 로 이루어진 시퀀스 |
| s-char | - | 다음 중 하나 |
| basic-s-char | - | 기본 원본 문자 집합 (C++23까지) 변환 문자 집합 (C++23부터) 에 속하는 문자 중 큰따옴표 " , 백슬래시 \ , 또는 개행 문자를 제외한 문자 |
| d-char-seq | - | 하나 이상의 d-char 로 이루어진 시퀀스 (최대 16자) |
| d-char | - | 기본 원본 문자 집합 (C++23까지) 기본 문자 집합 (C++23부터) 에 속하는 문자 중 괄호, 백슬래시, 공백 문자 를 제외한 문자 |
| r-char-seq | - |
하나 이상의
r-char
로 이루어진 시퀀스 (단, 종료 시퀀스
)
d-char-seq
"
를 포함할 수 없음)
|
| r-char | - | 기본 원본 문자 집합 (C++23까지) 변환 문자 집합 (C++23부터) 에 속하는 문자 |
| 구문 | 종류 | 타입 | 인코딩 | ||||
|---|---|---|---|---|---|---|---|
| (1,2) | 일반 문자열 리터럴 | const char [ N ] | 일반 리터럴 인코딩 | ||||
| (3,4) | 와이드 문자열 리터럴 | const wchar_t [ N ] | 와이드 리터럴 인코딩 | ||||
| (5,6) | UTF-8 문자열 리터럴 |
|
UTF-8 | ||||
| (7,8) | UTF-16 문자열 리터럴 | const char16_t [ N ] | UTF-16 | ||||
| (9,10) | UTF-32 문자열 리터럴 | const char32_t [ N ] | UTF-32 |
위 표에 나열된 유형에서, N 는 아래에서 결정되는 인코딩된 코드 단위의 수입니다. 아래 .
일반 및 UTF-8 (C++11부터) 문자열 리터럴을 통칭하여 좁은 문자열 리터럴(narrow string literals)이라고 합니다.
문자열 리터럴을 평가하면 정적 저장 기간 을 가진 문자열 리터럴 객체가 생성됩니다. 모든 문자열 리터럴이 겹치지 않는 객체 에 저장되는지 여부와 문자열 리터럴의 연속적인 평가가 동일한 객체를 반환하는지 다른 객체를 반환하는지는 명시되어 있지 않습니다.
문자열 리터럴 객체를 수정하려는 시도의 효과는 정의되지 않습니다.
bool b = "bar" == 3 + "foobar"; // true 또는 false일 수 있으며, 지정되지 않음 const char* pc = "Hello"; char* p = const_cast<char*>(pc); p[0] = 'M'; // 정의되지 않은 동작
원시 문자열 리터럴
원시 문자열 리터럴은 접두사로
// OK: 하나의 백슬래시를 포함함, // "\\"와 동등함 R"(\)"; // OK: 네 개의 \n 쌍을 포함함, // "\\n\\n\\n\\n"와 동등함 R"(\n\n\n\n)"; // OK: 하나의 닫는 괄호, 두 개의 큰따옴표 및 하나의 여는 괄호를 포함함, // ")\"\"("와 동등함 R"-()""()-"; // OK: "\n)\\\na\"\"\n"와 동등함 R"a( )\ a"" )a"; // OK: "x = \"\"\\y\"\""와 동등함 R"(x = ""\y"")"; // R"<<(-_-)>>"; // 오류: 시작과 끝 구분자가 일치하지 않음 // R"-()-"-()-"; // 오류: )-"가 중간에 나타나 리터럴을 종료함 |
(C++11부터) |
초기화
문자열 리터럴 객체는 문자열 리터럴의 s-char 시퀀스 및 r-char 시퀀스 (C++11부터) 에 해당하는 코드 유닛 값 시퀀스와 종료 널 문자(U+0000)를 다음과 같은 순서로 초기화됩니다:
T
를 문자열 리터럴의 배열 요소 타입(위의
표
참조)으로 지정합니다:
-
만약
v
가
T의 표현 가능한 값 범위를 초과하지 않으면, 이스케이프 시퀀스는 값 v 를 갖는 단일 코드 단위를 제공합니다. -
그렇지 않고,
문자열 리터럴이 구문
(1)
또는
(3)
이고,
(C++11부터)
v
가
T의 기본 타입에 해당하는 부호 없는 타입의 표현 가능한 값 범위를 초과하지 않으면, 이스케이프 시퀀스는T타입의 고유한 값을 갖는 단일 코드 단위를 제공하며, 이 값은 v mod 2 S
와 합동입니다. 여기서 S 는T의 너비입니다. - 그렇지 않으면, 프로그램은 ill-formed입니다.
연결
인접한 문자열 리터럴은 번역 단계 6 (전처리 이후)에서 연결됩니다:
- 두 문자열 리터럴이 동일한 종류(kind) 인 경우, 연결된 문자열 리터럴도 해당 종류를 가집니다.
|
(C++11 이전) | ||||
|
(C++11 이후) |
"Hello, " "world!" // 6단계에서 2개의 문자열 리터럴이 "Hello, world!"를 형성함 L"Δx = %" PRId16 // 4단계에서 PRId16이 "d"로 확장됨 // 6단계에서 L"Δx = %"와 "d"가 L"Δx = %d"를 형성함
- ↑ 이러한 연결을 지원하는 것으로 알려진 구현체는 없습니다.
평가되지 않은 문자열
다음 컨텍스트들은 문자열 리터럴을 기대하지만, 이를 평가하지는 않습니다:
| (C++11부터) | |
|
(C++14부터) |
|
(C++20부터) |
| (C++26부터) |
|
비-일반 문자열 리터럴이 이러한 문맥에서 허용되는지 여부는 명시되지 않음 , 단 리터럴 연산자 이름은 반드시 일반 문자열 리터럴을 사용해야 함 (since C++11) . |
(until C++26) |
|
이러한 문맥에서는 일반 문자열 리터럴만 허용됨. 평가되지 않은 문자열 내의 각 universal character name 과 각 simple escape sequence 은 그것이 나타내는 translation character set 의 멤버로 대체됨. 숫자 이스케이프 시퀀스나 조건부 이스케이프 시퀀스를 포함하는 평가되지 않은 문자열은 잘못된 형식임. |
(since C++26) |
참고 사항
문자열 리터럴은 문자 배열을 초기화 하는 데 사용할 수 있습니다. 배열이 char str [ ] = "foo" ; 와 같이 초기화되면, str 은 문자열 "foo" 의 복사본을 포함하게 됩니다.
|
문자열 리터럴은 C와의 호환성을 위해 비상수 char * 또는 wchar_t * 로 변환 및 할당 가능합니다. C에서 문자열 리터럴의 타입이 char [ N ] 과 wchar_t [ N ] 이기 때문입니다. 이러한 암시적 변환은 사용이 권장되지 않습니다. |
(C++11 이전) |
|
문자열 리터럴은 비상수
|
(C++11 이후) |
문자열 리터럴은 반드시 널 종료 문자 시퀀스일 필요는 없습니다: 문자열 리터럴에 내장된 널 문자가 있는 경우, 이는 둘 이상의 문자열을 포함하는 배열을 나타냅니다.
const char* p = "abc\0def"; // std::strlen(p) == 3, 하지만 배열의 크기는 8입니다
문자열 리터럴에서 16진수 이스케이프 시퀀스 뒤에 유효한 16진수 숫자가 오는 경우, 잘못된 이스케이프 시퀀스로 인해 컴파일이 실패합니다. 문자열 연결을 우회 방법으로 사용할 수 있습니다:
//const char* p = "\xfff"; // 오류: 16진수 이스케이프 시퀀스가 범위를 벗어남 const char* p = "\xff""f"; // 정상: 리터럴은 {'\xff','f','\0'}를 담는 const char[3] 타입
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_char8_t
|
202207L
|
(C++23)
(DR20) |
char8_t 호환성 및 이식성 수정 ( ( unsigned ) char 배열 초기화 를 UTF-8 문자열 리터럴로 허용) |
__cpp_raw_strings
|
200710L
|
(C++11) | Raw 문자열 리터럴 |
__cpp_unicode_literals
|
200710L
|
(C++11) | 유니코드 문자열 리터럴 |
예제
#include <iostream> // array1과 array2는 동일한 값을 포함합니다: char array1[] = "Foo" "bar"; char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'}; const char* s1 = R"foo( Hello World )foo"; // 다음과 동일함 const char* s2 = "\nHello\n World\n"; // 다음과 동일함 const char* s3 = "\n" "Hello\n" " World\n"; const wchar_t* s4 = L"ABC" L"DEF"; // OK, 다음과 동일함 const wchar_t* s5 = L"ABCDEF"; const char32_t* s6 = U"GHI" "JKL"; // OK, 다음과 동일함 const char32_t* s7 = U"GHIJKL"; const char16_t* s9 = "MN" u"OP" "QR"; // OK, 다음과 동일함 const char16_t* sA = u"MNOPQR"; // const auto* sB = u"Mixed" U"Types"; // C++23 이전에는 구현에 따라 지원될 수도 있고 지원되지 않을 수도 있음; // C++23부터는 형식이 잘못됨 const wchar_t* sC = LR"--(STUV)--"; // OK, 원시 문자열 리터럴 int main() { std::cout << array1 << ' ' << array2 << '\n' << s1 << s2 << s3 << std::endl; std::wcout << s4 << ' ' << s5 << ' ' << sC << std::endl; }
출력:
Foobar Foobar Hello World Hello World Hello World ABCDEF ABCDEF STUV
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
|
CWG 411
( P2029R4 ) |
C++98 |
문자열 리터럴 내 이스케이프 시퀀스가
여러 코드 단위에 매핑되는 것이 허용되지 않음 |
허용됨 |
|
CWG 1656
( P2029R4 ) |
C++98 |
문자열 리터럴 내 숫자 이스케이프 시퀀스로
표시되는 문자가 불명확했음 |
명확하게 규정됨 |
| CWG 1759 | C++11 |
UTF-8 문자열 리터럴이
char 에 표현 불가능한 코드 단위를 가질 수 있었음 |
char 가 모든 UTF-8 코드 단위를 표현 가능 |
| CWG 1823 | C++98 |
문자열 리터럴의 구별 여부가
구현에 따라 정의됨 |
구별 여부는 명시되지 않으며, 동일한
문자열 리터럴이 다른 객체를 생성할 수 있음 |
|
CWG 2333
( P2029R4 ) |
C++11 |
UTF-8/16/32 문자열 리터럴에서 숫자 이스케이프 시퀀스
허용 여부가 불명확했음 |
명확하게 규정됨 |
| CWG 2870 | C++11 |
두 개의 일반 문자열 리터럴을
연결한 결과가 불명확했음 |
명확하게 규정됨 |
| P1854R4 | C++98 |
인코딩 불가능한 문자가 포함된 일반 및
와이드 문자열 리터럴이 조건부 지원됨 |
이러한 리터럴을 포함하는 프로그램은 형식 오류 |
| P2029R4 | C++98 |
1. 문자열 리터럴이 인코딩 불가능한 문자를
포함할 수 있는지 불명확했음 2. 문자열 리터럴이 해당 코드 단위가 리터럴의 배열 요소 타입으로 표현 불가능한 숫자 이스케이프 시퀀스를 포함할 수 있는지 불명확했음 |
1. 일반 및 와이드 문자열 리터럴에 대해
조건부 지원으로 규정 [1] 2. 코드 단위가 기본 타입에 해당하는 부호 없는 정수 타입으로 표현 불가능한 경우 형식 오류 |
- ↑ P1854R4는 이후 DR로 채택되어 이 결정을 재정의하였습니다.
참고문헌
- C++23 표준 (ISO/IEC 14882:2024):
-
- 5.13.5 문자열 리터럴 [lex.string]
- C++20 표준(ISO/IEC 14882:2020):
-
- 5.13.5 문자열 리터럴 [lex.string]
- C++17 표준 (ISO/IEC 14882:2017):
-
- 5.13.5 문자열 리터럴 [lex.string]
- C++14 표준(ISO/IEC 14882:2014):
-
- 2.14.5 문자열 리터럴 [lex.string]
- C++11 표준 (ISO/IEC 14882:2011):
-
- 2.14.5 문자열 리터럴 [lex.string]
- C++03 표준 (ISO/IEC 14882:2003):
-
- 2.13.4 문자열 리터럴 [lex.string]
- C++98 표준(ISO/IEC 14882:1998):
-
- 2.13.4 문자열 리터럴 [lex.string]
참고 항목
| 사용자 정의 리터럴 (C++11) | 사용자 정의 접미사를 가진 리터럴 |
|
C 문서
for
문자열 리터럴
|
|