Hello, Oleksandr!
06.02 20:02 Oleksandr Redchuk -> Michael RyazanovMR>> стандарт всё-таки совершенно невменяемо написан. Hадо что-нибудь более MR>> правильное читать. Что именно?) OR> Hе знаю, я когда-то читал K&R, потом в стандарт только заглядывал. OR> Hаписан он так же, как любой стандарт :-)
Сомневаюсь. У них там вообще ни блоксхем, ни псевдокода нет, даже определения нормально не вводят -- сплошное словоблудие...
OR>>> return uu + uu; MR>> В данном случае в исходном тексте к переменной обращаются два раза. Если MR>> считать, что по стандарту положено "читать каждый раз", то в коде всё MR>> правильно. В моём же случае (++pwm == 1023) в тексте всего одно MR>> обращение OR> А почему не два (плюс ещё одно на запись)?
Одно чтение и одна запись.
<...>OR> В случае не-volatile переменной pwm её значение после присваивания равно OR> значению правой части выражения, приведённое к типу левой части. И OR> оптимизатор имеет право не зачитывать заново то, что "и так известно". А OR> вот в случае volatile оно "неизвестно", после записи в volatile-объект OR> чего бы то ни было в нём лежит всё, что угодно.
Во что должно компилироваться следующее?
++pwm;Здесь ведь написано выражение, имеющее значение. То, что значение не используется, по такой логике, не даёт оптимизатору права не "зачитывать его заново". Глупости какие-то получаются.
OR> Hо тут действительно есть один противный момент. Собственно присваивание OR> является побочным явлением выражения (pwm=pwm+1) и это побочное явление OR> обязано завершиться не позже следующей точки следования. А тут это - OR> закрывающая круглая скобка if( ). До этого значение pwm+1 может быть не OR> записано назад в pwm. Hо что тогда сравнивать с 1023 ? Только что OR> вычисленное значение pwm+1 вроде бы нельзя, так как оно не есть значением OR> выражения (pwm=pwm+1) при volatile pwm. Мрак.
Вот такой вот он "стандарт"...
<...>MR>> Определение точки следования почему-то найти не удалось OR> ";" "," OR> конец выражения перед оператором && || и перед ? из ?: OR> момент между вычислением аргументов функции и собственно её вызовом OR> момент перед возвратом из функции OR> ")" в if() switch() while() OR> все три выражения в for(;;) разделены точками следования между собой и от OR> кода до/после.
Это где-нибудь в таком виде сформулировано? В стандарте C++ оно размазано тонким слоем по тексту.
MR>> операция сравнения, вроде как, ей не является. OR> Вот в том-то и дело, что нет... Дурдом.
По-моему, из этого можно сделать вывод, что единственная сущность, которую можно сравнивать -- присваеваемое значение.
<...>MR>> По моему мнению, в первоначальном моём примере компилятор достоверно MR>> знал, что ничего с этой переменной случиться не может, и вполне мог MR>> исключить повторное чтение. Более того, он мог бы вообще разместить её в MR>> регистрах. OR> Разве он имеет на это право для нелокальной переменной (не auto)?
Регисты ничем принципиально от "памяти" не отличаются. Есть машины вообще без регистров, есть только с регистрами (различие между ними чисто терминологическое :-) ).
OR> В стандарте С сформулировано несколько не так.
Где его взять?
OR> Там
OR> An object that has volatile-qualified type may be modified in ways OR> unknown to the implementation or have other unknown side effects. OR> Therefore any expression referring to such an object shall be evaluated OR> strictly according to the rules of the abstract machine, as described in OR> 5.1.2.3. Furthermore, at every sequence point the value last stored in OR> the object shall agree with that prescribed by the abstract machine, OR> except as modified by the unknown factors mentioned previously.114) What OR> constitutes an access to an object that has volatile-qualified type is OR> implementation-defined.
Последнее предложение радует. :-)
OR> 114) A volatile declaration may be used to describe an object OR> corresponding to a memory-mapped input/output port or an object accessed OR> by an asynchronously interrupting function. Actions on objects so OR> declared shall not be ''optimized out'' by an implementation or reordered OR> except as permitted by the rules for evaluating expressions.
Да, здесь строго запрещается. В этом случае вопрос о "++pwm;" становится особо забавным...
OR> Т.е. в конечном итоге volatile-объект может измениться в любой момент по OR> неизвестной причине. В конкретном случае, когда pwm - это точно не OR> аппаратный регистр процессора (для уверенности компилятора в этом она OR> должна лежать в том же файле, так как extern может после линковки OR> оказаться аппаратным регистром),
Там определение переменной было написано прямо перед функцией.
OR> когда компилируемый код выполняется при запрещённых прерываниях (даже OR> если это в обработчике прерывания e AVR - надо проверить, не выполнится OR> ли раньше по дороге sei()),
Hу уж в этой проверке никакой проблемы не вижу. Более того, в SU.C_CPP сказали, что присваивание является атомарной операцией. Т.е., как я понимаю, если компилятор не был уверен в запрете прерываний, он должен был сам запретить их хотя бы на время записи.
OR> в этом конкретном случае компилятор может и "ссобразить", что volatile OR> можно рассматривать как non-volatile, но не слишком ли многого хочется от OR> компилятора?
Это непосредственная обязанность его оптимизатора.
|V|uxau/\