|
Неожиданный результат, Прочитать два байта |
|
|
|
Jan 19 2008, 14:37
|
Знающий
   
Группа: Свой
Сообщений: 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; Во втором случае дает другой (правильный) результат. Почему?
|
|
|
|
|
 |
Ответов
|
Jan 19 2008, 14:45
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jan 20 2008, 12:17
|

Местный
  
Группа: Свой
Сообщений: 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);
|
|
|
|
|
Jan 20 2008, 18:59
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jan 20 2008, 21:34
|

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

|
Цитата(Aesthete Animus @ Jan 20 2008, 21:43)  Не дадите ссылочку на первоисточник - надо бы почитать для просвещения  Да запросто: Google -> ISO/IEC 9899, вторая ссылка дает pdf
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
Сообщений в этой теме
alux Неожиданный результат Jan 19 2008, 14:37 alux Я поражен меткости и, главное, оперативности Ваших... Jan 19 2008, 14:53   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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|