Is this a bug of operator ~ ?

simonli
2013-11-27
2013-11-29
  • simonli
    simonli
    2013-11-27

    I used "~" to toggle a sbit in a 8051 programme. When compiling, the sdcc gave a warming that using ~ on bit/bool/unsigned char variables can give unexpected results due to promotion to int.

    So I wrote some code to test the bitwise toggling with the SDCC 20131125-8898 snapbuild:

    #include <at89c55.h>

    __sbit __at 0xb2 TEST_BIT;
    volatile unsigned char test=0;

    void main(void)
    {

    test = 0x0f;
    test = !test;
    test = 0x0f;
    test = ~test;
    test = 0x0f;
    test ^= 0xff;
    
    TEST_BIT = 0;
    TEST_BIT = !TEST_BIT;
    TEST_BIT = 0;
    TEST_BIT = ~TEST_BIT;
    TEST_BIT = 1;
    TEST_BIT = ~TEST_BIT;
    TEST_BIT = 0;
    TEST_BIT ^= 1;
    

    }

    The asm generated is as follows:
    ; bit-toggle-test.c:9: test = 0x0f;
    mov _test,#0x0F
    ; bit-toggle-test.c:10: test = !test;
    mov a,_test
    cjne a,#0x01,00103$
    00103$:
    clr a
    rlc a
    mov _test,a
    ; bit-toggle-test.c:11: test = 0x0f;
    mov _test,#0x0F
    ; bit-toggle-test.c:12: test = ~test;
    mov a,_test
    cpl a
    mov _test,a
    ; bit-toggle-test.c:13: test = 0x0f;
    mov _test,#0x0F
    ; bit-toggle-test.c:14: test ^= 0xff;
    xrl _test,#0xFF
    ; bit-toggle-test.c:16: TEST_BIT = 0;
    clr _TEST_BIT
    ; bit-toggle-test.c:17: TEST_BIT = !TEST_BIT;
    mov c,_TEST_BIT
    cpl c
    mov _main_sloc0_1_0,c
    mov _TEST_BIT,c
    ; bit-toggle-test.c:18: TEST_BIT = 0;
    clr _TEST_BIT
    ; bit-toggle-test.c:19: TEST_BIT = ~TEST_BIT;
    setb _TEST_BIT
    ; bit-toggle-test.c:20: TEST_BIT = 1;
    setb _TEST_BIT
    ; bit-toggle-test.c:21: TEST_BIT = ~TEST_BIT;
    setb _TEST_BIT
    ; bit-toggle-test.c:22: TEST_BIT = 0;
    clr _TEST_BIT
    ; bit-toggle-test.c:23: TEST_BIT ^= 1;
    cpl _TEST_BIT

    Curiously, I found that SDCC did not promote the unsigned char and bit to int. The results for toggling of unsigned char were in order. But for the toggling of the sbit with "~", no matter the sbit was set to 0 or 1, the toggling results were always "setb".

    Is the operation of "~" on a bit a bug? Should I file a bug report?

     
  • Erik Petrich
    Erik Petrich
    2013-11-27

    The C standard specifies that the result should be correct as if the integer promotion occurs, but does not require the compiler to explicitly generate code for the promotion. Here the compiler sees that the result will be cast back to unsigned char or bit for the assignment, so it does not need to generate any code to calculate the upper byte of the promoted int value in most of these cases.

    The bit is considered to be a boolean type, so assigning any non-zero value will set the bit. The initial value for a bit is either 0 or 1, so after integer promotion it has the 16-bit value 0x0000 or 0x0001. After the complement operation, the value is then 0xffff or 0xfffe. Both of these values are non-zero, so assigning either value would make the bit a 1, which is what SDCC does.

    Not quite a bug (since the generated code gives the correct result), but the generated code for TEST_BIT = !TEST_BIT should be as good as TEST_BIT ^=1 and in the past has been identical, so something has regressed. I think it would be worthwhile to note this regression on a bug report so that it is noticed (or in my case, not forgotten) and fixed.

     
  • Maarten Brock
    Maarten Brock
    2013-11-27

    sdcc gave a warming that using ~ on bit/bool/unsigned char variables can give unexpected results due to promotion to int.

    But for the toggling of the sbit with "~", no matter the sbit was set to 0 or 1, the toggling results were always "setb".

    And that is exactly why SDCC is warning you. Because this is probably not what you intended to happen!

     
  • simonli
    simonli
    2013-11-29

    Erik and Maarten, thank you for taking the time to answer my ignorant question. Your answers are very helpful for me who knows nothing about how compiler works and they clear all my doubts.

    I will file a bug report according to Erik's comment about the regression of ! on bit operation.

     
    Last edit: simonli 2013-11-30