2011-05-31 17 views
5
sin firmar

¿es correcto hacer esto?fundición firmada al

typedef unsigned int Index; 

enum 
{ 
    InvalidIndex = (Index) -1 
}; 

He leído que no es seguro en todas las plataformas, pero he visto esto en tantos códigos "profesionales" ...

+1

Me gustaría que dejaras de escribir "Hola" al comienzo de cada pregunta ... –

Respuesta

6

Lo que leyó probablemente fue por Miedo, Incertidumbre y Duda. El autor de lo que sea que hayas leído probablemente pensó que (unsigned)-1 estaba desbordado y podría causar caos en los sistemas donde la representación de bit no da UINT_MAX para tu problema.

Sin embargo, el autor está equivocado, porque la norma garantiza que los valores sin signo se envuelvan cuando alcanzan el límite de su rango. No importa qué representaciones de bit estén involucradas, (unsigned)-1esstd::numeric_limits<unsigned>::max(). Período.

No estoy seguro de qué beneficio hay aquí. Obtendrás ese gran valor máximo ... Si eso está bien, creo que estás listo para ir.

+1

Puede que no sepa el tipo subyacente de 'enum', pero sabe que podrá contener el valor de cualquiera de las constantes enum, o obtendrá un error de tiempo de compilación. 'UINT_MAX' es un valor, y ese es el único valor legal que puede tener la constante enum. –

+0

@JamesKanze: Eso, James, es un punto razonablemente bueno. :) –

0

No estoy seguro si esto es la aplicación definida, pero la fundición -1 (que obviamente está firmado) a un entero sin signo causa un subdesbordamiento, que generalmente conduce a valores extremadamente grandes (es decir, INT_MAX).

+2

Ese es normalmente el intento al codificar algo como esto –

+0

No es realmente un flujo inferior, ya que los valores sin signo se definen para envolver. –

4

Si quieres obtener UINT_MAX, estoy bastante seguro de que es la mejor manera de hacerlo. La conversión de -1 a unsigned garantiza la obtención de UINT_MAX. Se explica en los comentarios.

+2

'UINT_MAX'. Y está garantizado pero * no * debido a la representación firmada bit a bit. Está garantizado porque el lanzamiento a un tipo sin signo realiza la aritmética del módulo. Sucede que con la representación de complemento de 2 esto deja el patrón de bits sin cambios, pero en el complemento de 1s y magnitud de signo cambia el patrón de bits, y se garantiza que el reparto hará ese trabajo. –

+0

Querías decir 'INT_MAX', y es' UINT_MAX' lo que aquí es relevante. Y no por bits, sino porque el estándar dice que los valores sin signo se envuelven. Luego, al convertir a 'signed' nuevamente para usar en la enumeración (_if_ el tipo subyacente está firmado), obtiene -1 de nuevo. –

+0

Corregido, gracias a los dos. – slezica

2

No es seguro porque lo que es una enumeración no está claramente definido.

Consulte Are C++ enums signed or unsigned? para obtener más información al respecto.

Al final del día, lo que ha escrito parece que terminaría siendo (int) (unsigned int) (int) en la traducción, por lo que no estoy seguro de lo que está tratando de lograr.

+0

Es perfectamente seguro, porque el valor de la expresión está perfectamente definido, y ese valor puede representarse en la enumeración o es un error. –