visual tutorial studio descargar c++ c visual-studio-2010 gcc

c++ - tutorial - representación de trampa



visual studio c++ descargar (3)

  1. ¿Qué es la representación de trampa en C (algunos ejemplos pueden ayudar)? ¿Esto se aplica a C ++?

    float f=3.5; int *pi = (int*)&f;

  2. Editar: Sé que ''pi'' infringe la regla de aliasing y es UB según el estándar C. Al menos en GCC no produce errores, sino advertencias. En esta implementación (es decir, GCC), asumiendo sizeof(int) == sizeof(float) do f y *pi tienen la misma representación binaria / patrón? ¿Qué hay de MSVC?

  1. Una representación de trampa es un término general utilizado por C99 (IIRC no por C89) para describir patrones de bits que se ajustan al espacio ocupado por un tipo, pero desencadenan un comportamiento indefinido si se utiliza como un valor de ese tipo. La definición se encuentra en la sección 6.2.6.1p5 (con tentáculos en 6.2.6) y no voy a citarla aquí porque es larga y confusa. Se dice que un tipo para el que existen tales patrones de bits "tiene" representaciones de trampas. No se requiere ningún tipo de tipo para tener representaciones de trampas, pero el único tipo que las garantías estándar no tendrán representaciones de trampas es unsigned char (6.2.6.1p5, 6.2.6.2p1).

    El estándar brinda dos ejemplos hipotéticos de representaciones de trampas, ninguna de las cuales corresponde a nada que haya hecho una CPU real durante muchos años, así que no voy a confundirlo con ellas. Un buen ejemplo de una representación de trampa (también es la única que califica como una representación de trampa de nivel de hardware en cualquier CPU que pueda encontrar) es un NaN de señalización en un tipo de coma flotante. El anexo F de C99 (sección 2.1) deja explícitamente el comportamiento de los NaN de señalización indefinidos, aunque IEC 60559 especifica su comportamiento en detalle.

    Vale la pena mencionar que, aunque se permite que los tipos de punteros tengan representaciones de trampas, los punteros nulos no son representaciones de trampas. Los punteros nulos solo causan un comportamiento indefinido si se desreferencian o compensan; otras operaciones en ellos (lo más importante, comparaciones y copias) están bien definidos. Las representaciones de trampa producen un comportamiento indefinido si simplemente las lee utilizando el tipo que tiene la representación de trampa. (Si los punteros no válidos pero no nulos son, o deberían ser, considerados representaciones de trampas es un tema de debate. La CPU no los trata de esa manera, pero el compilador podría).

  2. El código que muestra tiene un comportamiento indefinido, pero esto se debe a las reglas de alias del puntero, no a las representaciones de trampas. Esta es la forma de convertir un float en el int con la misma representación (asumiendo, como dices, sizeof(float) == sizeof(int) )

    int extract_int(float f) { union { int i; float f; } u; u.f = f; return u.i; }

    Este código tiene un comportamiento no especificado (no indefinido) en C99, que básicamente significa que el estándar no define qué valor entero se produce, pero obtienes algún valor entero válido, no es una representación de trampa y el compilador no puede optimizar en el supuesto de que no has hecho esto. (Sección 6.2.6.1, párrafo 7. Mi copia de C99 podría incluir corrigienda técnica; mi recuerdo es que esto no estaba definido en la publicación original, pero se cambió a no especificado en una TC).


Comportamiento no definido para alias un flotante con un puntero-a-int.


En general, cualquier valor de coma flotante IEEE-754 sin captura puede representarse como un entero en algunas plataformas sin ningún problema. Sin embargo, hay valores de punto flotante que pueden dar como resultado un comportamiento inesperado si se supone que todos los valores de punto flotante tienen una representación entera única y que forzará a la FPU a cargar ese valor.

(Ejemplo tomado de http://www.dmh2000.com/cpp/dswap.shtml )

Por ejemplo, cuando se trabaja con datos de FP necesita establecer una matriz entre CPU con endianness diferente, puede pensar en hacer lo siguiente:

double swap(double)

Desafortunadamente, si el compilador carga la entrada en un registro FPU y es una representación de trampa, la FPU puede escribirla de nuevo con una representación de trampa equivalente que resulta ser una representación de bit diferente.

En otras palabras, hay algunos valores FP que no tienen una representación de bit correspondiente si no se convierten correctamente (es decir, a través de una union , memcpy vía char * u otro mecanismo estándar).