Reflector писал(а): Программист читая регистр знает, что должно генериться прерывание, возможно именно для этого он его и читает, а без volatile результат непредсказуем...
это программист. программист всеми силами стремится в ногу не стрелять. опасность подстерегает "не совсем программиста" который может думать, что бессмысленное чтение ни на что не влияет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Что-то у меня подозрение, что в мою сторону камни. Но я там был именно за понимание всего механизма работы с volatile, опциями оптимизатора, для чего, почему и как. А не за бездумное использование.
лично я никаких камней не кидаю.
volatile мешает оптимизатору.
помогает ли программиступисателю программ - это вопрос другой.
например, постоянно можно услышать, что все переменные, изменяемые в прерываниях, должны быть volatile... это не так. НЕ ВСЕ, а только те, которые в том нуждаются. просто надо понимать, какие нуждаются, а какие нет. если не выжимать до последнего байта всю память, то можно ставить volatile бездумно, попасть на "предсказанный" мной вариант ошибки будет редким "везением"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Да и вообще, почему что-то быть именно должно? я вот не очень командный игрок, чаще один. Внутри команды да, есть соглашения, их все придерживаются, единый стиль, это тоже удобно. Но когда один работаю с 8-битными мк, у меня идет смесь Си с ассемблером. Ну, привычка такая, мне раньше часто доставалось от ошибок оптимизатора (да, именно его ошибок, которые впоследствии официально признавались и фиксились, а не от того, что я недоволатилил), да и мне нравится эдакое соревнование, могу ли изначально слепить оптимальный код, который оптимизатор не сможет оптимизировать.
На простых задачах это не отнимает много времени и доставляет удовольствие.
Поэтому, я против догм. Да, программист обязан знать все тонкости volatile и если глянуть на ссылку, что я приводил в той ветке и на первый пост этой ветки а так же замечаний ARV, ну никак не обойтись короткой фразой. Но применение не должно быть догмой, предложение о применении необходимо сопровождать разъяснением, почему. Потому что "оптимизатор всегда вкл" тоже не обязано быть догмой. И это мы вообще рассуждаем о фундаментальном сферическом, а вот в частном случае с частным компилятором вообще всё может быть не так. Тоже чтение регистров, например. У меня вот компилятор космика не выкидывает "пустое в никуда" неволатильное чтение регистра. Хотя, глядя на код, мне хочется его выкинуть самому.
Ну вот какая-то такая мысль. Извините, если сумбурно - малость с похмелья.
[uquote="ARV",url="/forum/viewtopic.php?p=4163233#p4163233"]volatile мешает оптимизатору.
помогает ли программиступисателю программ - это вопрос другой.[/uquote]
volatile не мешает оптимизатору. Он просто делает обращение к конкретной ячейке памяти предсказуемыми. И только.
Да, помогает. Но для этого пИсатель программ должен знать к какой ячейке надо обращаться особо (регистр там или в прерывании задействована), а какая просто ячейка, которую можно отдать на откуп оптимизатору.
Применение volatile, равно как и других инструментов, не отменяет необходимости думать головой. Это главное правило. Компилятор думать за программиста не будет.
Добавлено after 1 hour 21 minute 23 seconds:
кстати, кому не нравится volatile, то вот способ обхода. Пишите две функции (пример для байтовой ячейки) в виде отдельной библиотеки.
[uquote="SfS",url="/forum/viewtopic.php?p=4163499#p4163499"]Компилятор такое не оптимизирует.[/uquote]
Компилятор такое и не компилирует, по крайней мере gcc
А если имелось в виду:
[uquote="Reflector",url="/forum/viewtopic.php?p=4163536#p4163536"][uquote="SfS",url="/forum/viewtopic.php?p=4163499#p4163499"]Компилятор такое не оптимизирует.[/uquote]
Компилятор такое и не компилирует, по крайней мере gcc [/uquote]
Замечательно комплирует. Сейчас проверил. Там почемуто амперсанды лишние из редактора копирнулись. Убрал.
Если функции делать в виде отдельной либы - то работает всё именно как задумано.
[uquote="SfS",url="/forum/viewtopic.php?p=4163572#p4163572"]Если функции делать в виде отдельной либы - то работает всё именно как задумано.[/uquote]
Проверяем, пишу:
[uquote="SfS",url="/forum/viewtopic.php?p=4163499#p4163499"]кстати, кому не нравится volatile[/uquote]Чего??? Сегодня кому-то volatile не нравится, завтра const нелюб будет, а послезавтра что следующее?
Добавлено after 9 minutes 26 seconds:
[uquote="SfS",url="/forum/viewtopic.php?p=4162026#p4162026"]Адепты мантры - «а у меня и так работает» - часто нарываются на очень неожиданное поведение кода в самый неподходящий момент времени. Удачи им в скачке по граблям.[/uquote]
[uquote="SfS",url="/forum/viewtopic.php?p=4163615#p4163615"]И там в асме прекрасно сработало.[/uquote]А как дышал, как дышал
[uquote="VladislavS",url="/forum/viewtopic.php?p=4163620#p4163620"][uquote="SfS",url="/forum/viewtopic.php?p=4163615#p4163615"]И там в асме прекрасно сработало.[/uquote]А как дышал, как дышал [/uquote]
А как дышал?
Дышал ровно и выступал за стандарты:)
Но привел пример извращения. Почему не привести ради прикола и для оживления темы?
Но выше товарищи правы, с lto компилерами без отключения оного lto не прокатит. А я както и не написал об этом.
вот именно, что "эмм"... в стандарте полно мест, которые "на усмотрение реализаторов компилятора"
к тому же мало кто видел этот стандарт на русском языке...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Я на AVR Си не применяю, но вот любопытная ситуация произошла. На родственном форуме у студента возникла прооблема с точками "остановки". Я по доброте душевной , хоть в этом и не шибко секу, посоветовал ему обратить взор на volatile - не исключено, что компилятор оптимизнул - выбросил этот бессмысленный с его точки зрения фрагмент.
СпойлерНужна помощь! При составление программы на языке С+ возникает проблема с точками остановки. Может кто подскажет что я делаю не так.
Код:
#include "compiler.h"
#include <avr/interrupt.h>
#include "conf_example.h"
// Only use Pin Change Interrupt handler for devices supporting this.
#ifdef EXAMPLE_PCINT_vect
ISR(EXAMPLE_PCINT_vect)
{
PIND = (1 << PIND0);
}
#endif
int main(void)
{
uint8_t val;
DDRD = 0xff;
// Set output levels high. Will turn off STK600 LEDs.
PORTD = 0xff;
// Set output levels low. Will turn on STK600 LEDs.
PORTD = 0;
PORTB = 0xff;
val = PINB;
while (1)
{
PORTD |= (1 << PORTD0);
PORTD &= ~(1 << PORTD0);
}
}
А мне стало интересно: как "заволатилить" порт?
Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.
Ну а стьюденьт тоже зря лил слёзы. Загрузил в Студию hex - и всё видно, что оно там накомпиляло.
---------------
СпойлерПравильно говорит мне мой кот Мурзик: "Не занимайся фигнёй. Хочешь написать для AVR - ну ты же на асме - как на родном
[uquote="Jack_A",url="/forum/viewtopic.php?p=4164658#p4164658"]Я на AVR Си не применяю, но вот любопытная ситуация произошла. На родственном форуме у студента возникла прооблема с точками "остановки". Я по доброте душевной , хоть в этом и не шибко секу, посоветовал ему обратить взор на volatile - не исключено, что компилятор оптимизнул - выбросил этот бессмысленный с его точки зрения фрагмент.
СпойлерНужна помощь! При составление программы на языке С+ возникает проблема с точками остановки. Может кто подскажет что я делаю не так.
Код:
#include "compiler.h"
#include <avr/interrupt.h>
#include "conf_example.h"
// Only use Pin Change Interrupt handler for devices supporting this.
#ifdef EXAMPLE_PCINT_vect
ISR(EXAMPLE_PCINT_vect)
{
PIND = (1 << PIND0);
}
#endif
int main(void)
{
uint8_t val;
DDRD = 0xff;
// Set output levels high. Will turn off STK600 LEDs.
PORTD = 0xff;
// Set output levels low. Will turn on STK600 LEDs.
PORTD = 0;
PORTB = 0xff;
val = PINB;
while (1)
{
PORTD |= (1 << PORTD0);
PORTD &= ~(1 << PORTD0);
}
}
А мне стало интересно: как "заволатилить" порт?[/uquote]
Не очень понятно о каком именно фрагменте речь.
val - обычная переменная и компилер может её выбрасить, как неиспользуемую. Всё по правилам.
PORTx и PINx - волатильные. Их не должен выбросить.
Добавлено after 2 minutes 4 seconds:
[uquote="Jack_A",url="/forum/viewtopic.php?p=4164671#p4164671"]Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.[/uquote]
Мои примеры - абстрактные - НЕ ДЛЯ AVR. И там оговорено, что UDR - это регистр записи-чтения FIFO-буфера.