|
IAR 6.4 Optimization Bug, изменение работы алгоритма при включении оптимизации |
|
|
|
Oct 3 2012, 05:50
|
Местный
  
Группа: Свой
Сообщений: 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 Спасибо.
|
|
|
|
|
 |
Ответов
(15 - 29)
|
Oct 3 2012, 13:03
|
Частый гость
 
Группа: Свой
Сообщений: 170
Регистрация: 8-02-06
Из: Москва
Пользователь №: 14 116

|
Цитата(KRS @ Oct 3 2012, 16:52)  так писали про 6.4 Я понимаю. Я написал для статистики, что результат свойственен последней версии и в одной из предыдущих все работает.
|
|
|
|
|
Oct 4 2012, 07:24
|
Местный
  
Группа: Свой
Сообщений: 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 все еще бажит
|
|
|
|
|
Oct 4 2012, 07:29
|

Профессионал
    
Группа: Модераторы
Сообщений: 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] для длинного кода!!!
|
|
|
|
|
Oct 10 2012, 07:33
|
Участник

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

|
Используйте квалификатор volatile. И будет вам счастье. Справка: Квалификатор volatile указывает компилятору на то, что значение переменной может измениться независимо от программы, т.е. вследствие воздействия еще чего-либо, не являющегося оператором программы. Например, адрес глобальной переменной можно передать в подпрограмму операционной системы, следящей за временем, и тогда эта переменная будет содержать системное время. В этом случае значение переменной будет изменяться без участия какого-либо оператора программы. Знание таких подробностей важно потому, что большинство компиляторов С автоматически оптимизируют некоторые выражения, предполагая при этом неизменность переменной, если она не встречается в левой части оператора присваивания. В этом случае при очередной ссылке на переменную может использоваться ее предыдущее значение. Некоторые компиляторы изменяют порядок вычислений в выражениях, что может привести к ошибке, если в выражении присутствует переменная, вычисляемая вне программы. Квалификатор volatile предотвращает такие изменения программы.
|
|
|
|
|
Oct 10 2012, 10:58
|
Участник

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

|
Цитата(Сергей Борщ @ Oct 10 2012, 12:04)  В данном случае он абсолютно не нужен, ибо "воздействия еще чего-либо, не являющегося оператором программы" тут нет. Компилятор не знает есть внешнее воздействие или нет. Он не будет оптимизировать код где используются переменные с квалификатором volatile
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|