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

 
 
> IAR 6.4 Optimization Bug, изменение работы алгоритма при включении оптимизации
Sagittarius
сообщение Oct 3 2012, 05:50
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659



Здравствуйте.

Была в проекте написана простая функция преобразования числа uint32 в строку, без оптимизации работает, при включении Optimization/High/Speed и наличии опции Function Inlining вместо всего числа в строку заносит только последнюю цифру. Функцию конечно поправил так чтоб работала и при оптимизации но как то все равно неприятно, где еще ждать косяков.
сам код:

CODE
//
///8*************************************************
// перевод числа i в строку символов в buf длиной = maxlen
uint32_t Int2Str(uint32_t i,uint8_t *buf,uint32_t maxlen){
uint32_t j;
uint32_t k,l;
uint32_t idx;

idx=0;
// используется только для преобразования даты
if((i<10000)&&(maxlen)&&(maxlen<=4)){
for(j=(maxlen-1);j;j--){
buf[idx]='0';
k=Pow10(j);
for(l=9;l;l--){
if(i>=k){
i-=k;
buf[idx]++;
}else l=1; // выход из цикла
}
idx++;
}
buf[idx]='0'+i;
idx++;
}
// buf[idx]=0;
return idx;
}

///8*************************************************
uint32_t Pow10(uint32_t p){// возвращает 10^p
uint32_t ret=1;
if(p>8)ret=0;
else{
for(;p;p--)ret*=10;
}
return ret;
}




Отдельный проект с этими функциями в IAR:
Прикрепленный файл  iarbug.rar ( 15.32 килобайт ) Кол-во скачиваний: 76

Было обнаружено на STM32F103, проверено наличие бага и для LPC2378

Спасибо.
Go to the top of the page
 
+Quote Post
4 страниц V  < 1 2 3 4 >  
Start new topic
Ответов (15 - 29)
chernenko
сообщение Oct 3 2012, 13:03
Сообщение #16


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

Группа: Свой
Сообщений: 170
Регистрация: 8-02-06
Из: Москва
Пользователь №: 14 116



Цитата(KRS @ Oct 3 2012, 16:52) *
так писали про 6.4

Я понимаю. Я написал для статистики, что результат свойственен последней версии и в одной из предыдущих все работает.
Go to the top of the page
 
+Quote Post
Lotor
сообщение Oct 3 2012, 13:42
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Таки глюк компилятора...

PS: Как действовать автору топика в подобных ситуациях наглядно продемонстрировал KRS. =)


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post
KRS
сообщение Oct 3 2012, 14:21
Сообщение #18


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



а новый компилер 6.40.4 (кажется) кто нибудь использует?
надо бы в ЯР код послать, если не исправили еще
Go to the top of the page
 
+Quote Post
Sagittarius
сообщение Oct 4 2012, 07:24
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659



Цитата(KRS @ Oct 3 2012, 17:21) *
а новый компилер 6.40.4

IAR C/C++ Compiler for ARM
6.40.4.24170 (6.40.4.24170)
C:\Program Files (x86)\IARM64\arm\bin\iccarm.exe
13/Sep/2012 05:19:20, 27336704 bytes

все еще бажит
Go to the top of the page
 
+Quote Post
KRS
сообщение Oct 4 2012, 07:29
Сообщение #20


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Глючат именно циклы с предусловием (и не только циклы с goto тоже самое) но с проверкой условия в начале.
Причем независимо от управляющей переменной!
из этих функций нормально компилируются только нечетные!
CODE
void test_bug4(uint8_t *buf)
{
unsigned i;
unsigned j;
j=100;
i=0;
while(i<10){
buf[i++]=j;
j-=2;
}
buf[i]=0;
}

void test_bug5(uint8_t *buf)
{
unsigned i;
unsigned j;
j=100;
i=0;
do {
buf[i++]=j;
j-=2;
} while(i<10);
buf[i]=0;
}

void test_bug6(uint8_t *buf)
{
unsigned i;
unsigned j;
j=100;
i=0;
while(j>0){
buf[i++]=j;
j-=2;
}
buf[i]=0;
}

void test_bug7(uint8_t *buf)
{
unsigned i;
unsigned j;
j=100;
i=0;
do {
buf[i++]=j;
j-=2;
}while(j >0);
buf[i]=0;
}

void test_bug8(uint8_t *buf)
{
unsigned i;
unsigned j;
j=100;
i=0;
loop:
if (i < 10) {
buf[i++]=j;
j-=2;
goto loop;
}
buf[i]=0;
}

void test_bug9(uint8_t *buf)
{
unsigned i;
unsigned j;
j=100;
i=0;
loop:
buf[i++]=j;
j-=2;
if (i < 10)
goto loop;
buf[i]=0;
}


Сообщение отредактировал IgorKossak - Oct 4 2012, 07:52
Причина редактирования: [codebox] для длинного кода!!!
Go to the top of the page
 
