Vaclav Peroutka wrote:
Hello all,
// this code works
if ( (var0xaa ^ 0xff) == var0x55) {
delay_ms(100);
} else {
delay_ms(200);
}
// this code is buggy
if ( (~var0xaa) == var0x55) {
delay_ms(100);
} else {
delay_ms(200);
}
The problem is with buggy code - when using '~', it gets expanded to 16 bits
(however, in avr-gcc 3.4.6 it was the same problem as well) :
The "bug" is in your code (alternatively, it is in the C standards!).
This is the way C works - before any arithmetic or logical operation,
and on various other occasions (such as in a if(), while() or switch()
test), any data unit smaller than an int gets promoted to an int. That
means the "~" complement is done as a 16-bit int. avrgcc is pretty good
(not perfect, but not bad) at removing unnecessary 16-bit code when it
doesn't affect the results of the operation. In this case, however, the
16-bit promotion /does/ affect the working of the code, and it must be
kept there.
Use the "-Wextra" flag to get a warning about these things - you should
be using "-Wall -Wextra" at a minimum on all but legacy C code.
(Perhaps I should file an "enhancement request" for avr-gcc to issue an
error message if it is called without warning flags.)
Furthermore, the new .LST file looks really crazy and the resulting code is
bigger ( 266 bytes from 4.3.2 compared to 130 bytes from 3.4.6).
Does anybody have a clue, what happened ?
Without knowing the compiler flags you used, it's difficult to tell.
However, in general later avr-gcc versions often generate larger code
because they do more aggressive inlining. There are compiler flags that
counter this behaviour if you want to reduce code size - search in the
archives of this mailing list for examples.
mvh.,
David
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list