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

Вопрос к знатокам С.

Те же самые рассуждения можно провести и в случае
if(UDR);

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

Ну можно и

for( int i = 0; i < 1; ++i) if(UDR);

и результат опять будет тот же самый :-)

А на

if(UDR);

gcc выдаёт предупреждение "warning: empty body in an if-statement", а вот на

(void)UDR;

не выдаёт ничего и правильно делает. Зачем мне лишние предупреждения?

Собственно, в том конкретном случае, о котором говорил Сергей, тоже не ошибка была, а предупреждение, причём предупреждение правильное ("выражение ничего не делает"), которое помогло поймать неправильность компиляции :-)

И если компилятор нормально отрабатывает

if(UDR);

но шалит на

UDR;

то просто надо что-то делать с компилятором, хотя бы жаловаться в ООН, а как временную меру написать макрос, который прячет плохое поведение компилятора (чтобы спинной мозг не привыкал писать обходную конструкцию, а глаза не привыкали видеть - я, например, если увижу if(UDR); то в первую очередь подумаю что тут ошибка, проскочила лишняя ; ).

Либо кто-то должен доказать мне со ссылками на стандарт, что он имеет право так делать.

 

а, простите, разве писать читаемый всеми код - это уже признак дурного стиля программирования?

...

P.S. Имхо, то, что язык позволяет писать конструкции, с трудом поддающиеся расшифровке "простыми смертными", еще не означает, что так писать - хорошо или круто. в русском языке много матерных оборотов, однако их использование в речи все-же осуждается... равно как и арго и т.п. сленг...

Что значит "всеми"? Совсем-совсем всеми?

Вот Ваш P.S. с все поймут? Или "все, имеющие уровень образования выше некоторого порога"?

И причём тут маты?

Так что, на мой взгляд, тут скорее "в русском языке много разных способов посттроения предложений, однако для того, чтобы быть понятым всеми, стоит избегать сложных предложений, да и вообще - наличие запятых не ещё не означает, что стоит их ставить в предложениях".

"Все" понимают рекламу, это "хороший стиль рекламы".

Но не все понимают сложный язык литературных произведений, пользующихся всей мощью русского языка и это их хороший стиль. Отменим? Оставим только понимаемые всеми?

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


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

SPSR это регистр статуса SPI, все I/O регистры описаны в .h как VOLATILE

Они там описаны как __io union, никаких volatile в помине нет.

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


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

Все правильно, но вот конструкция, например

 char tmp = SPSR; // tmp далее не исп.;

генерит код чтения регистра а просто

 SPSR;

нет.

М.б. все таки "тупое" явное чтение в переменную более надежно,

чем варианты предлагаемые гуру.

IAR 4.12 оптимизация отключена.

"оптимизация отключена" - это не то для таких проверок.

При "оптимизация откулючена" компилятор вообще должен бы делать всё "строго как написано", т.е. если написано подряд десять присваиваний в какую-то (не-volatile) переменную, то все десять и написать. И для первого фрагмента даже при не-volatile SPSR мог бы и прочитать, и записать. "Благодаря" этому и прижилась такая конструкция для "гарантированного чтения" со времён компиляторов с недоразвитой оптимизацией - исправно читали не-volatile - переменную в не-volatile-переменую.

По моему мнению, конструкция если и имеет право на жизнь, то только как обход ошибочно не объявленного как volatile регистра в не подлежащих изменению h-файлах. В такой форме

volatile char tmp = non_volatile_var;

А вот если со включенной оптимизацией для указанных выше фрагментов кода генерируется разный код, то, на мой взгляд, что-то тут не то.

 

Может и не убедительный, но все же аргумент в пользу "тупых" конструкций.
Пользуясь уже проскочившей аналогией, эта конструкция - "арго", "сленг" gcc. Использовать или нет - зависит от условий. Так же как и сленг в любой другой области - между своими повышает эффективность общения (в данном случае "между своими" - это "рассчитывая на компилятор gcc и на активно использующих его на полную катушку"). Чужим непонятно, но стоит ли ради "общепонятности" жертвовать эффективностью - решать каждый раз пишущему.

Ещё раз напоминаю про ++i и i++ и указатели - то же самое, только на более низком пороге "свой-чужой", "общепонятности - не общепонятности". Бывает трудно понимается.

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


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

Они там описаны как __io union, никаких volatile в помине нет.

 

Разочарую Вас. Сорри, но не умею выделять в окошке кодов:

__io Controls the storage of data objects in I/O memory space, alternatively data memory

space.

The __io memory attribute implies that objects are __no_init and volatile, and allows

objects to be accessed by use of the special I/O instructions in the AVR microcontroller.

