Atmel CAVR-4 Manual De Usuario

Descargar
Página de 323
CAVR-4
132
Writing efficient code
AVR® IAR C/C++ Compiler
Reference Guide
INTEGER TYPES AND BIT NEGATION
There are situations when the rules for integer types and their conversion lead to 
possibly confusing behavior. Things to look out for are assignments or conditionals (test 
expressions) involving types with different size and logical operations, especially bit 
negation. Here, types also include types of constants.
In some cases there may be warnings (for example, constant conditional or pointless 
comparison), in others just a different result than what is expected. Under certain 
circumstances the compiler may warn only at higher optimizations, for example, if the 
compiler relies on optimizations to identify some instances of constant conditionals. In 
the following example an 8-bit character, a 16-bit integer, and two’s complement is 
assumed:
void f1(unsigned char c1)
{
  if  (c1 = = ~0x80)
  ;
}
Here, the test is always false. On the right hand side, 
0x80
 is 
0x0080
, and 
~0x0080
 
becomes 
0xFF7F
. On the left hand side, 
c1
 is an 8-bit unsigned character, and, thus, 
cannot be larger than 255. It also cannot be negative, thus the integral promoted value 
can never have the top 8 bits set.
PROTECTING SIMULTANEOUSLY ACCESSED VARIABLES
Variables that are accessed from multiple threads, for example from 
main
 or an 
interrupt, must be properly marked and have adequate protection, the only exception to 
this is a variable that is always read-only.
To mark a variable properly, use the 
volatile
 keyword. This informs the compiler, 
among other things, that the variable can be changed from other threads. The compiler 
will then avoid optimizing on the variable (for example, keeping track of the variable in 
registers), will not delay writes to it, and be careful accessing the variable only the 
number of times given in the source code.
A sequence that accesses a volatile declared variable must also not be interrupted. This 
can be achieved using the 
_ _monitor
 keyword in interruptible code. This must be done 
for both write and read sequences, otherwise you might end up reading a partially 
updated variable. This is true for all variables of all sizes. Accessing a small-sized 
variable can be an atomic operation, but this is not guaranteed and you should not rely 
on it unless you continuously study the compiler output. It is safer to ensure that the 
sequence is an atomic operation using the 
_ _monitor
 keyword.