[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Byte values promted to int when during compare
From: |
Ned Konz |
Subject: |
Re: [avr-gcc-list] Byte values promted to int when during compare |
Date: |
Thu, 24 Jun 2004 05:59:48 -0700 |
User-agent: |
KMail/1.6.2 |
On Thursday 24 June 2004 4:06 am, Joerg Wunsch wrote:
> "Lars Jeppesen (address@hidden)" <address@hidden> wrote:
> > It seems that A is promoted to int before the binary & operation ?
> > But why?
>
> Because the C standard says so.
Though of course you could use the
-mint8
GCC option which makes ints 8 bits wide, and then be explicit about your data
sizes (chars and ints will be 1 byte, longs 2 bytes, "long long" 4 bytes).
I've noticed that integer promotion rules are one of the first things that
vendors of 8-bit microcontroller C compilers tend to change (or at least
provide an option for).
For instance, the Microchip C18 compiler Users Guide says (section 2.7):
------
2.7 ISO DIVERGENCES
2.7.1 Integer Promotions
ISO mandates that all arithmetic be performed at int precision or greater. By
default, MPLAB C18 will perform arithmetic at the size of the largest
operand, even if both operands are smaller than an int. The ISO mandated
behavior can be instated via the -Oi command-line option.
For example:
unsigned char a, b;
unsigned i;
a = b = 0x80;
i = a + b; /* ISO requires that i == 0x100, but in C18 i == 0 */
Note that this divergence also applies to constant literals. The chosen type
for constant literals is the first one from the appropriate group that can
represent the value of the constant without overflow.
For example:
#define A 0x10 /* A will be considered a char unless -Oi specified */
#define B 0x10 /* B will be considered a char unless -Oi specified */
#define C (A) * (B) unsigned i; i = C; /* ISO requires that i == 0x100, but in
C18 i == 0 */
------
Their other ISO divergences include:
* rom, ram, near, and far storage qualifiers (some ports of GCC have the "far"
and "near" function attributes (as well as "model", etc.)
* overlay storage class (for local variables)
* static function arguments
* 0b0000001 style binary literals
* Automatically placing string literals in program memory (that is, "const rom
char []")
Their language extensions include:
* anonymous structures inside unions (like GCC)
* inline assembly language delimited by _asm and _endasm
* #pragmas for specifying memory sections and placing data or code in them
(with optional absolute addresses) (like GCC's
section("section-name") attribute, or its "shared" and "common" attributes)
* #pragmas for giving the compiler a hint as to where variables will be
located at link time
* #pragmas to declare functions to be interrupt service routines (like
GCC-AVR's "signal" function attribute)
* "short long" type for 24-bit numbers (somewhat like GCC's "long long" type)
Of course, GCC is notable for its extensions to the C language as well (see
http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html). From the point of view
of an AVR (and maybe also MSP430 and HC12) microcontroller user, I'd rather
see some of the above extensions than some of the ones that are already in
GCC.
--
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE