|
Использование static переменных |
|
|
|
 |
Ответов
|
Oct 7 2010, 17:11
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(777777 @ Oct 7 2010, 18:41)  Насчет любой переменной вы погорячились - значения static переменных сохраняются даже после выхода из функции и будут иметь его при повторном входе в эту функцию. Ключевой момент - "Если результат такой записи не используется". Т.е. если вы не читате из такой переменной, а только пишете, то такая запись - бесполезная трата тактов процессора. Я не уверен, является ли присвоение адреса переменной указателю сигналом о том, что результат записи где-то потребуется и не смог найти упоминания об этом в стандарте. В вашем случае я могу предположить еще один сценарий, который также сделает вашу программу неработоспособной - компилятор имеет право сделать запись в вашу переменную непосредственно перед выходом из функции. А вы пытаетесь использовать содержимое этой переменной в прерывании до выхода из функции.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 8 2010, 09:46
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Ну раз пошла такая пьянка (с привлечением стандартов) то читаем: Цитата 6.2.4 Storage durations of objects ... 3 An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup. Таким образом, выкинуть компилятор ее не может при всем желании, так как Its lifetime is the entire execution of the program Цитата(Сергей Борщ @ Oct 7 2010, 21:11)  Ключевой момент - "Если результат такой записи не используется". Т.е. если вы не читате из такой переменной, а только пишете, то такая запись - бесполезная трата тактов процессора. Я не уверен, является ли присвоение адреса переменной указателю сигналом о том, что результат записи где-то потребуется и не смог найти упоминания об этом в стандарте. А что по-вашему означает "использование" переменной? Как раз присвоение ее значения другой или передача как параметра в функцию. И выкидывать запись в нее компилятор тоже не может, так как это значение может понадобиться функции при последующих входах, она ведь полагается на то, что оно сохранится поскольку Its lifetime is the entire execution of the program. Цитата(Itch @ Oct 8 2010, 05:01)  это смотря как накрутить ему уровень оптимизации. Оптимизация здесь совершенно ни при чем. Поведение static переменных регламентируются стандартом. Цитата(Itch @ Oct 8 2010, 05:01)  в режиме отладки обычно оптимизацию вообще отключают Оптимизацию отключают только... альтернативно одаренные люди. Мне кажется что сама возможность ее отключения оставлена для того, чтобы пользователь мог отключив ее убедиться что виноват не оптимизатор, а его программа. ЗЫ. Тут недавно проскакивал пост в котором один такой юзер удивлялся почему AVR-ка не выполняет запись в EEPROM хотя у него все написано правильно: EECR |= _BV(EEMPE); EECR |= _BV(EEPE); правда у него зачем-то оптимизация была отключена в результате для этого кода генерировался десяток команд, а EEMPE действительно лишь на протяжении четырех клоков... Цитата(SasaVitebsk @ Oct 7 2010, 22:19)  В целом я согласен с Сергей Борщ. Особенно зная его квалификацию. Понравилос  По таким постам легко отличать верующих от атеистов. Для верующих сила авторитета сильнее стандарта Си.
|
|
|
|
|
Oct 8 2010, 12:46
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(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-флага, информирующего прерывание о том, что запись произведена. В результате прерывание может начать читать буфер до того, как в него реально произведена запись.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
Сообщений в этой теме
777777 Использование static переменных Oct 7 2010, 15:41 rezident Не совсем понятно из какого топика вырвана эта цит... Oct 7 2010, 16:14 777777 Цитата(rezident @ Oct 7 2010, 20:14) Не с... Oct 7 2010, 16:32  rezident Цитата(777777 @ Oct 7 2010, 22:32) И обра... Oct 7 2010, 16:43  aesok Цитата(777777 @ Oct 8 2010, 13:46) Таким ... Oct 8 2010, 10:02   777777 Цитата(aesok @ Oct 8 2010, 14:02) Проверт... Oct 8 2010, 10:16    aesok ну и еще один пример тогда, конечно с -Os:
Код#in... Oct 8 2010, 10:22     aesok Код#include <avr/io.h>
#include <avr/i... Oct 9 2010, 22:02      777777 Цитата(aesok @ Oct 10 2010, 02:02) Правил... Oct 10 2010, 08:57       demiurg_spb Цитата(777777 @ Oct 10 2010, 12:57) Разум... Oct 10 2010, 12:31        777777 Цитата(demiurg_spb @ Oct 10 2010, 16:31) ... Oct 11 2010, 04:30         GetSmart Цитата(777777 @ Oct 11 2010, 09:30) Стати... Oct 11 2010, 04:41          777777 Цитата(GetSmart @ Oct 11 2010, 08:41) Ста... Oct 11 2010, 07:36         demiurg_spb Цитата(777777 @ Oct 11 2010, 08:30) А для... Oct 11 2010, 08:58          777777 Цитата(demiurg_spb @ Oct 11 2010, 12:58) ... Oct 11 2010, 10:20           demiurg_spb Цитата(777777 @ Oct 11 2010, 14:20) Ну, е... Oct 11 2010, 12:49         halfdoom Цитата(777777 @ Oct 11 2010, 07:30) Стати... Oct 11 2010, 10:52          GetSmart Цитата(halfdoom @ Oct 11 2010, 15:52) Ори... Oct 11 2010, 10:58          777777 Цитата(halfdoom @ Oct 11 2010, 14:52) Ори... Oct 11 2010, 11:10           halfdoom Цитата(777777 @ Oct 11 2010, 14:10) Ключе... Oct 11 2010, 11:18           GetSmart Цитата(777777 @ Oct 11 2010, 16:10) ... П... Oct 11 2010, 11:25    Petka Цитата(777777 @ Oct 8 2010, 14:16) Код#in... Oct 8 2010, 12:28  SasaVitebsk Цитата(777777 @ Oct 8 2010, 12:46) Понрав... Oct 8 2010, 23:03 SasaVitebsk В целом я согласен с Сергей Борщ. Особенно зная ег... Oct 7 2010, 18:19 Itch Цитата(SasaVitebsk @ Oct 8 2010, 01:19) Н... Oct 8 2010, 01:01 rezident Цитата(aesok @ Oct 8 2010, 16:02) Проверт... Oct 8 2010, 11:52 Сергей Борщ Цитата(rezident @ Oct 8 2010, 14:52) Она ... Oct 8 2010, 13:46  rezident Цитата(Сергей Борщ @ Oct 8 2010, 19:46) Д... Oct 8 2010, 13:54   Petka Цитата(rezident @ Oct 8 2010, 17:54) Не е... Oct 8 2010, 14:10    rezident Цитата(Petka @ Oct 8 2010, 20:10) На любо... Oct 8 2010, 15:01     MALLOY2 Не зряж в IAR введен Extended keyword __root с пом... Oct 8 2010, 15:21   Oldring Цитата(rezident @ Oct 8 2010, 17:54) Не е... Oct 8 2010, 14:51   MrYuran Цитата(rezident @ Oct 8 2010, 17:54) Не е... Oct 11 2010, 08:10 GetSmart Чтобы прерывания правильно обрабатывали глобальные... Oct 9 2010, 22:17 aesok Цитата(GetSmart @ Oct 10 2010, 02:17) Что... Oct 9 2010, 22:32 777777 Цитата(GetSmart @ Oct 10 2010, 02:17) Что... Oct 10 2010, 10:03  _Pasha Цитата(777777 @ Oct 10 2010, 14:03) компи... Oct 10 2010, 12:07 GetSmart Я уже потерял суть спора. Чё не нравится? В смысле... Oct 11 2010, 07:55
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|