2012-06-27 3 views
2

Considérez ceci compilé dans MS Visual Studio 2005 (et probablement d'autres):Quand est un bool pas un bool (compilateur C4800 avisent)

CPoint point1(1, 2); 
CPoint point2(3, 4); 
const bool point1And2Identical(point1 == point2);   // C4800 warning 
const bool point1And2TheSame((point1 == point2) == TRUE); // no warning 

Qu'est-ce que ...? Le compilateur MSVC est-il mort? Pour autant que je sache, TRUE est # défini comme 1, sans aucune information de type. Alors par quelle magie y a-t-il une différence entre ces deux lignes? Sûrement le type de l'expression à l'intérieur des parenthèses est le même dans les deux cas? Personnellement, je pense qu'éviter l'avertissement en utilisant l'option == TRUE est moche (mais moins moche que l'alternative! = 0, en dépit d'être plus strictement correct), et il est préférable d'utiliser #pragma warning (disable: 4800) pour impliquer "mon code est bon, le compilateur est un âne". Se mettre d'accord? Note - J'ai vu toutes sortes de discussions sur C4800 parler d'assigner des ints à des booléens, ou de lancer un combo de hamburger avec de grandes frites (tenir les oignons) à un bool, et se demander pourquoi il y a des résultats étranges. Je ne peux pas trouver une réponse claire sur ce qui semble être une question beaucoup plus simple ... qui pourrait juste briller ligne sur C4800 en général.

+0

Recherchez la déclaration de 'operator ==' liée à la classe 'CPoint'. – aschepler

+0

Non - vous le cherchez :-) Je n'ai pas trouvé de magie du tout - operator == renvoie un BOOL qui est un typedef à un int. Pour autant que je sache, int == TRUE est toujours un int. – omatai

+1

Sur les types intégrés, '==' donne un 'bool', pas un' BOOL'. – aschepler

Répondre

0

En fait, n'utiliseriez-vous PAS ASSERT (point1 == point2)? L'opérateur de la classe CPoint est explicitement surchargé pour renvoyer non nul si les points sont égaux et 0 s'ils ne le sont pas. La fameuse macro ASSERT me tue, mais si vous regardez comment la macro ASSERT se développe, il serait presque analogue à l'ajout de == TRUE ci-dessus dans votre code. Jetez un oeil à this link on msdn. Notez l'exemple de code qui indique explicitement de ne pas utiliser l'opérateur d'égalité directement contre deux objets CPoint. Je suis d'accord que votre code semble le plus correct, mais c'est pourquoi nous aimons C++. Ugh ...

+0

Oui et non. La raison pour laquelle je veux assigner une valeur à un const bool est pour une utilisation ultérieure dans (plusieurs) autres endroits où je teste if (point1And2TheSame && point3And4TheSame &&! Point5And5TheSame ...) et similaire. Donc ASSERT() est inapproprié. Et il disparaît dans la version RELEASE aussi. – omatai

+0

D'accord sur ASSERT ne pas le faire pour libérer des versions. Je suis d'accord que désactiver l'avertissement dans le code avec un commentaire qui décrit pourquoi serait la meilleure solution dans ce cas. J'aime la suggestion de Matt Millwood de !! (point1 == point2) mais je suis aussi d'accord pour dire que cela ne clarifie pas vraiment le raisonnement derrière la syntaxe. Bonne chance! – EdFred

3

Have a look at this

En règle générale, ce message est dû en attribuant des variables int bool des variables

TRUE et BOOL sont ints, non bool.

Vous pouvez également vérifier si (point1 == point2) != 0 ou utilisez !!(point1 == point2)

EDIT

Le !! les opérations convertissent simplement le résultat en un booléen, et puisque c'est un double négatif, vous recevrez le même résultat.

Il y a eu une discussion à ce sujet avant les deux here et here.

+1

Vous savez ... J'aime un peu !! (point1 == point2) comme alternative. Il se distingue comme une chose étrange à faire, un peu comme un #pragma fait. Toute personne qui tente ensuite d'enlever le !! recevra un avertissement, et fera face à ces mêmes dilemmes. Mais je pense toujours que #pragma le dit plus explicitement - il y a une bonne chance que quelqu'un assumera !! était une faute de frappe, et le changer en un seul!, ou le == à un! =. Réponse inventive cependant :-) – omatai

+0

Cela répond à vos questions sur l'avertissement C4800 et pourquoi il se produit dans votre situation. Quant à savoir si vous utilisez des macros ou !! ou! = 0 pour supprimer ces avertissements est totalement basé sur vos préférences personnelles. – Aesthete

0

La réponse qui me satisfait maintenant est la suivante:

Sur types intégrés, l'opérateur == renvoie bool (tel que requis par C++ standard). Pour CPoint et de nombreux autres types de Microsoft, l'opérateur == renvoie BOOL de Microsoft, qui est typedef'd à un int. Donc, la première ligne d'affectation const bool essaye d'assigner un int à un bool const, ce qui donne C4800.La seconde ligne d'affectation constbool compare un int à la valeur TRUE, qui est typedef'd comme 1 (supposé être un int par le compilateur) et donc le résultat de la comparaison int == int est un booléen. Ceci est assigné au const bool sans avertissement. En ce qui concerne ce qui semble le plus agréable à l'écran, #pragma est moche et inutile. ! Si vous ne l'aimez pas le look de l'extra = 0, essayez ceci:

#define ISTRUE(x) ((x) != 0) 

const bool point1And3Identical(ISTRUE(point1 == point2)); // no warning 

sémantiquement et syntaxiquement cela semble être une meilleure façon de peu le code. Vous pouvez tranquillement placer le #define pour ISTRUE() loin dans un fichier d'en-tête de sorte qu'il semble encore plus joli.

Questions connexes