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

 
 
> Неожиданный результат, Прочитать два байта
alux
сообщение Jan 19 2008, 14:37
Сообщение #1


Знающий
****

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



Долго не мог выявить, почему цифровой датчик давления выдает неверный результат.
Код
//Первый случай;
resultat = ((unsigned int)i2c_read(ACK)<<8) | i2c_read(ACK);

//Второй случай:
HiTemp=i2c_read(ACK);        
LowTemp=i2c_read(ACK);
resultat = ((unsigned int)HiTemp<<8) | LowTemp;

Во втором случае дает другой (правильный) результат. Почему?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Jan 19 2008, 14:45
Сообщение #2


Гуру
******

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



Цитата(alux @ Jan 19 2008, 16:37) *
Во втором случае дает другой (правильный) результат. Почему?
Потому что стандарт языка С не определяет порядок вычисления подвыражений.
Какой из i2c_read() будет вызван первым зависит в общем случае от положения звезд на небе. Ваша функция обладает побочными эффектами, поэтому вызывать ее дважды в одном выражении не рекомендуется во избежание таких неожиданностей.


--------------------
На любой вопрос даю любой ответ
"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
Aesthete Animus
сообщение Jan 20 2008, 12:17
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(Сергей Борщ @ Jan 19 2008, 17:45) *
Потому что стандарт языка С не определяет порядок вычисления подвыражений.

Что значит, стандарт не определяет? Вот строчка из "K&R C": "Все бинарные операции и условная операция (прим. Перевод.: условная операция группируется справа налево; это изменение внесено в язык в 1978 г.) группируются слева направо"

Это следут проверить таким образом:
Код
resultat = ((HiTemp = (unsigned int)i2c_read(ACK))<<8) | (LowTemp = i2c_read(ACK));

printf("High byte 0x%02X\n", HiTemp);
printf("Low byte 0x%02X\n", LowTemp);
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2008, 18:59
Сообщение #4


Гуру
******

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



Цитата(Aesthete Animus @ Jan 20 2008, 14:17) *
Вот строчка из "K&R C": "Все бинарные операции и условная операция (прим. Перевод.: условная операция группируется справа налево; это изменение внесено в язык в 1978 г.) группируются слева направо"
Если под бинарными понимаются && и || - определен. Для остальных (кроме ?: и оператора "запятая") - нет. Вот цитата из стандарта языка (INTERNATIONAL STANDARD ISO/IEC 9899, Programming languages — C, Second edition 1999-12-01):
Цитата
6.5 Expressions
....
3 The grouping of operators and operands is indicated by the syntax. Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.
Это дает гораздо больше свободы оптимизатору.


Цитата(alux @ Jan 20 2008, 17:01) *
Вот что выдал листинг:
Мне пришло в голову, что во избежание подобных недоразумений функцию надо бы объявить как volatile. В этом случае:
1) Компилятор был бы обязан вызвать ее дважды.
2) IAR выдал бы предупреждение о неопределенности при использовании более одной volatile в выражении. GCC такое предупреждение не выдает, это ему минус. Хотя когда в IAR появилась эта проверка - многих предупреждение ставило в тупик. Вот, видимо, наглядный пример, когда это предупреждение обосновано.


--------------------
На любой вопрос даю любой ответ
"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
Aesthete Animus
сообщение Jan 20 2008, 19:43
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(Сергей Борщ @ Jan 20 2008, 21:59) *
Если под бинарными понимаются && и || - определен. Для остальных (кроме ?: и оператора "запятая") - нет. Вот цитата из стандарта языка (INTERNATIONAL STANDARD ISO/IEC 9899, Programming languages — C, Second edition 1999-12-01)...

Вот оно как... Не дадите ссылочку на первоисточник - надо бы почитать для просвещения smile.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- alux   Неожиданный результат   Jan 19 2008, 14:37
|- - alux   Я поражен меткости и, главное, оперативности Ваших...   Jan 19 2008, 14:53
||- - Сергей Борщ   Цитата(Aesthete Animus @ Jan 20 2008, 21...   Jan 20 2008, 21:34
|- - singlskv   Цитата(Сергей Борщ @ Jan 20 2008, 21:59) ...   Jan 20 2008, 22:07
|- - Dog Pawlowa   Цитата(singlskv @ Jan 21 2008, 02:07) Даж...   Jan 21 2008, 07:39
|- - singlskv   Цитата(Dog Pawlowa @ Jan 21 2008, 10:39) ...   Jan 21 2008, 20:54
|- - Сергей Борщ   Цитата(singlskv @ Jan 21 2008, 22:54) по ...   Jan 21 2008, 21:10
|- - singlskv   Цитата(Сергей Борщ @ Jan 22 2008, 00:10) ...   Jan 21 2008, 21:16
|- - Сергей Борщ   Цитата(singlskv @ Jan 21 2008, 23:16) кон...   Jan 21 2008, 23:13
|- - singlskv   Цитата(Сергей Борщ @ Jan 22 2008, 02:13) ...   Jan 22 2008, 08:50
|- - Сергей Борщ   Цитата(singlskv @ Jan 22 2008, 10:50) Воп...   Jan 22 2008, 11:57
|- - singlskv   Цитата(Сергей Борщ @ Jan 22 2008, 14:57) ...   Jan 22 2008, 12:44
|- - alux   Цитата(singlskv @ Jan 22 2008, 16:44) Авт...   Jan 22 2008, 13:31
|- - singlskv   Цитата(alux @ Jan 22 2008, 16:31) Прошу п...   Jan 22 2008, 17:53
|- - alux   Код 49 Accumulator = ((unsigned int...   Jan 22 2008, 19:47
|- - ReAl   Цитата(alux @ Jan 22 2008, 15:31) Кстати,...   Jan 22 2008, 21:17
|- - alux   Цитата(ReAl @ Jan 23 2008, 01:17) У IAR-а...   Jan 23 2008, 07:13
|- - ReAl   Я немного цитаты перетасую Цитата(alux @ Jan...   Jan 23 2008, 14:49
|- - alux   Цитата(ReAl @ Jan 23 2008, 18:49) в преды...   Jan 23 2008, 15:10
|- - Сергей Борщ   Цитата(alux @ Jan 23 2008, 17:10) ReAl ог...   Jan 23 2008, 15:30
|- - ReAl   Цитата(Сергей Борщ @ Jan 23 2008, 17:30) ...   Jan 24 2008, 08:04
- - Baser   Цитата(alux @ Jan 19 2008, 16:37) Долго н...   Jan 19 2008, 15:44
- - rezident   Я не такой большой специалист в Си и могу ошибатьс...   Jan 20 2008, 12:23
- - alux   Цитата(rezident @ Jan 20 2008, 16:23) ......   Jan 20 2008, 15:01


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

 


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


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