Your application may access the AVR I/O system by using the memory-mapped internal

special function registers (SFRs). To access the AVR I/O system efficiently, the __io

memory attribute should be included in the code.

Address range Max object size Pointer size Memory space

0-0x3F 4 bytes (32 bits) Pointers not allowed I/O

0x60-0xFF 4 bytes (32 bits) Pointers not allowed Data

Table 64: I/O address ranges

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


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

Они там описаны как __io union, никаких volatile в помине нет.

Если это так, то это ошибка того, кто эти h-файлы писал.

 

Разочарую Вас. Сорри, но не умею выделять в окошке кодов:

Ну если так...

А проверьте то же самое с явно заданной

volatile char vch;

а не с SPSR.

Может где-то отвалилась volatile-ность __io_memory

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


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

Они там описаны как __io union, никаких volatile в помине нет.

 

__io Controls the storage of data objects in I/O memory space, alternatively data memory

space.

The __io memory attribute implies that objects are __no_init and volatile, and allows

objects to be accessed by use of the special I/O instructions in the AVR microcontroller.

Your application may access the AVR I/O system by using the memory-mapped internal

special function registers (SFRs). To access the AVR I/O system efficiently, the __io

memory attribute should be included in the code.

Address range Max object size Pointer size Memory space

0-0x3F 4 bytes (32 bits) Pointers not allowed I/O

0x60-0xFF 4 bytes (32 bits) Pointers not allowed Data

Table 64: I/O address ranges

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


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

Разочарую Вас.

Интересно. А если принудительно объявить его как volatile? Или провести эксперимент с обычной volatile переменной, как советует уважаемый ReAl?

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


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

Может где-то отвалилась volatile-ность __io_memory

Такой глюк был в версии IAR3.20C, регистры I/O оптимизатор глазом не моргнув кэшировал. Но потом в начиная с 3.20D вроде его исправили.

Попробую просто с обычной переменной.

9 int main()

\ main:

10 {

11

12 volatile unsigned char vol_var;

13 vol_var;

14 return 0;

\ 00000000 E000 LDI R16, 0

\ 00000002 E010 LDI R17, 0

\ 00000004 9508 RET

15 }

То же самое

 

9 int main()

\ main:

10 {

\ 00000000 9721 SBIW R29:R28, 1

11

12 volatile unsigned char vol_var;

13 unsigned char novol_var = vol_var;

\ 00000002 8108 LD R16, Y

\ 00000004 2F20 MOV R18, R16

14 return 0;

\ 00000006 E000 LDI R16, 0

\ 00000008 E010 LDI R17, 0

\ 0000000A 9621 ADIW R29:R28, 1

\ 0000000C 9508 RET

15 }

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


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

То же самое
Рискну повторить вопрос aaarrr из поста №38 - у вас точно не включен режим C++?

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


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

Рискну повторить вопрос aaarrr из поста №38 - у вас точно не включен режим C++?

Да нет, тут дело, похоже, в том, что переменная локальная.

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


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

Рискну повторить вопрос aaarrr из поста №38 - у вас точно не включен режим C++?

 

Конечно, Сергей, прав :a14:

В режиме С все читается нормально, был С++.

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


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

Ворнинг выдает, т.к. temp не используется после присвоения.
возможно, степень выдачи ворнингов - параноидальная? как мне кажется, это настраивается... WinAVR не выдает ничего с опцией -Wall

 

 

off: подозреваю, что все одиозные уязвимости и проблемы Windows вытекают из "виртуозности" кодировщиков, с которой компилятор не справляется :biggrin:

 

Что значит "всеми"? Совсем-совсем всеми?

Вот Ваш P.S. с все поймут? Или "все, имеющие уровень образования выше некоторого порога"?

И причём тут маты?

Так что, на мой взгляд, тут скорее "в русском языке много разных способов посттроения предложений, однако для того, чтобы быть понятым всеми, стоит избегать сложных предложений, да и вообще - наличие запятых не ещё не означает, что стоит их ставить в предложениях".

"Все" понимают рекламу, это "хороший стиль рекламы".

Но не все понимают сложный язык литературных произведений, пользующихся всей мощью русского языка и это их хороший стиль. Отменим? Оставим только понимаемые всеми?

