traductor tipos significado que programacion interprete fuente ejemplos compiladores compilador codigos codigo basicos c++ c math signed

c++ - tipos - que es un traductor en programacion



¿Verificando que el desplazamiento a la derecha de C/C++ firmado sea aritmético para un compilador en particular? (3)

¡Me parece bien! También puede configurar el compilador para que emita un archivo de ensamblaje (o cargar el programa compilado en el depurador) y ver qué código de operación emite para signed int i; i >> 1; signed int i; i >> 1; , pero eso no es automático como tu solución.

Si alguna vez encuentra un compilador que no implementa el cambio aritmético a la derecha de un número firmado, me gustaría saberlo.

De acuerdo con el estándar C / C ++ (ver este enlace) , el operador >> en C y C ++ no es necesariamente un cambio aritmético para los números con signo. Depende de la implementación del compilador si 0''s (lógico) o el bit de signo (aritmética) se desplazan a medida que los bits se desplazan a la derecha.

¿Funcionará este código para ASERTAR (fallar) en tiempo de compilación para los compiladores que implementan un cambio lógico hacia la derecha para enteros con signo?

#define COMPILE_TIME_ASSERT(EXP) / typedef int CompileTimeAssertType##__LINE__[(EXP) ? 1 : -1] #define RIGHT_SHIFT_IS_ARITHMETIC / ( (((signed int)-1)>>1) == ((signed int)-1) ) // SHR must be arithmetic to use this code COMPILE_TIME_ASSERT( RIGHT_SHIFT_IS_ARITHMETIC );


¿Por qué afirmar? Si el operador de turno de su compilador no se adapta a sus necesidades, puede remediar la situación con gracia extendiendo el resultado. Además, a veces el tiempo de ejecución es lo suficientemente bueno. Después de todo, el optimizador del compilador puede hacer que el tiempo de compilación fuera del tiempo de ejecución:

template <typename Number> inline Number shift_logical_right(Number value, size_t bits) { static const bool shift_is_arithmetic = (Number(-1) >> 1) == Number(-1); const bool negative = value < 0; value >>= bits; if (!shift_is_arithmetic && negative) // sign extend value |= -(Number(1) << (sizeof(Number) * 8 - bits)); }

La static const bool puede evaluarse en el momento de la compilación, por lo que si se garantiza que shift_is_arithmetic sea true , cada compilador que se shift_is_arithmetic eliminará la cláusula if completa y la construcción de la const bool negative como código muerto.

Nota: el código se adapta de la función encode_sleb128 de Mono: here .

Actualizar

Si realmente desea abortar la compilación en máquinas sin cambio aritmético, es mejor que no confíe en el preprocesador. Puedes usar static_assert (o BOOST_STATIC_ASSERT ):

static_assert((Number(-1) >> 1) == Number(-1), "Arithmetic shift unsupported.");


De tus diversos comentarios, hablas acerca del uso de esta plataforma cruzada. Asegúrese de que sus compiladores garanticen que cuando compilan para una plataforma, sus operadores de tiempo de compilación se comportarán igual que los de tiempo de ejecución.

Se puede encontrar un ejemplo de comportamiento diferente con números de punto flotante. ¿Su compilador está haciendo su matemática de expresión constante en precisión simple, doble o extendida si está regresando a int? Como

constexpr int a = 41; constexpr int b = (a / 7.5);

Lo que estoy diciendo es que debe asegurarse de que sus compiladores garanticen el mismo comportamiento durante el tiempo de ejecución que el tiempo de compilación cuando trabaje con tantas arquitecturas diferentes.

Es totalmente posible que un compilador se pueda extender internamente pero no genere los códigos de operación previstos en el destino. La única manera de estar seguro es hacer una prueba en tiempo de ejecución o mirar la salida del ensamblaje.

No es el fin del mundo mirar la salida de ensamblajes ... ¿Cuántas plataformas diferentes hay? Dado que esto es tan crítico para el rendimiento, simplemente haga el "trabajo" de observar 1-3 líneas de salida de ensamblador para 5 arquitecturas diferentes. No es como si tuvieras que sumergirte en una salida de ensamblaje completa (¡generalmente!) Para encontrar tu línea. Es muy, muy fácil de hacer.