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

 
 
7 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Вопрос к знатокам С.
demiurg_spb
сообщение Oct 20 2008, 16:04
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Возник тут вопрос.
Кусочек программы можно написать двумя способами,
но с одним и тем же правильным результатом (компилятор avr-gcc 4.1.2).
Вопрос: это можно взять на вооружение?
И что стандарт может нам сказать по этому поводу?
Спасибо.
Код
//============================================
    unsigned char temp;

    temp = *uart->pUDR;   // Очищаем буфер 3-его уровня.
    temp = *uart->pUDR;  
    temp = *uart->pUDR;  

//============================================
    *uart->pUDR;   // Очищаем буфер 3-его уровня.
    *uart->pUDR;  
    *uart->pUDR;


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 20 2008, 16:17
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Oct 20 2008, 18:04) *
Вопрос: это можно взять на вооружение?

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 20 2008, 17:27
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Спасибо за подсказку.
Я, по незнанию, наверное, всегда делал присвоение промежуточной переменной. Что-то подсказывает, что второй вариант тоже законный, но тщательное чтение стандарта C99 не помогло выявить пункт, который это подтверждает. Не могли бы более знающие товарищи навести на этот пункт (пункты)?
С другой стороны, присваивание промежуточной переменной имеет одно преимущество: даже неискушённые в глубоких тонкостях языка Си поймут, что имелось в виду. На мой взгляд, это сильное преимущество. Не следует жертвовать читаемостью кода.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 20 2008, 18:05
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(scifi @ Oct 20 2008, 21:27) *
Спасибо за подсказку.

Всегда радsmile.gif
Цитата(scifi @ Oct 20 2008, 21:27) *
Я, по незнанию, наверное, всегда делал присвоение промежуточной переменной. Что-то подсказывает, что второй вариант тоже законный, но тщательное чтение стандарта C99 не помогло выявить пункт, который это подтверждает. Не могли бы более знающие товарищи навести на этот пункт (пункты)?
С другой стороны, присваивание промежуточной переменной имеет одно преимущество: даже неискушённые в глубоких тонкостях языка Си поймут, что имелось в виду. На мой взгляд, это сильное преимущество. Не следует жертвовать читаемостью кода.

На мой взгляд читаемость лишь улучшается.
А вот первоисточник сего финта найти надо, да как вообще это называется очень хочется узнать, чтоб знать хоть что искать.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 20 2008, 18:17
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(scifi @ Oct 20 2008, 19:27) *
...но тщательное чтение стандарта C99 не помогло выявить пункт, который это подтверждает.

Кроме прочитать, нужно еще и суть понимать.
1.Упоминание имени переменной означает обращение к ней. Это основы основ. Какие "подтверждения" еще требуются?
2.Для того, что бы "бесполезные" обращения не были выкинуты компилятором есть клбчевое слово volatile. Поиск по доукменту, надеюсь работает?
Цитата
С другой стороны, присваивание промежуточной переменной имеет одно преимущество: даже неискушённые в глубоких тонкостях языка Си поймут, что имелось в виду. На мой взгляд, это сильное преимущество. Не следует жертвовать читаемостью кода.

Вcе с точностью до наоборот sad.gif
1. Никаких "тонкостей" нет напрочь - это самые основы.
2. Введение неких ненужных переменных, получение воплей о их ненужности от компилятора, закрытие этих вопплей - да какая уж тут, простите, в результате "читаемость"!?
Цитата
А вот первоисточник сего финта найти надо,

"Финты" это как-раз с лишней переменной sad.gif не знаю, какой "умник" такой финт и с какого бодуна применил, но думаю, что его уже не найти smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 20 2008, 18:35
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Oct 20 2008, 22:17) *
1.Упоминание имени переменной означает обращение к ней. Это основы основ. Какие "подтверждения" еще требуются?

Контрпример: взятие адреса переменной. Имя упоминается, а обращения нет.

После дополнительного прочтения стандарта начинает вырисовываться:
- The expression in an expression statement is evaluated as a void expression for its side effects.
- A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.
Действительно, есть значение выражения, а для его получения необходимо обращение к полю сруктуры.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 20 2008, 19:11
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(scifi @ Oct 20 2008, 20:35) *
Контрпример: взятие адреса переменной. Имя упоминается, а обращения нет.

На то это и ДРУГАЯ ОПЕРАЦИЯ. Совсем другая - взятие адреса, а не значения.
Цитата
После...

Эко куда Вас понесло..... Зачем?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 20 2008, 19:34
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Oct 20 2008, 22:17) *
1.Упоминание имени переменной означает обращение к ней.

Цитата(zltigo @ Oct 20 2008, 23:11) *
На то это и ДРУГАЯ ОПЕРАЦИЯ. Совсем другая - взятие адреса, а не значения.

