45 votos

¿Por qué hay una advertencia rendimiento puntero fundido a bool?

Extiende.

Yo pensaba que era genial cuando yo hice algo como:

bool hasParent()
{
 return this->parentNode ;
}

Incluso con un (bool) de fundición, la advertencia de que aún no desaparece.

Donde esta->parentNode es NULL si no hay ningún nodo padre.

Pero estoy consiguiendo:

advertencia C4800: 'Nodo *' : forzando el valor bool 'true' o 'false' (advertencia de rendimiento)

¿Cuál es el trato, yo? ¿Por qué es que una advertencia de rendimiento? Yo pensaba que iba a ser más eficiente no escribir algo como:


bool hasParent()
{
 if( this->parentNode )
 return true ;
otra cosa
 return false ;
}

Pero la segunda versión no genera advertencias y el compilador parece mucho más feliz. Que es más rápido?

37voto

Michael Burr Puntos 181287

Hay una discusión en Microsoft Connect (http://stackoverflow.com/questions/206564/what-is-the-performance-implication-of-converting-to-bool-in-c). El ejemplo que se da a Microsoft es:

$ cat -n t.cpp && cl -c -W3 -O2 -nologo -Fa t.cpp
1 bool f1 (int i)
2 {
3 return i & 2;
4 }
5
6 bool f2 (int i)
7 {
8 const bool b = i & 2;
9 return b;
10 }
11
12 bool f3 (int i)
13 {
14 const bool b = 0 != (i & 2);
15 return b;
16 }
t.cpp
t.cpp(3) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
t.cpp(8) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

Y la respuesta de Microsoft (desde el desarrollador responsable de la advertencia) es:

Esta advertencia es sorprendentemente útil, y se encontró un error en mi código de ayer. Creo que Martin está tomando "advertencia de rendimiento" fuera de contexto.

No se trata de que el código generado, es acerca de si o no el programador ha señalado la intención de cambiar un valor de tipo int a bool. Hay una pena por que, y el usuario tiene la opción de utilizar los "int" en lugar de "bool" constantemente (o más bien viceversa) para evitar el "boolifying" codegen. La advertencia se suprime en el tercer caso de abajo, porque está claramente manifestado su intención de aceptar la int->bool transición.

Es un viejo refrán, y puede haber sobrevivido a su propósito, pero se está comportando como se concibe aquí

Así que, básicamente, el MS desarrollador parece estar diciendo que si quieres 'echar' un int a bool usted debería más bien hacerlo mediante el uso de "return this->parentNode != 0" en lugar de un implícito o explícito emitidos.

Personalmente, me interesaría saber más acerca de qué tipo de bichos, la advertencia descubre. Me gustaría pensar que esta advertencia no tiene un montón de valor.

21voto

James McNellis Puntos 193607

El hecho de que la conversión de a bool no hacer la advertencia desaparece es por diseño:

La fundición de la expresión de tipo bool no desactivar la advertencia, que es por diseño.

Yo recomendaría el enfoque que el MSDN descripción de advertencia C4800 recomienda:

return this->parentNode != NULL;

esto deja en claro que están regresando true si parentNode no es un puntero nulo y false si parentNode es un puntero null.

6voto

hirschhornsalz Puntos 16306

El compilador necesita generar código adicional para convertir un puntero a int. Básicamente es una comparación contra cero y estableciendo el resultado a uno si no cero.

00000000004005e0 <_Z4testPv>:
bool test(void* adr) {
  4005e0:       48 85 ff                test   %rdi,%rdi
  4005e3:       0f 95 c0                setne  %al
    return adr;
}
  4005f8:       c3                      retq

Esto no es directamente visible desde la fuente, el compilador cree que esto es algo que el usuario debe ser advertido.

5voto

user9876 Puntos 5385

¿Por qué es una advertencia de rendimiento?

El compilador es convertir esto:

bool hasParent()
{
  return this->parentNode;
}

en:

bool hasParent()
{
  return this->parentNode != 0;
}

Esto tarda aproximadamente un reloj ciclo más que esperarías de mirando el código. Es una diferencia insignificante desempeño.

Creo que es mejor escribir la != 0 explícitamente de todos modos, como hace el código más claro así como silenciar la advertencia.

3voto

Loki Astari Puntos 116129

Sería más eficiente que escribir:

bool hasParent()
{
    return  this->parentNode != NULL;
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X