visual tipo false example ejemplo bool c++ visual-c++

c++ - tipo - false visual basic



¿Cuál es la implicación de rendimiento de convertir a bool en C++? (11)

[Esta pregunta está relacionada pero no es lo mismo que esta .]

Mi compilador advierte sobre la conversión implícita o la conversión de ciertos tipos a bool, mientras que las conversiones explícitas no producen una advertencia:

long t = 0; bool b = false; b = t; // performance warning: forcing long to bool b = (bool)t; // performance warning b = bool(t); // performance warning b = static_cast<bool>(t); // performance warning b = t ? true : false; // ok, no warning b = t != 0; // ok b = !!t; // ok

Esto es con Visual C ++ 2008 pero sospecho que otros compiladores pueden tener advertencias similares.

Entonces mi pregunta es: ¿cuál es la implicación de rendimiento de casting / conversion to bool ? ¿La conversión explícita tiene un mejor rendimiento en algunas circunstancias (por ejemplo, para ciertas arquitecturas o procesadores de destino)? ¿La conversión implícita de alguna manera confunde al optimizador?

La explanation de Microsoft de su advertencia no es particularmente útil. Implican que hay una buena razón pero no la explican.


A menos que esté escribiendo código para un bucle interno realmente crítico (núcleo del simulador, ray-tracer, etc.) no tiene sentido preocuparse por los golpes de rendimiento en este caso. Hay otras cosas más importantes de las que preocuparse en su código (y otras trampas de rendimiento más importantes que acechan, estoy seguro).


El rendimiento es idéntico en todos los ámbitos. Implica un par de instrucciones en x86, quizás 3 en algunas otras arquitecturas.

En x86 / VC ++, todos lo hacen

cmp DWORD PTR [whatever], 0 setne al

GCC genera lo mismo, pero sin las advertencias (en cualquier nivel de advertencia).


En C ++ un bool ISA int con solo dos valores 0 = falso, 1 = verdadero. El compilador solo tiene que verificar un bit. Para ser perfectamente claro, verdadero! = 0, por lo que cualquier int puede anular bool, solo cuesta ciclos de procesamiento hacerlo.

Al utilizar una muestra larga como la del código, está obligando a realizar muchas más comprobaciones de bits, lo que provocará un impacto en el rendimiento.

No, esto no es una optimización prematura, es bastante loco usar código que requiere más tiempo de procesamiento en general. Esto es simplemente una buena práctica de codificación.


Estaba desconcertado por este comportamiento, hasta que encontré este enlace:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99633

Aparentemente, viniendo del Desarrollador de Microsoft que "posee" esta advertencia:

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

No se trata del código generado, sino de si el programador ha indicado o no el intento de cambiar un valor de int a bool . Hay una penalización por eso, y el usuario tiene la opción de usar "int" en lugar de "bool" de manera consistente (o más bien viceversa) para evitar el codegen "boolifying". [...]

Es una vieja advertencia, y puede haber sobrevivido a su propósito, pero se está comportando como se diseñó aquí.

Entonces me parece que la advertencia es más sobre estilo y evitar algunos errores que cualquier otra cosa.

Espero que esto responda tu pregunta ...

:-pag


La advertencia de rendimiento realmente tiene un poco de sentido. Lo he tenido también y mi curiosidad me llevó a investigar con el desensamblador. Está tratando de decirle que el compilador tiene que generar algún código para forzar el valor a 0 o 1. Como está insistiendo en un bool, la idea C de la vieja escuela de 0 o cualquier otra cosa no se aplica.

Puede evitar ese pequeño golpe de rendimiento si realmente lo desea. La mejor manera es evitar el reparto por completo y usar un bool desde el principio. Si debe tener un int, puede usar if (int) en lugar de if (bool). El código generado simplemente comprobará si int es 0 o no. No se generará código adicional para asegurarse de que el valor sea 1 si no es 0.


La explicación de Microsoft parece ser que lo que intentan decir es:

Oye, si estás usando una int, pero solo estás almacenando información verdadera o falsa, ¡haz que sea un bool!

Soy escéptico sobre cuánto se ganaría en cuanto al rendimiento, pero MS puede haber encontrado que hubo alguna ganancia (para su uso, de todos modos). El código de Microsoft tiende a correr muchísimo, así que tal vez hayan encontrado que la micro-optimización vale la pena. Creo que gran parte de lo que entra en el compilador de MS es para soportar cosas que les resultan útiles (solo tiene sentido, ¿no?).

Y te deshaces de algunos moldes sucios y pequeños para arrancar.


Me parece una optimización prematura. ¿Estás esperando que el rendimiento del elenco afecte seriamente el rendimiento de tu aplicación? Tal vez si está escribiendo código de núcleo o controladores de dispositivo, pero en la mayoría de los casos, todos deberían estar bien.


