реклама на сайте
подробности

 
 
7 страниц V  « < 2 3 4 5 6 > »   
Reply to this topicStart new topic
> Вопрос к знатокам С.
aaarrr
сообщение Nov 11 2008, 12:33
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



RVCT на пропуск операнда ругается.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2008, 13:17
Сообщение #47


Нечётный пользователь.
******

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



Цитата(IgorKossak @ Nov 11 2008, 12:09) *
Те же самые рассуждения можно провести и в случае
Код
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); то в первую очередь подумаю что тут ошибка, проскочила лишняя ; ).
Либо кто-то должен доказать мне со ссылками на стандарт, что он имеет право так делать.

Цитата(ARV @ Nov 11 2008, 13:13) *
а, простите, разве писать читаемый всеми код - это уже признак дурного стиля программирования?
...
P.S. Имхо, то, что язык позволяет писать конструкции, с трудом поддающиеся расшифровке "простыми смертными", еще не означает, что так писать - хорошо или круто. в русском языке много матерных оборотов, однако их использование в речи все-же осуждается... равно как и арго и т.п. сленг...

Что значит "всеми"? Совсем-совсем всеми?
Вот Ваш P.S. с все поймут? Или "все, имеющие уровень образования выше некоторого порога"?
И причём тут маты?
Так что, на мой взгляд, тут скорее "в русском языке много разных способов посттроения предложений, однако для того, чтобы быть понятым всеми, стоит избегать сложных предложений, да и вообще - наличие запятых не ещё не означает, что стоит их ставить в предложениях".
"Все" понимают рекламу, это "хороший стиль рекламы".
Но не все понимают сложный язык литературных произведений, пользующихся всей мощью русского языка и это их хороший стиль. Отменим? Оставим только понимаемые всеми?


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 11 2008, 13:31
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(VladimirYU @ Nov 11 2008, 14:57) *
SPSR это регистр статуса SPI, все I/O регистры описаны в .h как VOLATILE

Они там описаны как __io union, никаких volatile в помине нет.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2008, 13:42
Сообщение #49


Нечётный пользователь.
******

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



Цитата(VladimirYU @ Nov 11 2008, 13:42) *
Все правильно, но вот конструкция, например
Код
char tmp = SPSR; // tmp далее не исп.;

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

нет.
М.б. все таки "тупое" явное чтение в переменную более надежно,
чем варианты предлагаемые гуру.
IAR 4.12 оптимизация отключена.
"оптимизация отключена" - это не то для таких проверок.
При "оптимизация откулючена" компилятор вообще должен бы делать всё "строго как написано", т.е. если написано подряд десять присваиваний в какую-то (не-volatile) переменную, то все десять и написать. И для первого фрагмента даже при не-volatile SPSR мог бы и прочитать, и записать. "Благодаря" этому и прижилась такая конструкция для "гарантированного чтения" со времён компиляторов с недоразвитой оптимизацией - исправно читали не-volatile - переменную в не-volatile-переменую.
По моему мнению, конструкция если и имеет право на жизнь, то только как обход ошибочно не объявленного как volatile регистра в не подлежащих изменению h-файлах. В такой форме
volatile char tmp = non_volatile_var;
А вот если со включенной оптимизацией для указанных выше фрагментов кода генерируется разный код, то, на мой взгляд, что-то тут не то.

Цитата(VladimirYU @ Nov 11 2008, 13:42) *
Может и не убедительный, но все же аргумент в пользу "тупых" конструкций.
Пользуясь уже проскочившей аналогией, эта конструкция - "арго", "сленг" gcc. Использовать или нет - зависит от условий. Так же как и сленг в любой другой области - между своими повышает эффективность общения (в данном случае "между своими" - это "рассчитывая на компилятор gcc и на активно использующих его на полную катушку"). Чужим непонятно, но стоит ли ради "общепонятности" жертвовать эффективностью - решать каждый раз пишущему.
Ещё раз напоминаю про ++i и i++ и указатели - то же самое, только на более низком пороге "свой-чужой", "общепонятности - не общепонятности". Бывает трудно понимается.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Nov 11 2008, 13:43
Сообщение #50


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(aaarrr @ Nov 11 2008, 16:31) *
Они там описаны как __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
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2008, 13:46
Сообщение #51


Нечётный пользователь.
******

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



Цитата(aaarrr @ Nov 11 2008, 15:31) *
Они там описаны как __io union, никаких volatile в помине нет.

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