+Quote Post
VslavX
сообщение Oct 4 2012, 07:38
Сообщение #21


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Версия 5.41 - генерирует нормально. Мда, никак оно на 6.x перейти не получается, серьезно будем рассматривать GCC от CodeSourcery/Mentor.


Цитата(KRS @ Oct 4 2012, 10:29) *
Глючат именно циклы с предусловием

Что-то с тестированием в ЯР плоховато. Такие косяки можно автоматическими тестами выловить. Скомпилируй и запусти на реальном железе - все быстро вылезет.
Go to the top of the page
 
+Quote Post
grisha_scorpion
сообщение Oct 10 2012, 07:33
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 24-08-10
Пользователь №: 59 074



Используйте квалификатор volatile. И будет вам счастье. Справка: Квалификатор volatile указывает компилятору на то, что значение переменной может измениться независимо от программы, т.е. вследствие воздействия еще чего-либо, не являющегося оператором программы. Например, адрес глобальной переменной можно передать в подпрограмму операционной системы, следящей за временем, и тогда эта переменная будет содержать системное время. В этом случае значение переменной будет изменяться без участия какого-либо оператора программы. Знание таких подробностей важно потому, что большинство компиляторов С автоматически оптимизируют некоторые выражения, предполагая при этом неизменность переменной, если она не встречается в левой части оператора присваивания. В этом случае при очередной ссылке на переменную может использоваться ее предыдущее значение. Некоторые компиляторы изменяют порядок вычислений в выражениях, что может привести к ошибке, если в выражении присутствует переменная, вычисляемая вне программы. Квалификатор volatile предотвращает такие изменения программы.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 10 2012, 08:04
Сообщение #23


Гуру
******

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



QUOTE (grisha_scorpion @ Oct 10 2012, 10:33) *
Используйте квалификатор volatile. И будет вам счастье.
В данном случае он абсолютно не нужен, ибо "воздействия еще чего-либо, не являющегося оператором программы" тут нет.


--------------------
На любой вопрос даю любой ответ
"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
grisha_scorpion
сообщение Oct 10 2012, 10:58
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 24-08-10
Пользователь №: 59 074



Цитата(Сергей Борщ @ Oct 10 2012, 12:04) *
В данном случае он абсолютно не нужен, ибо "воздействия еще чего-либо, не являющегося оператором программы" тут нет.

Компилятор не знает есть внешнее воздействие или нет. Он не будет оптимизировать код где используются переменные с квалификатором volatile
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 10 2012, 11:09
Сообщение #25


Гуру
******

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



Цитата(grisha_scorpion @ Oct 10 2012, 14:58) *
Компилятор не знает есть внешнее воздействие или нет. Он не будет оптимизировать код где используются переменные с квалификатором volatile

Как способ обойти баг компилятора это, возможно, и сработает. Но автор уже обошёл его, поэтому ваше предложение не очень-то интересно. А пафос темы именно в том, что в компиляторе присутствует баг.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 10 2012, 12:55
Сообщение #26


Гуру
******

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



QUOTE (grisha_scorpion @ Oct 10 2012, 13:58) *
Компилятор не знает есть внешнее воздействие или нет.
Программист знает. Бага компилятора не является внешним воздействием, а других влияний на эти переменные нет. Прочитайте свою же справку и покажите, какая из перечисленных там причин подходит для этого кода.


--------------------
На любой вопрос даю любой ответ
"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
KRS
сообщение Oct 10 2012, 18:45
Сообщение #27


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



кстати с volatile тоже не все в порядке!
при цикле в 100 байт и присваивание 0. IAR сообразил что это очистка памяти и вызвал
___aaeabi_memclr
дальше не копал, но что то я сомневаюсь что эта функция будет по байтам 0 писать! А все таки раз уж volatile то менять байтовый доступ на словный не совсем корректно.
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 10 2012, 19:26
Сообщение #28


Гуру
******

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



Цитата(KRS @ Oct 10 2012, 22:45) *
кстати с volatile тоже не все в порядке!

Чем дальше в лес, тем толще партизаны!
Да уж, ЯР отжигает. Им пора "горячую линию" по поводу своих багов открывать...
Go to the top of the page
 
+Quote Post
MrAlex
сообщение Oct 11 2012, 08:35
Сообщение #29


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

Группа: Свой
Сообщений: 197
Регистрация: 15-10-10
Из: г. Москва
Пользователь №: 60 179



а что уже можно тип не указывать? только unsigned?
Go to the top of the page
 
+Quote Post
scifi
сообщение Oct 11 2012, 08:47
Сообщение #30


Гуру
******

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



Цитата(MrAlex @ Oct 11 2012, 12:35) *
а что уже можно тип не указывать? только unsigned?

Всегда можно было. Читайте учебники. K&R, к примеру.
Go to the top of the page
 
+Quote Post

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

 


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


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