que ejecutar compilar c++ c++11 auto

c++ - ejecutar - que es compilar



¿Cómo se puede distinguir automáticamente entre corto y largo en tiempo de compilación? (6)

El tipo para foo podría ser razonablemente int o incluso sin signo.

Podría ser muchas cosas, pero en realidad es una sola cosa.

El literal entero 12 tiene tipo int .

Período.

Pero supongamos que más adelante en mi programa, hago algunos cálculos y asigno a foo un valor de 4 mil millones. En ese momento, me gustaría que foo tuviera el tipo unsigned int o quizás long. ¿Cómo pueden los compiladores anticipar los valores que se asignarán más adelante en el programa?

No pueden, y no lo hacen. El tipo de foo no cambiará. foo no tiene tipo auto (no existe tal cosa); tiene tipo int . Su programa a partir de ahora será como si hubiera escrito int foo = 12; . La deducción / automatización termina ahí.

Estoy emocionado de usar variables auto en mis programas de C ++. Conozco las variables declaradas con reglas de plantilla de uso auto para deducir tipos de variables, pero estoy confundido en cuanto a cómo funciona para los tipos numéricos. Supongamos que tengo:

auto foo = 12;

El tipo para foo podría ser razonablemente int o incluso unsigned char . Pero supongamos que más adelante en mi programa hago algunos cálculos y asigno a foo un valor de 4 billones. En ese momento, me gustaría que foo convierta en tipo unsigned int o quizás long .

¿Cómo pueden los compiladores anticipar los valores que se asignarán más adelante en el programa?


En ese momento, me gustaría que foo tuviera el tipo unsigned int o quizás long .

No es así como funciona el lenguaje. Una variable no puede tener su tipo cambiado en tiempo de ejecución. Si define e inicializa una variable como auto foo = 12; , eso significa exactamente lo mismo que int foo = 12; , independientemente de cualquier asignación futura, porque el tipo de 12 es int .

¿Cómo pueden los compiladores anticipar los valores que se asignarán más adelante en el programa?

Ellos no tienen que hacerlo. Los valores que se asignan más tarde se convertirán al tipo de la variable. Si el valor está fuera del rango para ese tipo, las reglas exactas dependen de los tipos con los que está tratando.


El compilador trabaja con la información presente, que en su caso es el literal 12 entero. Así se deduce que foo es de tipo int . No anticipa nada. Puede usar el sufijo literal de enteros apropiado:

auto foo = 12ul;

forzar el foo para ser deducido como unsigned long . No puede definir que la variable sea del tipo int y luego, en la línea posterior, espere que el compilador la cambie a otro tipo simplemente porque le asignó un valor diferente que no se ajustará al tipo utilizado anteriormente. Si lo hiciera, simplemente se produciría un desbordamiento de enteros que es un comportamiento indefinido.

Para obtener más información sobre el tema, consulte el especificador automático y la referencia de deducción de tipo automático .


Mi consejo es que este no es un buen lugar para usar el auto . Usted sabe qué factores determinan el tipo que necesita y no se pueden deducir del contexto inmediato. (Sin embargo, si puede escribir sus variables como asignaciones estáticas únicas, eso nunca sucederá).

Si sabe que la variable debe ser capaz de mantener un valor de al menos 4 mil millones, declararla como long long int unsigned long o long long int unsigned long . O bien, si realmente desea codificar defensivamente contra opciones desafortunadas para el ancho de esos tipos (como plataformas con 32 bits de long para admitir código heredado, pero el tamaño de la palabra nativa es de 64 bits), declare como uint_fast32_t o int_fast64_t . O si quieres el más pequeño, no el más rápido, uint_least32_t . (A veces, ¡el código más rápido es el que mantiene la mayoría de los valores en el caché!)

Si lo que realmente desea es el tipo más rápido con o sin signo que puede contener un valor de 4 mil millones, diga lo que quiere decir.


Personalmente, no usaría auto para estas constantes inmediatas, pero cuando el valor proviene de otra llamada de método o se asigna de otra variable.

Si desea una manera de definir una variable para que coincida con el tipo de otra variable, de modo que pueda interactuar con ella, pero desea asignar un valor constante, entonces use decltype para asegurarse de que su tamaño sea compatible:

decltype(otherVar) myVar = 1234; myVar += otherVar; // will work just as well as otherVar += myVar

En cualquier caso, el tipo está especificado por la constante literal, y un 12 no decorado definirá un int.

Sin embargo, puedes decorar tu constante con U, para que no esté firmado, o L para que sea larga, o incluso LL para que sea súper larga. ¡No hay equivalente para forzarlo corto o char, desafortunadamente!


"El tipo para foo podría ser razonablemente int o incluso sin signo"

No, no puede. Cada expresión en C ++ tiene un tipo, y eso está claramente definido en el lenguaje. En su caso, la expresión es un literal entero, por lo que el tipo corresponde al literal. Qué tipo es específicamente, está definido por las reglas :

El tipo del literal.

El tipo del literal entero es el primer tipo en el que puede caber el valor, de la lista de tipos que depende de qué base numérica y qué sufijo entero se usó.

sin sufijo - int, long int, long long int (desde C ++ 11)

"¿Cómo pueden los compiladores anticipar los valores que se asignarán más adelante en el programa?"

No puede. El tipo se determina cuando se declara la variable y no se puede cambiar más adelante.