Цитата(VladimirYU @ Nov 11 2008, 15:43) *
Разочарую Вас. Сорри, но не умею выделять в окошке кодов:

Ну если так...
А проверьте то же самое с явно заданной
Код
volatile char vch;
а не с SPSR.
Может где-то отвалилась volatile-ность __io_memory


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Nov 11 2008, 13:46
Сообщение #52


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(aaarrr @ Nov 11 2008, 16:31) *
Они там описаны как __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
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 11 2008, 13:51
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(VladimirYU @ Nov 11 2008, 16:43) *
Разочарую Вас.

Интересно. А если принудительно объявить его как volatile? Или провести эксперимент с обычной volatile переменной, как советует уважаемый ReAl?
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Nov 11 2008, 13:59
Сообщение #54


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(ReAl @ Nov 11 2008, 16:46) *
Может где-то отвалилась 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 }
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 11 2008, 14:05
Сообщение #55


Гуру
******

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



Цитата(VladimirYU @ Nov 11 2008, 16:59) *
То же самое
Рискну повторить вопрос aaarrr из поста №38 - у вас точно не включен режим C++?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 11 2008, 14:10
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Сергей Борщ @ Nov 11 2008, 17:05) *
Рискну повторить вопрос aaarrr из поста №38 - у вас точно не включен режим C++?

Да нет, тут дело, похоже, в том, что переменная локальная.
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Nov 11 2008, 14:24
Сообщение #57


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(Сергей Борщ @ Nov 11 2008, 17:05) *
Рискну повторить вопрос aaarrr из поста №38 - у вас точно не включен режим C++?


Конечно, Сергей, прав a14.gif
В режиме С все читается нормально, был С++.
Go to the top of the page
 
+Quote Post
ARV
сообщение Nov 11 2008, 17:32
Сообщение #58


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(aaarrr @ Nov 11 2008, 14:15) *
Ворнинг выдает, т.к. temp не используется после присвоения.
возможно, степень выдачи ворнингов - параноидальная? как мне кажется, это настраивается... WinAVR не выдает ничего с опцией -Wall


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

Цитата(ReAl @ Nov 11 2008, 16:17) *
Что значит "всеми"? Совсем-совсем всеми?
Вот Ваш P.S. с все поймут? Или "все, имеющие уровень образования выше некоторого порога"?
И причём тут маты?
Так что, на мой взгляд, тут скорее "в русском языке много разных способов посттроения предложений, однако для того, чтобы быть понятым всеми, стоит избегать сложных предложений, да и вообще - наличие запятых не ещё не означает, что стоит их ставить в предложениях".
"Все" понимают рекламу, это "хороший стиль рекламы".
Но не все понимают сложный язык литературных произведений, пользующихся всей мощью русского языка и это их хороший стиль. Отменим? Оставим только понимаемые всеми?

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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Nov 11 2008, 17:39
Сообщение #59


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ARV @ Nov 11 2008, 20:18) *
возможно, степень выдачи ворнингов - параноидальная? как мне кажется, это настраивается... WinAVR не выдает ничего с опцией -Wall

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

Цитата(ARV @ Nov 11 2008, 20:18) *
off: подозреваю, что все одиозные уязвимости и проблемы Windows вытекают из "виртуозности" кодировщиков, с которой компилятор не справляется biggrin.gif

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

Цитата(ARV @ Nov 11 2008, 20:32) *
так ради чего сыр-бор?! какова конечная цель: получить всегда гарантированно однозначно воспринимаемый человеком и дающий всегда верный результат код или создать некое произведение искусства, понять которое без опытнейших искуствоведов никто не в силах, и которое транслируется одинаково далеко не во всех случаях?

Цель - не получить сотню-другую "левых" ворнингов при сборке проекта, среди которых так легко теряются "нужные".
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2008, 18:53
Сообщение #60


Нечётный пользователь.
******

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



Цитата(ARV @ Nov 11 2008, 19:32) *
возможно, степень выдачи ворнингов - параноидальная? как мне кажется, это настраивается... WinAVR не выдает ничего с опцией -Wall

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

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

Написать присваивание какой-то переменной там, где оно не нужно и для переменной, которая больше нигде не используется, или 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. По крайней мере в случае С.
Надо разобраться, что там с С++ - мне казалось, что базоыве вещи должны были остаться и там, иначе нет той совместимости, которая декларировалась.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

7 страниц V  « < 2 3 4 5 6 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 07:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01519 секунд с 7
ELECTRONIX ©2004-2016