What double negation does in C

后端 未结 5 588
谎友^
谎友^ 2021-01-14 05:34

I had a controversy about what compilers \"think\" about this:

a = 8;
b = !!a;

So, is b == 0x01 ? Is TRUE always

相关标签:
5条回答
  • 2021-01-14 05:55

    !!a will be either 0 or 1, and will be type int. It will be 0 for zero a, and 1 otherwise.

    As for your choices (a) and (b), they are not equivalent, due to a possibility of a being negative. That aside, you could argue that a > 0 ? 1 : 0 is clearer but in performance-critical applications !!a may be better as it will not branch whereas a ternary conditional could dump the pipeline. But a good compiler will optimise out either way. I seldom use either since things like if (a) and if (!!a) are functionally equivalent.

    0 讨论(0)
  • 2021-01-14 06:01

    You have not supplied enough information to tell whether !!a works for your purposes or not.

    You stated that you really need the result of a > 0. However, this is not equivalent to !!a if a is signed and holds a negative value. If this is possible, then the answer is obviously "no".

    !!a is equivalent to a != 0, not to a > 0.

    0 讨论(0)
  • 2021-01-14 06:03

    Yes, b == 1. The result of any boolean operator is always 0 or 1. You can do better though...

    I want to extract only 0x00 if (a == 0) and 0x01 if (a > 0)

    b = a > 0; most accurately reflect your rule.

    0 讨论(0)
  • 2021-01-14 06:09

    In teems of speed I think this is highly dependent on the compiler and processor you are using.

    The longer expression would produce an executable 4 - 16 bytes larger.

    0 讨论(0)
  • 2021-01-14 06:21

    The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E). C11 §6.5.3.3 5

    b below will typical have the value of 1 (or possible -1, see below).

    a = 8;
    b = !!a;
    

    So, is b == 0x01?

    Yes (* see below)

    Is TRUE always 0x01 or it may be 0xFF, 0xFFFF, 0xFFFFFFFF etc..?

    In <stdbool.h>, true is a macro with the integer constant 1. TRUE is not defined by the C standard. Various implementations defines it with the value of 1. It might be have other values. It certainly should be non-zero.

    what is better to use?

    A)  a>0?1:0 
    B)  !!a
    

    Both result in an int with the value of 0 or 1. A reasonable to good compiler would be expected to generate the same code for both (if a in not signed). Use the form that 1) adhere to your groups coding standard or else 2) best conveys the meaning of code at that point. A third option which results in type (bool):

    C)  (bool) a
    

    If a is signed , then a>0?1:0 is not equivalent to !!a. a != 0 ? 1 :0 is equivalent of !!a.


    * If b is a 1 bit signed bit field, b = !!8 will have the value of -1.

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