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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> IAR: вопрос типа "глазам не верю"
ARV
сообщение Jan 20 2012, 07:08
Сообщение #1


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

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



Неужели правда в IAR в результате такого кода
Код
volatile unsigned char v1 = 1;
volatile unsigned char  v2 = 255;
volatile unsigned char  v3 = 2;


if (v1 == (v2+v3))
   PORTB = 0;
else
   PORTB = 1;
в PORTB действительно будет выведен 0? наткнулся на тему на другом форуме - говорят, таки да...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jan 20 2012, 07:12
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ARV @ Jan 20 2012, 11:08) *
Неужели правда в IAR в результате такого кодав PORTB действительно будет выведен 0? наткнулся на тему на другом форуме - говорят, таки да...

А почему бы и нет?
255 + 2 = 1;
1 == 1;
PORTB = 0;


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ARV
сообщение Jan 20 2012, 07:13
Сообщение #3


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

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



ну потому, что как бы 1 должно выводиться... WinAVR, например, именно так поступает sm.gif


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
arttab
сообщение Jan 20 2012, 07:27
Сообщение #4


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

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



ff это 255 т.е. максимальное значение. 255 + 1 = 0. поясню ff + 1h = 100h поскольку unsigned char получаем 00h
соответственно ffh +2 = 101h -> 01h


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
ARV
сообщение Jan 20 2012, 07:39
Сообщение #5


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

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



а как же быть с тем, что по стандарту языка Си в выражениях char автоматически преобразуется к int?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jan 20 2012, 07:48
Сообщение #6


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ARV @ Jan 20 2012, 11:39) *
а как же быть с тем, что по стандарту языка Си в выражениях char автоматически преобразуется к int?

Озвучьте номер стандарта, где такое описано.
Код
#if !defined(__STDINT_H_)
#define __STDINT_H_

/*
*    ISO C99: 7.18 Integer types <stdint.h>
*/

#ifndef __int8_t_defined
#define __int8_t_defined
typedef signed char                             int8_t;
typedef int                                     int16_t;
typedef long int                                int32_t;
__extension__ typedef long long int             int64_t;

typedef unsigned char                           uint8_t;
typedef unsigned int                            uint16_t;
typedef unsigned long int                       uint32_t;
__extension__ typedef unsigned long long int    uint64_t;
# endif

Это в mspgcc. Не думаю, что WinAVR сильно отличается.

Из другого места:

Код
#ifndef __INTTYPES_H_
#define __INTTYPES_H_

#ifndef __int8_t_defined
#define __int8_t_defined
/* Use [u]intN_t if you need exactly N bits.
   XXX - doesn't handle the -mint8 option.  */

typedef signed char int8_t;
typedef unsigned char uint8_t;

typedef int int16_t;
typedef unsigned int uint16_t;

typedef long int32_t;
typedef unsigned long uint32_t;

typedef long long int64_t;
typedef unsigned long long uint64_t;
#endif


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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ARV
сообщение Jan 20 2012, 07:59
Сообщение #7


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

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



я не супер-знаток стандарта, и тем более его пунктов и подпунктов, но точно помню, что в нем сказано буквально следующее: при вычислении выражений переменные типа char и unsigned char всегда неявно преобразуются к типу int и unsigned int соответственно. именно результат такого преобразования я наблюдаю в WinAVR, который, если не ошибаюсь, декларирует полное соответствие стандарту Си. более того, если упомянутый ранее код слегка видоизменить, то он работает именно так, как вы и говорите:
Код
volatile unsigned char v1 = 1;
volatile unsigned char  v2 = 255;
volatile unsigned char  v3 = 2;

unsigned char v4;
v4 = v2 + v3;
if (v1 == v4)
   PORTB = 0;
else
   PORTB = 1;
в данном случае на самом деле v4 будет содержать значение 0x01, хотя результат ВЫРАЖЕНИЯ v2+v3 будет равен 0x0101;

собственно, я и задал вопрос с целью разобраться в этом вопросе: жду, пока Сергей Борщ или иной специалист, хорошо знающий стандарт, даст пояснения.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jan 20 2012, 08:14
Сообщение #8


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ARV @ Jan 20 2012, 11:59) *
я не супер-знаток стандарта, и тем более его пунктов и подпунктов, но точно помню, что в нем сказано буквально следующее: при вычислении выражений переменные типа char и unsigned char всегда неявно преобразуются к типу int и unsigned int соответственно.

