significan - ¿Por qué no se eligió el carácter de espacio para los separadores de 14 dígitos de C++?
separador de miles en excel (7)
De wiki , tenemos un buen ejemplo:
auto floating_point_literal = 0.000''015''3;
Aquí tenemos el .
operador y luego, si se cumple otro operador, mis ojos esperarán algo visible, como una coma o algo, no un espacio en blanco.
Así que un apóstrofe hace mucho mejor aquí que un espacio en blanco lo haría.
Con espacios en blanco sería
auto floating_point_literal = 0.000 015 3;
que no se siente tan bien como el caso con los apóstrofes.
En el mismo espíritu de la respuesta de Albert Renshaw , creo que el apóstrofe es más claro que el espacio que proponen las razas de la claridad en la órbita.
type a = 1''000''000''000''000''000''544''445''555;
type a = 1 000 000 000 000 000 544 445 555;
El espacio se usa para muchas cosas, como las cadenas de concatenación que menciona el OP, a diferencia del apóstrofe, que en este caso deja en claro para alguien que se utiliza para separar los dígitos.
Cuando las líneas de código se vuelven muchas, creo que esto mejorará la legibilidad, pero dudo que esa sea la razón por la que lo eligen.
Sobre los espacios, podría valer la pena echar un vistazo a esta question C, que dice:
El lenguaje no permite int i = 10 000;
(un literal entero es un token, el espacio en blanco intermedio se divide en dos tokens) pero generalmente no se incurre en gastos al expresar el inicializador como una expresión que es un cálculo de literales:
int i = 10 * 1000; /* ten thousand */
A partir de C ++ 14, gracias a n3781 (que en sí no responde a esta pregunta) podemos escribir código como el siguiente:
const int x = 1''234; // one thousand two hundred and thirty four
El objetivo es mejorar en código como este:
const int y = 100000000;
y hacerlo más legible.
El carácter de subrayado ( _
) ya fue tomado en C ++ 11 por literales definidos por el usuario, y la coma ( ,
) tiene problemas de localización. Muchos países europeos usan esto † como separador decimal, y tienen conflictos con el operador de la coma. Me pregunto qué código del mundo real se podría haber roto al permitir, por ejemplo, 1,234,567
.
De todos modos, una mejor solución parece ser el carácter espacial:
const int z = 1 000 000;
Estas señales literales numéricas adyacentes podrían ser concatenadas por el preprocesador al igual que los literales de cadena:
const char x[5] = "a" "bc" "d";
En su lugar, obtenemos el apóstrofe ( ''
), que no es utilizado por ningún sistema de escritura que yo sepa como un separador de dígitos.
¿Hay alguna razón por la que se eligió el apóstrofe en lugar de un simple espacio?
† Es desconcertante porque todos esos idiomas, dentro del texto, mantienen la noción de que una coma "separa" una oración atómica, con un punto que funciona para "terminar" la oración. Para mí, al menos, esto es bastante análogo a coma "separando" la parte integral de un número y un punto que "termina" listo para la entrada fraccionaria.
Es cierto que no veo ningún significado práctico para:
if (a == 1 1 1 1 1) ...
por lo tanto, los dígitos podrían combinarse sin ambigüedad real, pero ¿qué pasa con un número hexadecimal?
0 x 1 a B 2 3
No hay forma de desambiguar de un error tipográfico al hacerlo (normalmente deberíamos ver un error)
Hay un artículo anterior, n3499 , que nos dice que aunque Bjarne mismo sugirió espacios como separadores:
Si bien este enfoque es consistente con un estilo tipográfico común, tiene algunos problemas de compatibilidad.
- No coincide con la sintaxis de un número pp , y requeriría de forma mínima la extensión de esa sintaxis.
- Más importante aún, habría cierta ambigüedad sintáctica cuando un dígito hexadecimal en el rango [af] sigue un espacio. El preprocesador no sabría si realizar la sustitución de símbolos comenzando después del espacio.
- Probablemente haría que las herramientas de edición que capturan "palabras" sean menos confiables.
Supongo que el siguiente ejemplo es el principal problema señalado:
const int x = 0x123 a;
aunque en mi opinión este razonamiento es bastante débil. Todavía no puedo pensar en un ejemplo del mundo real para romperlo.
La justificación de las "herramientas de edición" es aún peor, ya que 1''234
rompe básicamente todos los resaltadores de sintaxis conocidos por la humanidad (por ejemplo, el utilizado por Markdown en la pregunta anterior) y hace que las versiones actualizadas de dichos resaltadores sean mucho más difíciles de implementar.
Aún así, para bien o para mal, esta es la razón que llevó a la adopción de apóstrofes en su lugar.
La razón obvia para no usar espacios en blanco es que una nueva línea también es espacio en blanco, y que C ++ trata a todos los espacios en blanco de manera idéntica. Y, por otro lado, no conozco ningún idioma que acepte espacios en blanco arbitrarios como separador.
Presumiblemente, se podría usar Unicode 0xA0 (espacio sin interrupciones), es la solución más utilizada al tipear. Sin embargo, veo dos problemas con eso: primero, no está en el conjunto de caracteres básico, y segundo, no es distintivo visualmente; no puede ver que no es un espacio solo mirando el texto en un editor normal.
Más allá de eso, no hay muchas opciones. No puede usar la coma, ya que ya es un token legal (y algo así como 1,234
es actualmente C ++ legal, con el significado 234). Y en un contexto donde podría ocurrir en un código legal, por ejemplo, a[1,234]
. Si bien no puedo imaginar ningún código real que realmente use esto, hay una regla básica de que ningún programa legal, independientemente de lo absurdo, debe cambiar la semántica en silencio.
Consideraciones similares significan que _
tampoco se puede usar; si hay un #define _234 * 2
, entonces a[1_234]
cambiaría silenciosamente el significado del código.
No puedo decir que estoy particularmente satisfecho con la elección de ''
, pero tiene la ventaja de ser utilizado en Europa continental, al menos en algunos tipos de textos. (Me parece recordar haberlo visto en alemán, por ejemplo, aunque en el texto de ejecución típico, el alemán, como la mayoría de los otros idiomas, usará un punto o un espacio sin interrupciones. Pero tal vez fue el alemán suizo). El problema con ''
es análisis La secuencia ''1''
ya es legal, como lo es ''123''
. Entonces, algo como 1''234
podría ser un 1
, seguido del comienzo de una constante de carácter; No estoy seguro de qué tan lejos tiene que mirar hacia adelante para tomar la decisión. No hay una secuencia de C ++ legal en la que una constante integral pueda ser seguida por una constante de carácter, por lo que no hay problema con romper el código legal, pero esto significa que la exploración léxica de repente se vuelve muy dependiente del contexto.
(Con respecto a su comentario: no hay lógica en la elección de un separador de decimales o de miles. Un separador de decimales, por ejemplo, ciertamente no es una parada completa. Son solo convenciones arbitrarias).
Supongo que es porque, mientras escribe el código, si llega al final de una "línea" (el ancho de su pantalla) se produce un salto de línea automático (o "ajuste de palabra"). Esto causaría que su int se dividiera por la mitad, la mitad de ella estaría en la primera línea, la segunda mitad en la segunda ... de esta manera, todo permanecerá unido en el caso de un word-wrap
.
Tiene que ver con cómo se analiza el lenguaje. Habría sido difícil para los autores del compilador volver a escribir sus productos para aceptar literales delimitados por espacios.
Además, no creo que separar dígitos con espacios sea muy común. Como he visto, siempre hay caracteres que no son espacios en blanco, incluso en diferentes países.
float floating_point_literal = 0.0000153; /* C, C++*/
auto floating_point_literal = 0.0000153; // C++11
auto floating_point_literal = 0.000''015''3; // C++14
El comentar no duele:
/* 0. 0000 1530 */
float floating_point_literal = 0.00001530;
Las cadenas binarias pueden ser difíciles de analizar:
long bytecode = 0b1111011010011001; /* gcc , clang */
long bytecode = 0b1111''0110''1001''1001; //C++14
// 0b 1111 0110 1001 1001 would be better, really.
// It is how humans think.
Una macro para consideración:
#define B(W,X,Y,Z) (0b##W##X##Y##Z)
#define HEX(W,X,Y,Z) (0x##W##X##Y##Z)
#define OCT(O) (0##O)
long z = B(1001, 1001, 1020, 1032 );
// result : long z = (0b1001100110201032);
long h = OCT( 35);
// result : long h = (035); // 35_oct => 29_dec
long h = HEX( FF, A6, 3B, D0 );
// result : long h = (0xFFA6BD0);