Following situation:
I have macros for storing the complement of a variable together with its original value within a structure. With another macro I want to check if the original value is equal to the complement of the stored complement value. But strangely I do not get the results I may expect. Simplifying the operation, this results in following situation:
#include <stdbool.h>
#include <stdint.h>
#define CHECKVAR(var__, compl__) ((var__^compl__)==-1);
int main()
{
uint8_t var;
uint8_t complementvar;
var=3;
complementvar=~var;
bool checkOK=CHECKVAR(var,complementvar); /*-> I expect that all bits are set and hereby it is equal to "-1", but instead i get "false" */
return 0;
}
My expectation would be (e.g. on a 32bit system :
complementvar
has the value 0xfffffffc
(after integer promotion caused by the ~ operator to int and assigning the lvalue to complementvar
by implicitly casting it down to uint8
).var: 0000 0000 0000 0000 0000 0000 0000 0011
;
complementvar: 1111 1111 1111 1111 1111 1111 1111 1100
1111 1111 1111 1111 1111 1111 1111 1111
1111 1111 1111 1111 1111 1111 1111 1111==1111 1111 1111 1111 1111 1111 1111 1111
shall result in true, but instead i always receive false, because the result of XOR-operation (strangely for me) is 0x000000ff?What compiler am I using? It's the MSVC++11, but actually the solution should be as compiler independent as possible. As I have to be portable too, would the results be different with a C compiler?
after the complement operation complementvar has the value
0xfffffffc
No. Look at that code:
uint8_t complementvar;
complementvar=~var;
~var
will evaluate to the value you expect, but complementvar
has type uint8_t
, so the conversion leads to just 0xfc
.
In your checking step, this is promoted again to int
, but as uint8_t
is an unsigned type, no sign extension happens here, you just get 0
bits added. This explains the result you get from xoring (^
).
User contributions licensed under CC BY-SA 3.0