Ну вот теперь все встало на свои места.
Спасибо за разъяснения!
То, что у ИАРа своя логика, иногда противоречащая стандартам, и так известно.
У меня с ним отношения не сложились, и как раз касательно if()-ов. Столько раз получал граблями в лоб, но постепенно привык.
А теперь вот на GCC переполз.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ARV
сообщение Jan 20 2012, 08:21
Сообщение #9


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

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



Цитата(MrYuran @ Jan 20 2012, 12:14) *
Ну вот теперь все встало на свои места.
Спасибо за разъяснения!
оно-то, конечно, пожалуйста... но как бы я сам разъяснения просил rolleyes.gif


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
sparcmaster
сообщение Jan 20 2012, 08:22
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 93
Регистрация: 13-01-12
Из: Гатчина
Пользователь №: 69 333



Цитата из Шилдта:
Цитата
Преобразования типов в выражениях

Если в выражении встречаются переменные и константы разных типов, они преобразуются к одному типу. Компилятор преобразует "меньший" тип в "больший". Этот процесс называется продвижением типов (type promotion). Сначала все переменные типов char и short int автоматически продвигаются в int. Это называется целочисленным расширением. (В С99 целочисленное расширение может также завершиться преобразованием в unsigned int.) После этого все остальные операции выполняются одна за другой, как описано в приведенном ниже алгоритме преобразования типов:

IF операнд имеет тип long double
THEN второй операнд преобразуется в long double
ELSE IF операнд имеет тип double
THEN второй операнд преобразуется в double
ELSE IF операнд имеет тип float
THEN второй операнд преобразуется в float
ELSE IF операнд имеет тип unsigned long
THEN второй операнд преобразуется в unsigned long
ELSE IF операнд имеет тип long
THEN второй операнд преобразуется в long
ELSE IF операнд имеет тип unsigned int
THEN второй операнд преобразуется в unsigned int


У вас же случай, когда переменные одинаковых типов - т.е. IAR прав.

Сообщение отредактировал sparcmaster - Jan 20 2012, 08:24
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2012, 08:22
Сообщение #11


Гуру
******

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



QUOTE (ARV @ Jan 20 2012, 09:59) *
собственно, я и задал вопрос с целью разобраться в этом вопросе
Да, все верно вы рассуждаете. 255+2 = 257, 257 != 1. Сравнение должно производиться в intах. Оптимизатор может выкинуть проверку старшего байта если это не повлияет на результат, как в вашем примере с v4. Что ИАР там творит - не могу сказать, у него случайно не включена опция вроде "8-битный int"?


--------------------
На любой вопрос даю любой ответ
"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
ARV
сообщение Jan 20 2012, 08:31
Сообщение #12


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

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



ну, если я рассуждаю верно - это меня сильно успокоило. а что там включено в IAR-е я не знаю: я прочел на другом форуме спор по этой теме, и поразился. а там народ, юзающий IAR, просто утверждает, что у них работает вот так. настройки не были озвучены.

спасибо.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 20 2012, 08:34
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Сергей Борщ @ Jan 20 2012, 12:22) *
Да, все верно вы рассуждаете.

Верно ли? Цитата из стандарта
Цитата
In executing the fragment
char c1, c2;
/* ... */
c1 = c1 + c2;
the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to int size
and then add the two ints and truncate the sum. Provided the addition of two chars can be done without
overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only
produce the same result, possibly omitting the promotions.
Мои знания английского языка - не ахти какие, но, по-моему, стандарт говорит, что в данном случае "promotions" можно не выполнять.
Go to the top of the page
 
+Quote Post
ARV
сообщение Jan 20 2012, 08:49
Сообщение #14


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

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



ваша цитата четко подтверждает 2 вещи:
1. int promotions для char на самом деле определено в стандарте
2. для варианта С ПРИСВАИВАНИЕМ переменной типа char на самом деле смысла в promotions нет - я приводил пример ранее.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 20 2012, 09:06
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(ARV @ Jan 20 2012, 12:49) *
для варианта С ПРИСВАИВАНИЕМ переменной типа char на самом деле смысла в promotions нет - я приводил пример ранее.

ИМХО, стандарт допускает не использовать promotions с переменными типа char не в зависимости от оператора (присваивание или сравнение), а от
Цитата
...without overflow, or with overflow wrapping silently...
Кроме того, если выражение справа вычислять отдельно (как в вашем примере), то и выполнение оператора сравнения меняет результат. Что, по-моему, слабо согласуется с "correct result", упомянутому в стандарте.
Go to the top of the page
 
+Quote Post

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

 


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


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