Character literal
Table des matières |
Syntaxe
'
c-char
'
|
(1) | ||||||||
u8'
c-char
'
|
(2) | (depuis C++17) | |||||||
u'
c-char
'
|
(3) | (depuis C++11) | |||||||
U'
c-char
'
|
(4) | (depuis C++11) | |||||||
L'
c-char
'
|
(5) | ||||||||
'
c-char-sequence
'
|
(6) | ||||||||
L'
c-char-sequence
'
|
(7) | (jusqu'à C++23) | |||||||
| c-char | - |
soit
|
| basic-c-char | - | Un caractère du jeu de caractères source de base (jusqu'en C++23) jeu de caractères de traduction (depuis C++23) , sauf l'apostrophe ' , la barre oblique inverse \ , ou le caractère de nouvelle ligne |
| c-char-sequence | - | deux ou plusieurs c-char s |
Explication
Caractères non codables
|
7)
Si un
c-char
quelconque dans
c-char-sequence
ne peut pas être encodé comme une unité de code unique dans
l'encodage littéral étendu
, le programme est mal formé.
|
(jusqu'à C++23) |
Séquences d'échappement numériques
Les séquences d'échappement numériques (octales et hexadécimales) peuvent être utilisées pour spécifier la valeur du caractère.
|
Si le littéral de caractère contient une seule séquence d'échappement numérique, et que la valeur spécifiée par la séquence d'échappement est représentable par la version non signée de son type, le littéral de caractère a la même valeur que la valeur spécifiée (éventuellement après conversion vers le type caractère). Un littéral de caractère UTF- N peut avoir n'importe quelle valeur représentable par son type. Si la valeur ne correspond pas à un point de code Unicode valide, ou si son point de code correspondant n'est pas représentable comme une unité de code unique en UTF- N , il peut toujours être spécifié par une séquence d'échappement numérique avec la valeur. Par exemple, u8 ' \xff ' est bien formé et égal à char8_t ( 0xFF ) . |
(depuis C++23) |
|
Si la valeur spécifiée par une séquence d'échappement numérique utilisée dans un littéral de caractère ordinaire ou large n'est pas représentable par char ou wchar_t respectivement, la valeur du littéral de caractère est définie par l'implémentation. |
(jusqu'en C++23) |
|
Si la valeur spécifiée par une séquence d'échappement numérique utilisée dans un littéral de caractère ordinaire ou large avec un c-char est représentable par la version non signée du type sous-jacent de char ou wchar_t respectivement, la valeur du littéral est la valeur entière de ce type entier non signé et la valeur spécifiée convertie vers le type du littéral. Sinon, le programme est mal formé. |
(depuis C++23) |
|
Si la valeur spécifiée par une séquence d'échappement numérique utilisée dans un littéral de caractère UTF-
N
n'est pas représentable par le
|
(depuis C++11) |
Notes
Les littéraux multi-caractères ont été hérités par C depuis le langage de programmation B. Bien que non spécifiés par les normes C ou C++, la plupart des compilateurs (MSVC est une exception notable) implémentent les littéraux multi-caractères comme spécifié dans B : les valeurs de chaque caractère dans le littéral initialisent les octets successifs de l'entier résultant, dans l'ordre big-endian complété à droite par des zéros, par exemple la valeur de ' \1 ' est 0x00000001 et la valeur de ' \1 \2 \3 \4 ' est 0x01020304 .
En C, les constantes de caractères telles que 'a' ou ' \n ' ont le type int , plutôt que char .
Exemple
#include <cstdint> #include <iomanip> #include <iostream> #include <string_view> template<typename CharT> void dump(std::string_view s, const CharT c) { const uint8_t* data{reinterpret_cast<const uint8_t*>(&c)}; std::cout << s << " \t" << std::hex << std::uppercase << std::setfill('0'); for (auto i{0U}; i != sizeof(CharT); ++i) std::cout << std::setw(2) << static_cast<unsigned>(data[i]) << ' '; std::cout << '\n'; } void print(std::string_view str = "") { std::cout << str << '\n'; } int main() { print("Littéraux de caractères ordinaires :"); char c1 = 'a'; dump("'a'", c1); char c2 = '\x2a'; dump("'*'", c2); print("\n" "Littéraux multi-caractères ordinaires :"); int mc1 = 'ab'; dump("'ab'", mc1); // défini par l'implémentation int mc2 = 'abc'; dump("'abc'", mc2); // défini par l'implémentation print("\n" "Littéraux de caractères UTF-8 :"); char8_t C1 = u8'a'; dump("u8'a'", C1); // char8_t C2 = u8'¢'; dump("u8'¢'", C2); // erreur : ¢ correspond à deux unités de code UTF-8 // char8_t C3 = u8'猫'; dump("u8'猫'", C3); // erreur : 猫 correspond à trois unités de code UTF-8 // char8_t C4 = u8'🍌'; dump("u8'🍌'", C4); // erreur : 🍌 correspond à quatre unités de code UTF-8 print("\n" "Littéraux de caractères UTF-16 :"); char16_t uc1 = u'a'; dump("u'a'", uc1); char16_t uc2 = u'¢'; dump("u'¢'", uc2); char16_t uc3 = u'猫'; dump("u'猫'", uc3); // char16_t uc4 = u'🍌'; dump("u'🍌'", uc4); // erreur : 🍌 correspond à deux unités de code UTF-16 print("\n" "Littéraux de caractères UTF-32 :"); char32_t Uc1 = U'a'; dump("U'a'", Uc1); char32_t Uc2 = U'¢'; dump("U'¢'", Uc2); char32_t Uc3 = U'猫'; dump("U'猫'", Uc3); char32_t Uc4 = U'🍌'; dump("U'🍌'", Uc4); print("\n" "Littéraux de caractères larges :"); wchar_t wc1 = L'a'; dump("L'a'", wc1); wchar_t wc2 = L'¢'; dump("L'¢'", wc2); wchar_t wc3 = L'猫'; dump("L'猫'", wc3); wchar_t wc4 = L'🍌'; dump("L'🍌'", wc4); // non supporté sur Windows depuis C++23 }
Sortie possible :
Littéraux de caractères ordinaires : 'a' 61 '*' 2A Littéraux multi-caractères ordinaires : 'ab' 62 61 00 00 'abc' 63 62 61 00 Littéraux de caractères UTF-8 : u8'a' 61 Littéraux de caractères UTF-16 : u'a' 61 00 u'¢' A2 00 u'猫' 2B 73 Littéraux de caractères UTF-32 : U'a' 61 00 00 00 U'¢' A2 00 00 00 U'猫' 2B 73 00 00 U'🍌' 4C F3 01 00 Littéraux de caractères larges : L'a' 61 00 00 00 L'¢' A2 00 00 00 L'猫' 2B 73 00 00 L'🍌' 4C F3 01 00
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| CWG 912 | C++98 | le littéral de caractère ordinaire non encodable n'était pas spécifié | spécifié comme conditionnellement pris en charge |
| CWG 1024 | C++98 | le littéral multi-caractères devait être pris en charge | rendu conditionnellement pris en charge |
| CWG 1656 | C++98 |
la signification de la séquence d'échappement numérique
dans un littéral de caractère n'était pas claire |
spécifiée |
| P1854R4 | C++98 | les littéraux de caractères non encodables étaient conditionnellement pris en charge | le programme est mal formé |
Références
- Norme C++23 (ISO/IEC 14882:2024) :
-
- 5.13.3 Littéraux de caractères [lex.ccon]
- Norme C++20 (ISO/CEI 14882:2020) :
-
- 5.13.3 Littéraux de caractères [lex.ccon]
- Norme C++17 (ISO/CEI 14882:2017) :
-
- 5.13.3 Littéraux de caractères [lex.ccon]
- Norme C++14 (ISO/CEI 14882:2014) :
-
- 2.14.3 Littéraux de caractères [lex.ccon]
- Norme C++11 (ISO/CEI 14882:2011) :
-
- 2.14.3 Littéraux de caractères [lex.ccon]
- Norme C++03 (ISO/CEI 14882:2003) :
-
- 2.13.2 Littéraux de caractères [lex.ccon]
- Norme C++98 (ISO/CEI 14882:1998) :
-
- 2.13.2 Littéraux de caractères [lex.ccon]
Voir aussi
| littéraux définis par l'utilisateur (C++11) | littéraux avec suffixe défini par l'utilisateur |
|
Documentation C
pour
Constante de caractère
|
|