Перейти к содержанию
    

(Не)доработки языков программирования

Ещё недоработку обнаружил. Volatile.

 

Этот квалификатор действует глобально на всю прогу и заставляет компилятор не оптимизировать переменную. Используется обычно тогда, когда в разных тредах, равно как и в программе+прерывании используется переменная. Но. Когда в программе юзается эта переменная, то она конечно может измениться и оптимизировать её не надо. Но когда в прерывании она юзается, то там было бы оптимальным снимать этот квалификатор. Но вроде бы это не предусмотрено. (?)

А если обработчики прерываний вынести в отдельный файл, там объявить необходимую переменную int val, а в другие файлы добавить эту переменную как extern volatile int val?

В результате обработчики прерываний будут работать с оптимизированной переменной, а вся остальная прога - с volatile.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если обработчики прерываний вынести в отдельный файл,
Как-то слишком сложно. _Pasha правильно предложил - завести временную переменную (только не указатель, на Пашин пример будет справедливо ругаться, ибо указатель должен быть на volatile), когда надо считывать в эту переменную, проводить с ней вычисления и когда надо записывать обратно в volatile-переменную. Лишь только программист в состоянии определить, когда наступает этот момент "когда надо". Ни один компилятор угадать его не сможет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Единственное, что я пользовал в Pascal, а в С этого нет - так это вложенные процедуры.

 

Если очень хочется - в gcc есть расширение

http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

 

хотя наверно вы знаете. На практике - я не встречал чтобы этим кто-то пользовался.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Лишь только программист в состоянии определить, когда наступает этот момент "когда надо". Ни один компилятор угадать его не сможет.

Это почему?

Внутри прерывания переменную можно оптимизировать как угодно. Не важно, вложенное оно или нет и есть ли другие прерывания c таким же или меньшим приоритетом, юзающие эту переменную. В идеале лучше задавать (отменять volatile) каким-то квалификатором внутри какой-то зоны видимости, будь то обработчик или {}.

 

Вручную копировать volatile в простую переменную, которую потом юзать не есть хорошо. Т.к. переменная volatile, то она сразу будет скопирована куда-то и отнимать место там (рег/рама). В конце обработчика та же беда. С указателем (вариант Паши) чем-то лучше, чем-то хуже. Как именно, зависит от компилятора по части разных методов оптимизации указателей и значений переменных. Указатель придётся грубо приводить к обычной переменной, но и фиг с ним.

 

=================================

 

Ещё одну недоработку родил. Хотя, может есть вариант прямого обхода, а не через переменную.

 

Когда в выражении юзаются две или более volatile, то компилер выдаёт варнинг, что "доступ к volatile не определён (не обозначен?) в выражении". Не очень понятно, как он расчитывает чтобы я его обозначил. Но можно было бы например задать скобками. Бувквально так ggg = abc + (volvar1) + volvar2; Тогда уровень вложенности скобок для volatile будет задавать приоритет доступа. Чем больше скобок, тем раньше доступ. При равном количестве - варнинг, означающий что реализация вычисления на откуп компилятора.

 

У меня такая ситуация происходит при сравнении (вне прерывания) volatile переменной временнОй метки и значения таймера, когда прерывание может изменить значение этой временнОй метки. При этом обязательно временнУю метку нужно прочитать раньше значения таймера, если произойдёт наоборот, то временнАя метка может "обогнать" значение из таймера, что вери вери бэд. Щас сделано через врЕменную переменную. Но из-за этого компилятор её суёт в стек (ИАР MCS-51). Upd. Хотя вот тут щас уже не суёт, но это не принципиально.

Изменено пользователем GetSmart

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А мне бы хотелось вот какую доработку - чтобы написать в редакторе прямо русскими словами "Уважаемый компилятор с оптимизатором, сделай мне хороший, быстрый и правильно работающий код" - и он бы сам все сделал :rolleyes:

 

ЗЫ МК всегда все делает "правильно", честно бежит по РИСК или ЦИСК командам и выполняет их. И если результат не нравится разработчику, то пусть ищет свои ошибки. А если он (разработчик) не опускается до asm, а пишет на ЯВУ (наяву - каламбурчик :rolleyes: ), то вдобавок к логике необходимо знать все тонкости и особенности компилятора вплоть до индивидуальных багов/фичей используемой версии. Это в принципе непросто, вот поэтому и получается типа "пишу одно а он мне делает не так". Закон Джоэла Спольски - все нетривиальные абстракции дырявы :rolleyes:

