Character literal
Contenidos |
Sintaxis
'
c-char
'
|
(1) | ||||||||
u8'
c-char
'
|
(2) | (desde C++17) | |||||||
u'
c-char
'
|
(3) | (desde C++11) | |||||||
U'
c-char
'
|
(4) | (desde C++11) | |||||||
L'
c-char
'
|
(5) | ||||||||
'
c-char-sequence
'
|
(6) | ||||||||
L'
c-char-sequence
'
|
(7) | (hasta C++23) | |||||||
| c-char | - |
ya sea
|
| basic-c-char | - | Un carácter del basic source character set (until C++23) translation character set (since C++23) , excepto la comilla simple ' , la barra invertida \ , o el carácter de nueva línea |
| c-char-sequence | - | dos o más c-char s |
Explicación
Caracteres no codificables
|
7)
Si algún
c-char
en la
c-char-sequence
no puede ser codificado como una única unidad de código en la
codificación de literal ancho
, el programa está mal formado.
|
(until C++23) |
Secuencias de escape numéricas
Las secuencias de escape numéricas (octales y hexadecimales) pueden utilizarse para especificar el valor del carácter.
|
Si el literal de carácter contiene solo una secuencia de escape numérica, y el valor especificado por la secuencia de escape es representable por la versión sin signo de su tipo, el literal de carácter tiene el mismo valor que el valor especificado (posiblemente después de la conversión al tipo carácter). Un literal de carácter UTF- N puede tener cualquier valor representable por su tipo. Si el valor no corresponde a un punto de código Unicode válido, o si su punto de código correspondiente no es representable como una única unidad de código en UTF- N , aún puede especificarse mediante una secuencia de escape numérica con el valor. Por ejemplo, u8 ' \xff ' está bien formado y es igual a char8_t ( 0xFF ) . |
(desde C++23) |
|
Si el valor especificado por una secuencia de escape numérica utilizada en un literal de carácter ordinario o ancho no es representable por char o wchar_t respectivamente, el valor del literal de carácter está definido por la implementación. |
(until C++23) |
|
Si el valor especificado por una secuencia de escape numérica utilizada en un literal de carácter ordinario o ancho con un c-char es representable por la versión sin signo del tipo subyacente de char o wchar_t respectivamente, el valor del literal es el valor entero de ese tipo entero sin signo y el valor especificado convertido al tipo del literal. De lo contrario, el programa está mal formado. |
(since C++23) |
|
Si el valor especificado por una secuencia de escape numérica utilizada en un literal de carácter UTF-
N
no es representable por el correspondiente
|
(desde C++11) |
Notas
Los literales multicarácter fueron heredados por C desde el lenguaje de programación B. Aunque no están especificados por el estándar de C o C++, la mayoría de los compiladores (MSVC es una excepción notable) implementan los literales multicarácter como se especifica en B: los valores de cada char en el literal inicializan bytes sucesivos del entero resultante, en orden big-endian rellenado con ceros y ajustado a la derecha, por ejemplo el valor de ' \1 ' es 0x00000001 y el valor de ' \1 \2 \3 \4 ' es 0x01020304 .
En C, las constantes de carácter como 'a' o ' \n ' tienen tipo int , en lugar de char .
Ejemplo
#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("Literal de caracteres ordinarios:"); char c1 = 'a'; dump("'a'", c1); char c2 = '\x2a'; dump("'*'", c2); print("\n" "Literales de caracteres múltiples ordinarios:"); int mc1 = 'ab'; dump("'ab'", mc1); // definido por la implementación int mc2 = 'abc'; dump("'abc'", mc2); // definido por la implementación print("\n" "Literales de caracteres UTF-8:"); char8_t C1 = u8'a'; dump("u8'a'", C1); // char8_t C2 = u8'¢'; dump("u8'¢'", C2); // error: ¢ se mapea a dos unidades de código UTF-8 // char8_t C3 = u8'猫'; dump("u8'猫'", C3); // error: 猫 se mapea a tres unidades de código UTF-8 // char8_t C4 = u8'🍌'; dump("u8'🍌'", C4); // error: 🍌 se mapea a cuatro unidades de código UTF-8 print("\n" "Literales de caracteres 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); // error: 🍌 se mapea a dos unidades de código UTF-16 print("\n" "Literales de caracteres 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" "Literales de caracteres anchos:"); 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); // no soportado en Windows desde C++23 }
Salida posible:
Literal de caracteres ordinarios: 'a' 61 '*' 2A Literales de caracteres múltiples ordinarios: 'ab' 62 61 00 00 'abc' 63 62 61 00 Literales de caracteres UTF-8: u8'a' 61 Literales de caracteres UTF-16: u'a' 61 00 u'¢' A2 00 u'猫' 2B 73 Literales de caracteres UTF-32: U'a' 61 00 00 00 U'¢' A2 00 00 00 U'猫' 2B 73 00 00 U'🍌' 4C F3 01 00 Literales de caracteres anchos: L'a' 61 00 00 00 L'¢' A2 00 00 00 L'猫' 2B 73 00 00 L'🍌' 4C F3 01 00
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 912 | C++98 | el literal de carácter ordinario no codificable no estaba especificado | especificado como condicionalmente soportado |
| CWG 1024 | C++98 | se requería soportar el literal multicarácter | hecho condicionalmente soportado |
| CWG 1656 | C++98 |
el significado de la secuencia de escape numérica
en un literal de carácter no estaba claro |
especificado |
| P1854R4 | C++98 | los literales de carácter no codificables eran condicionalmente soportados | el programa está mal formado |
Referencias
- Estándar C++23 (ISO/IEC 14882:2024):
-
- 5.13.3 Literales de caracteres [lex.ccon]
- Estándar C++20 (ISO/IEC 14882:2020):
-
- 5.13.3 Literales de caracteres [lex.ccon]
- Estándar C++17 (ISO/IEC 14882:2017):
-
- 5.13.3 Literales de caracteres [lex.ccon]
- Estándar C++14 (ISO/IEC 14882:2014):
-
- 2.14.3 Literales de caracteres [lex.ccon]
- Estándar C++11 (ISO/IEC 14882:2011):
-
- 2.14.3 Literales de caracteres [lex.ccon]
- Estándar C++03 (ISO/IEC 14882:2003):
-
- 2.13.2 Literales de caracteres [lex.ccon]
- Estándar C++98 (ISO/IEC 14882:1998):
-
- 2.13.2 Literales de caracteres [lex.ccon]
Véase también
| literales definidos por el usuario (C++11) | literales con sufijo definido por el usuario |
|
Documentación de C
para
Constante de carácter
|
|