2009-10-22 15 views
7

En el siguiente código, ¿cuál es el beneficio de usar (!!p) en lugar de (p != NULL)?Por qué/cuándo usar (!! p) en lugar de (p! = NULO)

AClass *p = getInstanceOfAClass(); 
if(!!p) 
    // do something 
else 
    // do something without having valid pointer 
+22

Me pregunto qué pasa con solo 'if (p)'. – GManNickG

+1

Absolutamente nada. :) – Twisol

+3

Siempre debe sospechar que los operadores están sobrecargados. Es posible '! P' o'! = 'Tener comportamientos especiales. – Kobi

Respuesta

9

Eso es una cuestión de estilo, de hecho, son equivalentes. Vea this very similar question para la discusión.

Comparación de la IMO con el puntero nulo es más claro.

3

Por lo que puedo ver, es solo una forma más corta de convertirlo en un valor booleano. Aplica el! dos veces, sin embargo, mientras que p != NULL hace una comparación. Así que supongo que el beneficio es un código más corto, aunque más críptico si no sabes lo que se supone que significa !!p.

11

Es más o menos lo mismo, aunque considero que el !!p es un mal estilo, y generalmente indica un codificador que intenta ser inteligente.

+4

Si le tomó una hora escribir el código inteligente, les tomará dos entenderlo luego de algunas semanas. – Twisol

+2

Estoy totalmente de acuerdo. Debería haber leído "tratando de ser inteligente y fallar" – Wernsey

0

Ellos son los mismos, pero se recomienda utilizar el

NULL != p 

Es más fácil de leer.

+0

Eso no es más que preferencias personales y estilo. –

+4

La legibilidad de esto es discutible. Personalmente, me parece * menos * legible, simplemente porque no se lee de forma natural. Normalmente digo 'si p no es NULL' no 'si NULL no es p'. –

+3

Sí, pero evita que las personas pierdan un "p = NULL" erróneo, ya que el compilador recogería "NULL = p". – ChrisBD

-2

Do !! NO use doble negación. Un argumento simple es que, dado que C++ es un subconjunto limitado de inglés y el inglés simplemente no tiene una doble negación, los hablantes de inglés tendrán muchas dificultades para analizar lo que está sucediendo.

+1

Veo lo que hizo allí ... – Twisol

+0

Excepto si también tomó clases de latín, entonces la doble negación, dependiendo del contexto, no se cancela, pero el significado de la negación se amplifica. – MP24

+2

¡Excepto eso! (C++ es un subconjunto limitado de inglés). – outis

-1

No hay diferencia en el ejemplo dado.

Sin embargo, la suposición de que esto se aplica a todos los casos es incorrecta. a = not not b no es lo mismo que a = b, en lo que respecta a los tipos enteros.

En C, 0 es falso. Cualquier cosa menos 0 es cierto. Pero not 0 es 1, y nada más. En C++, la verdadera arroja a 1 como un entero, no sólo para compatibilty hacia atrás con C, sino porque 1 no es 0, y 1 es el valor más común usado para denotar cierto en tipos C bool, incluyendo el official C bool type, y BOOL utilizarse en Win32.

Mientras que para el ejemplo de código dado, !!p es innecesaria ya que el resultado es arrojado a un bool para la evaluación de la condición if, que no descarta el uso de !! para fines de fundición booleanos a valores enteros esperados. Personalmente en este ejemplo, para maximizar la probabilidad de que el tipo cambie y la semántica esté clara, usaría NULL != p o p != NULL para dejar absolutamente claro lo que significa.

Esta técnica se conoce como la expresión de doble explosión, y this guy provides some good justifications.

+0

Esas justificaciones no son válidas en esta instancia. –

+0

En realidad, en este contexto si (p) y si (!! p) * son * idénticos. Esto se debe a que la condición de 'si' se convierte en bool y se prueba, ¡que es exactamente lo que es! termina haciendo. Con respecto a la respuesta vinculada, en C++ los chicos del kernel podrían haber arrojado su valor a un bool. –

+0

"Mientras que para el código de ejemplo dado, !! p obviamente no es necesario," quizás debería aclarar esto. –

7

I cosa comentario original del GMan debe ser la respuesta aceptada:

Me pregunto lo que está mal con sólo if (p)

El punto es: nada está mal con él, y esto debe sea la forma preferida. En primer lugar, !!p es "demasiado inteligente"; también es completamente innecesario y, por lo tanto, malo (aviso: estamos hablando de apuntadores en una declaración if aquí, por lo que el comentario de Anacrolix, aunque es válido en general, no se aplica aquí).

Lo mismo ocurre con p != NULL. Si bien esto es posible, simplemente no es necesario. Es más código, es completamente código redundante y, por lo tanto, empeora el código. Lo más sincero que dijo Jeff Atwood fue que "el mejor código no es código en absoluto". Evite la sintaxis redundante. Atenerse al mínimo (que todavía transmite el significado completo; if (p)es completo).

Finalmente, if (p) es posiblemente la forma más idiomática de escribir esto en C++. C++ hace lo imposible para obtener este mismo comportamiento para otros tipos en el lenguaje (por ejemplo, flujos de datos), a costa de algunos caprichos extraños. La próxima versión de la norma incluso introduce una nueva sintaxis para lograr este comportamiento en los tipos definidos por el usuario.

Para los punteros, obtenemos lo mismo de forma gratuita. Entonces úsalo.

/EDIT: Acerca de la claridad: sharptooth escribe que

OMI comparando contra el puntero nulo es más clara.

Yo afirmo que esto es objetivamente incorrecto: if (p) es más claro. No hay forma posible de que esta declaración pueda significar algo más, ni en este contexto ni en ningún otro, en C++.

+0

Sigo esto. si (p) lo hace todo, ¿es corto, claro?(Y algunos también pueden llamar al beneficio adicional de no usar 'NULL', ya que prefieren '0') – stijn

+2

Prefiero reservar if (x) para tipos booleanos, y si (x! = Nullptr/* o NULL * /) para tipos de puntero. De esta manera, las comprobaciones de su puntero se destacan en el código y son fáciles de buscar. – Bill

+0

"No hay forma posible de que esta declaración pueda significar algo más" - Tampoco hay manera posible de que (p! = NULL) signifique nada, pero p no es igual a NULL, cualquiera que sea NULL. –