Вот тут http://electronix.ru/forum/index.php?showtopic=95060 я безуспешно пытался многабуквенно это имховыражать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чем больше скобок, тем раньше доступ. При равном количестве - варнинг, означающий что реализация вычисления на откуп компилятора.

Дык, слева направо! :laughing: И при этом CSE идёт лесом.

 

Вот тут http://electronix.ru/forum/index.php?showtopic=95060 я безуспешно пытался многабуквенно это имховыражать.

Так Вы спрашивайте! В определенный период каждый первый страдает подобным.

Кстати, при изучении любого вопроса имхо полезно "в пику" создавать свой вариант решения.

Для облегчения понимания, прежде всего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дык, слева направо! :laughing: И при этом CSE идёт лесом.

А мне скобки больше нравятся. Больше гибкость.

Мне например будет не нравиться такая штука

time = -stamp+timer;

чтобы временнАя метка прочиталась раньше.

 

Причём скобки можно оптимизировать как обычно, удаляя лишние, но при разборе выражения для волатилов запоминать уровень.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я тут про прерывания подумал...

В стандарте языка они не определены и являются расширением конкретного компилятора, который всё-же должен следовать стандарту. И если сказано, что volatile пишется/читается всегда - он должен это делать.

Тем более, предложенная вами оптимизация может приводить и к негативным последствиям.

К примеру у меня регистр какой-нибудь переферии определен как volatile. И вот я его в прерывании читаю,пишу, а он мне берет всё это оптимизирует и только перед выходом записывает. Аналогично и считывает только один раз. А у меня в это время по UART байтик пришел. Как я его увижу, если всё соптимизировано )

Тогда получится нужно ещё и вводить типа super volatile который в прерываниях уже не оптимизируется ))

 

Ну т.е. сомнительная такая оптимизация получается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

volatile int some;
int *someptr = &some;
*someptr += 2;

Ы?

Внезапно обнаружил такую вещь.

volatile int *someptr;        // компилятор может запросто оптимизируя удалить присванивание этой переменной

int *volatile someptr;        // а этой компилятор не удалит

Вобщем это и понятно.

Но тогда вопрос к знатокам: если в самом начале строки с объявлением переменной будет "static", то всегда ли это (вне функций допустим) будет означать видимость переменной внутри модуля, или в первом случае (как и действие volatile) квалификатор будет засчитан к объекту, на который ссылается переменная, а не к самой переменной?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый вечер. Я знаю что мой вопрос несколько не в тему, поэтому заранее извеняюсь. Подскажите пожалуйста кто может помочь в написании программ на Ассемблере для микроконтроллеров PIC и MCS. Вот пример одного из заданий. Составить алгоритм и программу на языке Ассемблер для МП типа MCS –51, выполняющую логическое умножение содержимого порта Р1 и аккумулятора, в случае равенства результата нулю, устанавливающую в единицу флаг 22h. Для знающего человека это пара минут, а для меня полный мрак и даже хуже. Помогите, кто чем сможет!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Лишь только программист в состоянии определить, когда наступает этот момент "когда надо". Ни один компилятор угадать его не сможет.
Компилятору можно попробовать объяснить областями видимости, кешировать нужные переменные в нужных блоках кода, запись назад при выходе кеша из области видимости:

http://electronix.ru/forum/index.php?showt...mp;#entry535341

 

А вообще — разве не так?

class foo {
public:
    state_t get_state() volatile // volatile переехало сюда -- для пользователей класса
    {
        return state; // ну при sizeof(state_t) > sizeof(sig_atomic_t) ещё заворачивать в крит. секцию
    }
private:
    state_t state; // не-volatile для обработчика прерываний
    INLINE void isr(); // обработчик прерываний топчется по state как хочет
};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не понял вопрос.

Какая запись и где должна быть нужна. Имеется ввиду очередная собака - "сеттер"? (Витус Вагнер недавно говорил о том, что геттеры надо бы ретриверами называть, вместе с сеттерами и пойнтерами отличная псарня была бы)

Так пример короткий для общего понимания, setter-функция часто и не нужна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

До кучи

Ну вот. И эти товарищи встали на грабли. На самом деле из двух объявлений, только одно объявление волатильной переменной. Второе объявление есть объявление обычной переменной - указателя на волатильную.

post-16753-1331292062_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...