2011-02-17 13 views
8

La pregunta es clara.¿Por qué Qt utiliza un tipo de entero con signo para sus clases de contenedor?

Me pregunto por qué incluso pensaron que sería útil, ya que los indecisos claramente negativos son inutilizables en los contenedores que se usarían con ellos (ver por ejemplo QList's docs).

Pensé que querían permitir eso por algún tipo de indexación loca, pero parece no ser compatible?

También genera una tonelada de advertencias (correctas) del compilador sobre la fundición y la comparación de tipos firmados/sin firmar (en MSVC).

Sólo parece incompatible con la STL por diseño, por alguna razón ...

Respuesta

4

Debido a que, de manera realista, normalmente se desea realizar operaciones aritméticas en los índices, lo que significa que es posible que desee crear temporales que son negativas. Esto es claramente doloroso cuando el tipo de indexación subyacente no está firmado.

El único momento apropiado para usar números sin signo es con la aritmética del módulo. Usando "sin salirse" como algún tipo de especificador de contrato "un número en el rango [0 ..." es simplemente torpe, y demasiado grosero para ser útil.

Considera: ¿Qué tipo debo usar para representar la idea de que el número debe ser un entero positivo entre 1 y 10? ¿Por qué es 0 ... 2^x un rango más especial?

+2

"solo" es un especificador bastante fuerte, allí. – Sapph

+0

El caso especial es una matriz de caracteres [firmados/sin firmar]. En cuyo caso la aritmética del módulo arroja el mismo resultado en las plataformas de representación de complemento de dos –

+1

Estoy de acuerdo con el punto más general, sin embargo, en que los tipos sin firmar están sobrevalorados en su función comúnmente utilizada como documentación. –

8

Aunque soy profundamente comprensivo con la línea de razonamiento de Chris, no estaré de acuerdo aquí (al menos en parte, estoy jugando al abogado del diablo). No hay nada de malo en utilizar tipos sin signo para tamaños, e incluso puede ser beneficioso en algunas circunstancias.

La justificación de Chris para los tipos de tamaño con signo es que se utilizan naturalmente como índices de matriz, y es posible que desee hacer aritmética en índices de matriz, y esa aritmética puede crear valores temporales que son negativos.

Eso está bien, y la aritmética sin signo no presenta ningún problema al hacerlo, siempre y cuando se asegure de interpretar sus valores correctamente cuando haga comparaciones. Debido a que el comportamiento de desbordamiento de los enteros sin signo está completamente especificado, los desbordamientos temporales en el rango negativo (o en grandes números positivos) no introducen ningún error, siempre que se corrijan antes de realizar una comparación.

A veces, el comportamiento de desbordamiento es incluso deseable, ya que el comportamiento de desbordamiento de la aritmética sin signo hace que ciertas comprobaciones de rango sean expresables como una sola comparación que requeriría dos comparaciones en caso contrario. Si quiero comprobar si x está en el rango [a,b] y todos los valores son sin firmar, simplemente puedo hacer:

if (x - a < b) { 
} 

que no funciona con variables firmados; tales verificaciones de rango son bastante comunes con tamaños y compensaciones de matriz.

Mencioné antes que una ventaja es que la aritmética de desbordamiento tiene resultados definidos. Si su aritmética de índice se desborda de un tipo firmado, el comportamiento es la implementación definida; no hay forma de hacer que tu programa sea portátil. Use un tipo sin signo y este problema desaparece. Es cierto que esto solo se aplica a enormes compensaciones, pero es una preocupación para algunos usos.

Básicamente, las objeciones a los tipos sin firmar son frecuentemente exageradas.El problema real es que la mayoría de los programadores no piensan realmente en la semántica exacta del código que escriben, y para pequeños valores enteros, los tipos firmados se comportan más en línea con su intuición. Sin embargo, el tamaño de los datos crece bastante rápido. Cuando tratamos con buffers o bases de datos, con frecuencia nos salimos del rango de "pequeño", y el desbordamiento firmado es mucho más problemático de manejar correctamente que el desbordamiento sin signo. La solución no es "no use tipos sin firmar", es "pensar cuidadosamente sobre el código que está escribiendo y asegúrese de entenderlo".

+0

Me gusta mucho el estilo de control de subdesbordamiento lento posible con índices sin firmar. –

+0

+1 if (x - a user763305

Cuestiones relacionadas