Я запутался... Взятие адреса - это совсем другая операция по сравнению с упоминанием имени переменной? То есть "var++" - это упоминание имени, а "&var" - нет?

Цитата(zltigo @ Oct 20 2008, 23:11) *
Эко куда Вас понесло..... Зачем?

Затем, что вопрошающий сказал: "И что стандарт может нам сказать по этому поводу?" Посему стараюсь приводить цитаты из стандарта, имеющие отношение к данному вопросу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 20 2008, 19:53
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(scifi @ Oct 20 2008, 23:34) *
Я запутался... Взятие адреса - это совсем другая операция по сравнению с упоминанием имени переменной? То есть "var++" - это упоминание имени, а "&var" - нет?

Если раскрутить, то получим такую цепочку:
var++;
var += 1;
var = var + 1;

Отсюда видно, что что тут происходит не только упоминание переменной всуеsmile.gif
А взятие адреса - это действие, которое никак не отражается на самой переменной -
происходит лишь загрузка в индексный регистр адреса переменной.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Oct 21 2008, 15:08
Сообщение #10


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(zltigo @ Oct 20 2008, 20:17) *
Поскольку регистры uart безвариантно являются и прописаны как volatile, то несомнено второй вариант, ибо явные промежуточные переменные просто совсем не нужны.



К примеру MSVS 2008 для ARM в обоих случаях генерит одинаковый код.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 21 2008, 15:57
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Oct 20 2008, 21:53) *
А взятие адреса - это действие, которое никак не отражается на самой переменной -
происходит лишь загрузка в индексный регистр адреса переменной.

Есть еще и другие операции, например декларирование, sizeof, ...
Цитата
Посему стараюсь приводить цитаты из стандарта, имеющие отношение к данному вопросу.

Ну не обязан стандарт заменять учебник арифметики.
Пишем:
a = b
проговариваем как первоклашки на уроке арифметики - "взяли значение переменной 'b' и присвоили его переменной 'a'"
Теперь пишем:
b
проговариваем - "взяли значение переменной 'b'". И... и все. Все, что нам надо, мы сделали! Ничего лишнего и мутного. Чего не понятно-то? Какие какие такие "тонкости C"?


Цитата(sergeeff @ Oct 21 2008, 17:08) *
К примеру MSVS 2008 для ARM в обоих случаях генерит одинаковый код.

Ну и что? Слава оптимизации! Сначала читатель продирается через нагрможденение ненужностей, потом компилятор. Если оба поняли, что все эти "финты" не нужны совсем, то результаты, етественно будут одинаковые - БЕЗ ФИНТОВ.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Oct 21 2008, 17:01
Сообщение #12


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Без финтов - это отлично, но!!! - очень непривычно. Чтение из переменной очевидно, когда оно стоит справа от знака присваивания. И когда этот знак опущен это и вызывает недоумение и неприятие.

Я думаю, если бы разместить где-нибудь на форумах вопрос типа: "Что означает выражение для переменной volatile int x?: x;"

абсолютное большинство ответит неправильно. Посему, учитывая, что всех не переучишь, и почти все люди работают в коллективах, я бы именно из этих соображений оставил бы: int temp = x;.

Коллеге zltigo респект за неординарный подход. Тем более, что почти аналогичное использование чтения переменной, например, в while(x) ни у кого вопросов не вызвало бы.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 21 2008, 17:06
Сообщение #13


Гуру
******

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



Цитата(sergeeff @ Oct 21 2008, 21:01) *
Коллеге zltigo респект за неординарный подход.

Это единственно верный подход. Или предпочитаете ворнинги давить всем коллективом?
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 21 2008, 17:42
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Итак, итоги:
1) Согласно стандарту языка для чтения volatile переменной var достаточно написать
Код
var;

Кому интересно, могу подкрепить это цитатами из стандарта.
2) Очевидно, что такой код не проходит тест "даже моя бабушка поймёт, что это значит". Другими словами, читаемость кода страдает.
3) Вывод. Каждый решает сам, что лучше:
- пожетворать читаемостью кода
- бороться с предупреждениями компилятора при присваивании вспомогательной переменной
Код
dummy = var;


Итак, задача сведена к спору "читаемость кода против подавления предупреждений компилятора". Как известно, такой спор заведомо неразрешим, так что дальнейшие дискуссии результата не принесут :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 21 2008, 17:52
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(scifi @ Oct 21 2008, 19:42) *
Другими словами, читаемость кода страдает.

Это утверждение абсолютно ложное sad.gif, посему и "вывод" такой-же.
Код
var; // Это читабельно

А что-то типа такого, даже максимально обвешенного для понимания ненужности "финтов":
Код
{
int tmp = var;
tmp = tmp;
}  // Много, много хуже.

А такое:
Код
tmp = var; // Вообще безобразие


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


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


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