user3618186
user3618186

Reputation: 123

Warning about "C4800: 'int' : forcing value to bool 'true' or false'", why?

// Implementation of the INTTerface for cblas_saxpy
template <> inline void cblas_axpy<bool>( INTT n,  bool a,  bool* X,
       INTT incX, bool* Y,  INTT incY) {
   for (int i = 0; i<n; ++i)
      Y[i] = a*X[i];
};

warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

This is part of the code that makes the warning happen. I do not know how to fix it. Please anyone give me some advice. Thank you so so much!

Upvotes: 2

Views: 1470

Answers (3)

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63807

Solution

Using multiplication for two operands of type bool is well-defined, it is however normally frowned upon since it doesn't make sense from a theoretical view. Instead of multiplying the two operands, use bitwise-and or logical-and, as can be seen in the below example:

bool a = true;
bool b = true;

bool c = a && b;  // c = true  (using logical-and, RECOMMENDED)
bool d = a & !b;  // d = false (using bitwise-and)

Y[i] = a && X[i]; // fix

What about the warning?

The warning issued is completely useless, since both operands involved in the multiplications are of type bool the usual arithmetic conversion rules states that the result will also be of type bool.

It is probably so that the warning was introduced to protect cases where an implicit conversion to bool happens when calculating the multiplication of two operands where the resulting type is not bool.

The compiler you are using is inaccurately assuming that two arithmetic values multiplied might lead to a value that is not representable by the destination type, if that is bool, and decides to issue the diagnostic.


In the below example the result yield by x * y will be int following the rules of usual arithmetic conversion, this means that the result of the expression will be stored in an int, and then truncated to fit inside bool.

int  x = 10;
bool y = false;

bool z = x * y; // (1), semantically equivalent of `bool x = (int)(x * (int)y)`

Standard references (n3337)

5.6p2 Multiplicative operators [expr.mul]

The operands of * and / shall have arithmetic or unscoepd enumeration type; the operands of % shall have integral or unscoped enumeration type. The usual arithmetic conversions are performed on the operands and determine the type of the result.

5p9 Expressions [expr]

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. The pattern is called usual arithmetic conversions, which are defined as follows:

  • ...

    • If both operands are of the same type, no further conversion is needed.
    • ...

Upvotes: 2

Emilio Garavaglia
Emilio Garavaglia

Reputation: 20730

It is a nonsense turning inadvertently into another nonsense that makes some sense...

In term of c++ spec this explanation can be not rigorous, but it may help in understanding what is going on.

bool binary operation are just && and ||.

But bool convert implicitly into int, having false=1 and true=1.

and since * is an int multiplication, your bool * bool --> nonsense becomes int * int --> int. (that actually make sense, but is probably not what you though about)

Now you have and int (something with a 16 or 32 bit signer range) returned by the multiplication you assign to a bool (that needs to be truncated to one bit only)

The warning is about this truncation.


Note: in term of C++ spec, bool*bool is defined, but thinking the way I suggest can help more in abstract reasoning, where conversion between generic types happens or conversion to and from integrals of different types (or implicitly converting as such) can be around.

Upvotes: 0

Baj Mile
Baj Mile

Reputation: 780

Why not replace it with:

 template <> inline void cblas_axpy<bool>( INTT n,  bool a,  bool* X,
   INTT incX, bool* Y,  INTT incY) {
  for (int i = 0; i<n; ++i)
  Y[i] = a && X[i];
 };

I think that compiler is complaining because multiplying two bools requires to convert the result from int to bool and is more costly then to just multiply two integers. This warning happens each time when converting int to bool. If Y was int the warning would not be raised.

Upvotes: 1

Related Questions