Why use !! when converting int to bool?

前端 未结 10 1765
梦谈多话
梦谈多话 2020-11-30 22:37

What can be a reason for converting an integer to a boolean in this way?

bool booleanValue = !!integerValue;

instead of just



        
相关标签:
10条回答
  • 2020-11-30 22:37

    A bool can only have two states, 0, and 1. An integer can have any state from -2147483648 to 2147483647 assuming a signed 32-bit integer. The unary ! operator outputs 1 if the input is 0 and outputs 0 if the input is anything except 0. So !0 = 1 and !234 = 0. The second ! simply switches the output so 0 becomes 1 and 1 becomes 0.

    So the first statement guarantees that booleanValue will be be set equal to either 0 or 1 and no other value, the second statement does not.

    0 讨论(0)
  • 2020-11-30 22:40

    Another option is the ternary operator which appears to generate one line less of assembly code (in Visual Studio 2005 anyways):

    bool ternary_test = ( int_val == 0 ) ? false : true;
    

    which produces the assembly code:

    cmp DWORD PTR _int_val$[ebp], 0
    setne   al
    mov BYTE PTR _ternary_test$[ebp], al
    

    Versus:

    bool not_equal_test = ( int_val != 0 );
    

    which produces:

    xor eax, eax
    cmp DWORD PTR _int_val$[ebp], 0
    setne   al
    mov BYTE PTR _not_equal_test$[ebp], al
    

    I know it isn't a huge difference but I was curious about it and just thought that I would share my findings.

    0 讨论(0)
  • 2020-11-30 22:44

    No big reason except being paranoid or yelling through code that its a bool.

    for compiler in the end it wont make difference .

    0 讨论(0)
  • 2020-11-30 22:46

    Historically, the !! idiom was used to ensure that your bool really contained one of the two values expected in a bool-like variable, because C and C++ didn't have a true bool type and we faked it with ints. This is less of an issue now with "real" bools.

    But using !! is an efficient means of documenting (for both the compiler and any future people working in your code) that yes, you really did intend to cast that int to a bool.

    0 讨论(0)
  • 2020-11-30 22:48

    The answer of user143506 is correct but for a possible performance issue I compared the possibilies in asm:

    return x;, return x != 0;, return !!x; and even return boolean_cast<bool>(x) results in this perfect set of asm instructions:

    test    edi/ecx, edi/ecx
    setne   al
    ret
    

    This was tested for GCC 7.1 and MSVC 19 2017. (Only the boolean_converter in MSVC 19 2017 results in a bigger amount of asm-code but this is caused by templatization and structures and can be neglected by a performance point of view, because the same lines as noted above may just duplicated for different functions with the same runtime.)

    This means: There is no performance difference.

    PS: This boolean_cast was used:

    #define BOOL int
    // primary template
    template< class TargetT, class SourceT >
    struct boolean_converter;
    
    // full specialization
    template< >
    struct boolean_converter<bool, BOOL>
    {
      static bool convert(BOOL b)
      {
        return b ? true : false;
      }
    };
    
    // Type your code here, or load an example.
    template< class TargetT, class SourceT >
    TargetT boolean_cast(SourceT b)
    {
      typedef boolean_converter<TargetT, SourceT> converter_t;
      return converter_t::convert(b);
    }
    
    bool is_non_zero(int x) {
       return boolean_cast< bool >(x);
    }
    
    0 讨论(0)
  • 2020-11-30 22:52

    Because !integerValue means integerValue == 0 and !!integerValue thus means integerValue != 0, a valid expression returning a bool. The latter is a cast with information loss.

    0 讨论(0)
提交回复
热议问题