No creo que el rendimiento sea el problema aquí. El motivo por el que recibes una advertencia es que la información se pierde durante la conversión de int a bool.


Por lo que sé, no hay ninguna advertencia en ningún otro compilador para esto. La única forma en que puedo pensar que esto causaría una pérdida de rendimiento es que el compilador tiene que comparar el entero entero a 0 y luego asignar el bool apropiadamente (a diferencia de una conversión como char a bool, donde el resultado puede copiarse porque un bool es un byte y por lo tanto son efectivamente los mismos), o una conversión integral que implica copiar una parte o la totalidad de la fuente al destino, posiblemente después de un cero del destino si es más grande que la fuente (en términos de memoria) .

Es otra más de las inútiles e inútiles ideas de Microsoft sobre qué constituye un buen código, y nos lleva a tener que soportar definiciones estúpidas como esta:

template <typename T> inline bool to_bool (const T& t) { return t ? true : false; }


Según su enlace a la explicación de MS, parece que si el valor es simplemente 1 o 0, no hay impacto de rendimiento, pero si se trata de cualquier otro valor distinto de 0, ¿qué comparación debe generarse en tiempo de compilación?


long t; bool b; int i; signed char c; ...

Recibes una advertencia cuando haces algo que sería "gratis" si no se requería que bool fuera 0 o 1. b = !! t está asignando efectivamente el resultado del bool operator!(long) (lenguaje incorporado, no anulable) bool operator!(long)

¡No deberías esperar el! o! = los operadores cuestan cero asm, incluso con un compilador de optimización. Por lo general, es cierto que int i = t suele optimizarse por completo. O incluso firmó char c = t; (en x86 / amd64, si t está en el registro% eax, después de c = t, usar c solo significa usar% al. amd64 tiene un byte de direccionamiento para cada registro, por cierto. IIRC, en x86 algunos registros no tienen direccionamiento de bytes .)

De todos modos, b = t; i = b ; isn''t the same as c = t; i = c; it''s i = !!t; instead of i = t & 0xff b = t; i = b ; isn''t the same as c = t; i = c; it''s i = !!t; instead of i = t & 0xff b = t; i = b ; isn''t the same as c = t; i = c; it''s i = !!t; instead of i = t & 0xff ;

Err, creo que todos ya saben todo eso de las respuestas anteriores. Mi punto era que la advertencia tenía sentido para mí, ya que detectaba casos en los que el compilador tenía que hacer cosas que realmente no le contaba, como BOOL a la vuelta porque declaró la función bool, pero están devolviendo un valor integral eso podría ser cierto y! = 1. Por ejemplo, muchas cosas de Windows devuelven BOOL (int).

Esta es una de las pocas advertencias de MSVC que G ++ no tiene. Estoy mucho más acostumbrado a g ++, y definitivamente advierte sobre cosas que MSVC no hace, pero estoy contento de que me lo haya contado. Escribí un archivo de cabecera portab.h con stubs para las clases / macros / funciones de MFC / Win32 que utilicé. Esto tiene la aplicación MFC en la que estoy trabajando para compilar en mi máquina GNU / Linux en casa (y con cygwin). Principalmente quería poder compilar y probar en qué estaba trabajando en casa, pero terminé encontrando las advertencias de g ++ muy útiles. También es mucho más estricto sobre, por ejemplo, plantillas ...

En bool en general, no estoy seguro de que sea un mejor código cuando se usa como valor de retorno y paso de parámetros. Incluso para los lugareños, g ++ 4.3 no parece darse cuenta de que no tiene que forzar el valor a 0 o 1 antes de ramificarse en él. Si se trata de una variable local y nunca tomas su dirección, el compilador debe mantenerla en el tamaño que sea más rápido. Si tiene que derramarlo de los registros a la pila, también podría mantenerlo en 4 bytes, ya que puede ser un poco más rápido. (Utiliza muchas instrucciones de movsx (extensión de signo) al cargar / almacenar bools (no locales), pero realmente no recuerdo lo que hizo para las variables automáticas (pila local). Recuerdo haber visto que reservaba una impar cantidad de espacio de pila (no un múltiplo de 4) en funciones que tenían algunos bools locales).

El uso de indicadores de bool fue más lento que el int con el compilador Digital Mars D del año pasado: http://www.digitalmars.com/d/archives/digitalmars/D/opEquals_needs_to_return_bool_71813.html (D es muy parecido a C ++, pero abandona por completo C compatibilizar hacia atrás para definir una nueva semántica agradable y un buen soporte para la metaprogramación de plantillas, por ejemplo, "static if" o "static assert" en lugar de plantillas hacks o macros cpp. Realmente me gustaría probarlo alguna vez. :)

Para las estructuras de datos, puede tener sentido, por ejemplo, si quieres empacar un par de banderas antes de un int y luego algunas dobles en una estructura vas a tener bastante.