2011-01-10 15 views
32

probablemente esté familiarizado con el esquema enum máscara de bits, como:if (máscara y VALOR) o si ((máscara y VALOR) == VALOR)?

enum Flags { 
    FLAG1 = 0x1, 
    FLAG2 = 0x2, 
    FLAG3 = 0x4, 
    FLAG4 = 0x8, 

    NO_FLAGS = 0, 
    ALL_FLAGS = FLAG1 | FLAG2 | FLAG3 | FLAG4 
}; 

f(FLAG2 | FLAG4); 

he visto una gran cantidad de código que luego pruebas para un determinado bit de la máscara como

if ((mask & FLAG3) == FLAG3) 

Pero ISN ¿Es eso equivalente a esto?

if (mask & FLAG3) 

¿Hay alguna razón para usar la primera versión? En mi opinión, la segunda versión más corta es más legible.

¿Quizás los hábitos residuales de los programadores de C que piensan que los valores verdaderos deben convertirse a 1? (Aunque incluso allí, la versión más larga tiene más sentido en una asignación o return comunicado que en una prueba de sentencia condicional.)

+5

Ahora hazlo con máscara y ALL_FLAGS. Ya no es lo mismo. –

+4

'==' tiene mayor prioridad que '&', por lo que necesita paréntesis en su condición: 'if ((máscara & FLAG3) == FLAG3)'. – casablanca

Respuesta

75

La construcción if ((mask & FLAG3) == FLAG3) prueba si todos bits en FLAG3 están presentes en la máscara; if (mask & FLAG3) prueba si cualquiera están presentes.

Si sabe que FLAG3 tiene exactamente 1 bit configurado, son equivalentes, pero si potencialmente puede definir condiciones compuestas, puede ser más claro adquirir el hábito de probar explícitamente todos los bits, si eso es lo que quiere decir.

2

Cuando se trata de un bitset, así que hay que comparar un solo poco , es está bien tener if(mask & value).

Pero, supongamos que tiene una dirección IP almacenada en la hormiga int32 y desea saber si es 192.168.*, entonces usted tendrá que hacer:

if((ip & 0xFFFF0000) == 0xC0A80000) // assuming some endianness representation. 
1

if toma un valor lógico (bool). La primera expresión es directamente del tipo bool, mientras que la última es un valor numérico que se convertirá implícitamente en bool.

1

Su condición será verdadera si el resultado es distinto de cero. En su ejemplo, el resultado de ambas operaciones sería equivalente, y la segunda opción podría ser incluso más rápida porque algunas CPU pueden probar cero más fácilmente que otros números arbitrarios, PERO:

Obviamente, no puede hacer la segunda opción si el valor que está buscando consta de más de un bit. En ese caso, debes usar la primera opción. Eso obviamente también se aplica si estás buscando varios bits al mismo tiempo.

2

Incluso para el valor de un bit donde estas declaraciones son realmente equivalentes, siempre estoy a favor de la comparación explícita.

  1. Hace la intención más clara. Realmente somos interesados ​​en comparar banderas. (x & Flag) == Flag es un patrón establecido y puedo procesarlo y reconocerlo en un abrir y cerrar de ojos.

  2. Normalmente prefiero las conversiones explícitas a las implícitas. Hago una excepción para los estados de falla (p.Escribo if (file) en lugar de if (file.good())), pero cuando trabajo con números, 0 no es un "estado fallido", es un número como cualquier otro. No me gusta tratarlo de manera diferente en un contexto booleano.

+0

Su código en el punto (1) es incorrecto. Debido a la precedencia del operador en C y C++, necesita agregar paréntesis para obtener el efecto deseado. Un gotcha común. – ChrisN