Цитата(777777 @ Oct 8 2010, 12:46)

Понравилос

По таким постам легко отличать верующих от атеистов. Для верующих сила авторитета сильнее стандарта Си.

Ну так вот стандрат С говорит, что компилятор в процессе оптимизации обязан обеспечить observable behaviour такое же, как у абстрактной машины языка. Да, время жизни static-переменной по стандарту совпадает с временем жизни программы. Но и время жизни static-функции совпадает с ним же. А компилятор успешно выбрасывает, если она в пределах этого же файла не вызывается сама и её адрес никуда не передаётся. А всё почему - на всё то же o.b. не виляет - выбрасываем.
Так что наличие обсуждаемой static-переменной в функции foo() с observable behaviour никак не связано, поэтому компилятор имеет право её выбросить. Всё зависит от уровня оптимизации, на который способен компилятор и от указаний ему по этому поводу.
Код
#include <avr/io.h>
void
foo (void)
{
static int a;
a = 2;
return;
}
void
main(void)
{
for(;;) {
foo();
PORTB ^= 0x01;
}
}
avr-gcc -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -mmcu=atmega8 static.c
avr-objdump -d a.out >static.dump
Код
...
0000005e <main>:
5e: 91 e0 ldi r25, 0x01; 1
60: 88 b3 in r24, 0x18; 24
62: 89 27 eor r24, r25
64: 88 bb out 0x18, r24; 24
66: fc cf rjmp .-8 ; 0x60 <main+0x2>
...
Или так
avr-gcc -Os -fwhole-program -S -mmcu=atmega8 static.c
Код
.global main
.type main, @function
main:
/* prologue: function */
/* frame size = 0 */
ldi r25,lo8(1)
.L2:
in r24,56-32
eor r24,r25
out 56-32,r24
rjmp .L2
А то, что не выкинул при компиляции одной только функции foo() - ну так есть ещё над чем работать. Поскольку переменная не volatile, внутри функци не считывается и её адрес никуда не передаётся — она
может быть выброшена. Не в этой версии компилятора, так в следующей.
С массивами, в которые из основного кода ведётся только запись, а из прерывания — только чтение, тоже не всё так просто. Если массив не volatile, то компилятор имеет право переставить запись в него и взведение volatile-флага, информирующего прерывание о том, что запись произведена. В результате прерывание может начать читать буфер до того, как в него реально произведена запись.