[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] uint8_t assembled as uint16_t in some cases?

From: E. Weddington
Subject: Re: [avr-gcc-list] uint8_t assembled as uint16_t in some cases?
Date: Tue, 09 Dec 2003 09:41:52 -0700

On 9 Dec 2003 at 11:22, Robert Baruch wrote:

> Hi all,
> I have some test code which shows that there's a case where gcc
> needlessly converts a uint8_t into a uint16_t. Here's the code:


> So why the extra instruction at 0x56? It seems that although flags was
> declared to be uint8_t, the compiler is treating it as a uint16_t. More, if
> I change the if-statement from (flags & 0x02) to (flags == 0x02), the extra
> instruction goes away. So it seems to have something to do with the bit-wise
> operators.
> Anyone have any idea? Is it a genuine bug? Is there somewhere in the
> source I should be looking for this? Any workaround?

This is not a bug. The C Standard states that bitwise operators can promote 
a char to an int. GCC adheres to the Standard pretty closely, even though 
some things in the Standard are not amenable to embedded systems. Remember 
that GCC is used on a variety of computer platforms as well. This issue is 
also noted in the avr-libc FAQ (#20), which is in the avr-libc user manual. 
Did you look there?

The workaround is to typecast the operation. For example if you are 
clearing bits, you could do something like:

(uint8_t)PORTB &= (uint8_t)~mask;

Note that in the specific example of clearing bits, be sure to place the 
typecast *before* the bitwise NOT operator, as that operator could promote 
to int.

If you feel that liberally sprinkling typecasts would look ugly, you can 
always create macros, such as:

#define bit_clear_byte(var, mask)   ((uint8_t)(var) &= (uint8_t)~(mask))

bit_clear_byte(PORTB, 0x01);

You can also define macros for 16-bit sizes:

#define bit_clear_word(var, mask)   ((uint16_t)(var) &= (uint16_t)~(mask))

And of course macros for setting bits, toggling bits, etc.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]