Namespaces
Variants

Character literal

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

1) Literal de carácter ordinario, por ejemplo 'a' o ' \n ' o ' \13 ' . Tal literal tiene tipo char y el valor igual a la representación de c-char en el juego de caracteres de ejecución (hasta C++23) el punto de código correspondiente de la codificación de literal ordinaria (desde C++23) .
2) Literal de carácter UTF-8, por ejemplo u8 'a' . Tal literal tiene tipo char (hasta C++20) char8_t (desde C++20) y el valor igual al valor del punto de código de ISO/IEC 10646 de c-char , siempre que el valor del punto de código sea representable con una única unidad de código UTF-8 (es decir, c-char está en el rango 0x0-0x7F, inclusive).
3) Literal de carácter UTF-16, por ejemplo u '猫' , pero no u '🍌' ( u ' \U0001f34c ' ). Dicho literal tiene tipo char16_t y el valor igual al valor del punto de código ISO/IEC 10646 de c-char , siempre que el valor del punto de código sea representable con una única unidad de código UTF-16 (es decir, c-char está en el rango 0x0-0xFFFF, inclusive).
4) Literal de carácter UTF-32, por ejemplo U '猫' o U '🍌' . Dicho literal tiene tipo char32_t y el valor igual al ISO/IEC 10646 valor del punto de código de c-char .
5) Literal de carácter ancho, por ejemplo L 'β' o L '猫' . Dicho literal tiene tipo wchar_t y el valor igual a el valor de c-char en el conjunto de caracteres anchos de ejecución (hasta C++23) el punto de código correspondiente de la codificación literal ancha (desde C++23) .
6) Literal multicarácter ordinario (hasta C++23) Literal multicarácter (desde C++23) , por ejemplo 'AB' , es condicionalmente soportado, tiene tipo int y valor definido por la implementación.
7) El literal multicarácter ancho, por ejemplo L 'AB' , es soportado condicionalmente, tiene tipo wchar_t y valor definido por la implementación.

Caracteres no codificables

1-5) Dado que c-char no es una secuencia de escape numérica (ver abajo), si c-char no es representable en la codificación de caracteres asociada al literal o no puede codificarse como una única unidad de código en dicha codificación (por ejemplo, un valor no-BMP en Windows donde wchar_t es de 16 bits), el programa está mal formado.
6) Si algún c-char en la c-char-sequence no puede codificarse como una única unidad de código en la codificación literal ordinaria , el programa está mal formado.
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 char N _t , el valor del literal de carácter está definido por la implementación (hasta C++17) el programa está mal formado (desde C++17) .

(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