Bitwise complement

M

Martin Kojtal

Hello,

the example application is running on 8bit MCU, register is 8 bit wide. There's line where it has to clear the flag with following command:

StructPointer->REGISTER &= ~(FIRST_BIT_MASK);

It issues warning "possible loss of data" which I understand because ~ operator have operands integer type (6.5.4 Expressions). Why the warning disappears when the bit mask is casted to UINT8:

StructPointer->REGISTER &= ~((UINT8)FIRST_BIT_MASK);

I am inclined to cast the result of bitwise complement: (UINT8)(~FIRST_BIT_MASK).
Are both forms correct to suppress the warning?

MartinK
 
E

Eric Sosman

Hello,

the example application is running on 8bit MCU, register is 8 bit wide. There's line where it has to clear the flag with following command:

StructPointer->REGISTER &= ~(FIRST_BIT_MASK);

It issues warning "possible loss of data" which I understand because ~ operator have operands integer type (6.5.4 Expressions). Why the warning disappears when the bit mask is casted to UINT8:

StructPointer->REGISTER &= ~((UINT8)FIRST_BIT_MASK);

I am inclined to cast the result of bitwise complement: (UINT8)(~FIRST_BIT_MASK).
Are both forms correct to suppress the warning?

The compiler can issue warnings for any reason, even for C code
that is perfectly valid. Sometimes you'll be able to silence a
warning by changing one valid fragment to another, sometimes not.
(Sometimes, a rewrite that placates one compiler will upset another!)
In your case it looks like the (UINT8) cast silences your compiler's
warning -- but "Why?" is a question about the compiler, not about C.

We can't tell whether your two versions are equivalent, because
we don't know the data types of FIRST_BIT_MASK and REGISTER (we
don't actually *know* what UINT8 is, either, though we might guess).
Under reasonable assumptions about the data types and about the way
your machine probably represents negative integers, the two versions
do the same thing -- so the compiler's nervousness about one spelling
and acceptance of the other is not a C thing, but a compiler thing.
Perhaps the compiler's documentation says something about the matter.
 
I

ImpalerCore

Hello,

the example application is running on 8bit MCU, register is 8 bit wide. There's line where it has to clear the flag with following command:

StructPointer->REGISTER &= ~(FIRST_BIT_MASK);

It issues warning "possible loss of data" which I understand because ~ operator have operands integer type (6.5.4 Expressions). Why the warning disappears when the bit mask is casted to UINT8:

StructPointer->REGISTER &= ~((UINT8)FIRST_BIT_MASK);

I am inclined to cast the result of bitwise complement: (UINT8)(~FIRST_BIT_MASK).
Are both forms correct to suppress the warning?

This warning may appear because the integer width of FIRST_BIT_MASK is
larger than REGISTER. Often 'int' is a 16-bit integer in many 8-bit
PIC compilers.

If you had some form of <stdint.h>, you could possibly get around this
by defining FIRST_BIT_MASK using a UINT8_C(0x..) constant, or you
could include the (UINT8) cast in the definition of FIRST_BIT_MASK,
i.e. #define FIRST_BIT_MASK ((UINT8)0xA0).

Best regards,
John D.
 
L

Les Cargill

Martin said:
Hello,

the example application is running on 8bit MCU, register is 8 bit wide. There's line where it has to clear the flag with following command:

StructPointer->REGISTER &= ~(FIRST_BIT_MASK);

It issues warning "possible loss of data" which I understand because ~ operator have operands integer type (6.5.4 Expressions). Why the warning disappears when the bit mask is casted to UINT8:

StructPointer->REGISTER &= ~((UINT8)FIRST_BIT_MASK);

Because that probably neutralizes the risk of sign extension causing
problems.
I am inclined to cast the result of bitwise complement: (UINT8)(~FIRST_BIT_MASK).
Are both forms correct to suppress the warning?

MartinK


Seriously, just turn on -Wall and --strict-whatever and experiment. If
you're skeptical, dump the assembly and look at it.
 
P

Phil Carmody

Kenneth Brody said:
....
However, I think all of the replies have forgotten integer promotions.
Quoting section 6.3.1.1p2 footnote 48:


So, as I read it, the unary "~" promotes the UINT8 to an int.

More pedantically - before the ~ operates, its operand is promoted
to an int, rather than the operation simply yielding an int from
a UINT8.

(Corner case wacko definitions of UINT8 ignored.)
This seems to be confirmed on my system as:

Given:

char c;

Then:

sizeof(c) == 1
sizeof(~c) == 4

Gotta love
sizeof('c')
though, but that's a thread-hijack.

Phil
--
I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top