а что плохого в том, чтобы быть понятым всеми? или аура "продвинутости" тает при этом? мое мнение: применение "вывертов", которые допускает синтаксис Си, используется исключительно для того, чтобы выделить себя (личность) из ряда прочих (серостей). чем проще изложен алгоритм - тем меньше шансов, что будет допущена логическая ошибка в нем, заодно меньше неоднозначностей при переносе между разными компиляторами. витиеватость кода никак не отражается на оптимальности генерируемых ассемблерных конструкций (если, конечно, эта витиеватость правильно понята компилятором), и разница между i++ и i = i + 1 не видна абсолютно. и если этот пример оправдан хотя бы экономией 2-х (!!!) символов, то применение более "накрученных" штучек мало того что затрудняет восприятие кода другими, но еще может оказаться неверно понятым компилятором... так ради чего сыр-бор?! какова конечная цель: получить всегда гарантированно однозначно воспринимаемый человеком и дающий всегда верный результат код или создать некое произведение искусства, понять которое без опытнейших искуствоведов никто не в силах, и которое транслируется одинаково далеко не во всех случаях?

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


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

возможно, степень выдачи ворнингов - параноидальная? как мне кажется, это настраивается... WinAVR не выдает ничего с опцией -Wall

Степень нормальная и ворнинг вполне уместный.

 

off: подозреваю, что все одиозные уязвимости и проблемы Windows вытекают из "виртуозности" кодировщиков, с которой компилятор не справляется :biggrin:

Да, очень легко хаять программистов Майкрософт. А проблемы-то как раз и начинаются с подавления сообщений компилятора.

 

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

Цель - не получить сотню-другую "левых" ворнингов при сборке проекта, среди которых так легко теряются "нужные".

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


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

возможно, степень выдачи ворнингов - параноидальная? как мне кажется, это настраивается... WinAVR не выдает ничего с опцией -Wall

-Wall -Wextra, без --pedantic, хотя иногда стоит и его включать.

 

а что плохого в том, чтобы быть понятым всеми? или аура "продвинутости" тает при этом? мое мнение: применение "вывертов", которые допускает синтаксис Си, используется исключительно для того, чтобы выделить себя (личность) из ряда прочих (серостей).
Ну вот, то про маты что-то, то про ауру и выделение личности из серостей... "у кого что болит, тот о том и говорит"?

 

Написать присваивание какой-то переменной там, где оно не нужно и для переменной, которая больше нигде не используется, или if(UDR); там, где не нужно ничего проверять и рисовать для этого пустое тело if - это не "выверт", это "простое изложение алгоритма"?

Как на мой взгляд, так это как раз выверт для того, чтобы компилятор допёр до того, что надо всё же прочесть.

Приблизительно как FUNC(VAR + 0) в фортране - тоже был некий выверт для обхода неких особенностей.

Но дело в том, что если он не читает просто volatile_var; , то кто гарантирует, что при следующем витке развития он будет продолжать читать if(volatile_var); или temp = volatile_var; ?

Уповать на конкретную особенность конкретного оптимизатора конкретного компилятора - это "тем меньше шансов, что будет ошибка" ?

Да тут не между разными компиляторами, а между разными версиями одного компилятора или даже между разными ключами одной версии может переносимости не быть!

 

var; // это просто выражение
var+1; // тоже просто выражение
temp = var; // это присваивающее выражение

Все "выражения" (expression) должны быть абстрактной машиной "вычислены" или "оценены" (evaluate)

5.1.2.3 Program execution

1 The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.

2 Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,11) which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations

shall have taken place. (A summary of the sequence points is given in annex C.)

3 In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

Так вот первые два выражения в примере выше тоже должны быть "evaluated", как и третье.

И если в третьем переменная temp в этом файле нигде больше не используется и не глобальная (глобальность тоже может не помочь, кстати) и var не volatile, то компилятор имеет полное право выбросить его полностью - это не нарушит "observable behavior".

Повторюсь - когда-то давно не выбрасывал и во многих программах работы с аппаратурой вместо описания регистров ка volatile просто делали такое присваивание для принудительного чтения, и тянется жто до сих пор. Но это довольно быстро перестало помогать, как кстати и jmp на следующий адрес для задержки при обращении к медленным портам на PC.

А если var квалифицирована как volatile, то компилятор обязан зачитать её и в первом случае.

Во втором может иметь добрую волю выдать предупреждение, что результат вычисления var+1; нигде не используется, так же как и в третьем имеет право поворчать, что результат присвоения temp нигде не используется и выбросить запись в temp (но при этом обязан прочесть из var).

 

Поэтому я и говорю, что выверты с присвоением специально для этого заведёной переменной или if с пустым телом можно рассматривать только как обход ненормальности конкретного компилятора (либо, см. выше, докажите мне это со ссылкой на стандарт и я поменяю мнение), а не как хорошую практику программирования.

 

p.s. По крайней мере в случае С.

Надо разобраться, что там с С++ - мне казалось, что базоыве вещи должны были остаться и там, иначе нет той совместимости, которая декларировалась.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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