|
|
  |
Детская ошибка |
|
|
|
May 8 2016, 06:18
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Огурцов @ May 8 2016, 12:05)  о своих действиях - выбросил код, обнаружил невыполняемый или недостижимый код - сообщи Код 1: x = y + 2 + 3; Выбросил 2+3, заменил на 5. Сообщать? Код 2: int x, y, z; x = y + 2; z = (y + 2) * 3; Выбросил (y+2) во втором выражении, заменив на x*3. Сообщать? Код 3: #define DEF_X некое const-выражение int x; if (DEF_X == 1 && x == 1) { выражение1; } else { выражение2; }; если DEF_X != 1, то будет выкинута операция if и выражение1. Сообщать? ...и т.п.
|
|
|
|
|
May 8 2016, 06:53
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
> Выбросил 2+3, заменил на 5. Сообщать? скорее нет, чем да >Выбросил (y+2) во втором выражении, заменив на x*3. Сообщать? скорее да, чем нет >если DEF_X != 1, то будет выкинута операция if и выражение1. Сообщать? определённо да, ибо иначе использовался ifdef Цитата(jcxz @ May 8 2016, 06:32)  если среди них трудно найти полезные пишите так, чтобы не было неполезных
|
|
|
|
|
May 8 2016, 07:18
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(jcxz @ May 8 2016, 09:32)  IAR всё может. Только какая польза от такого кол-ва предупреждений, если среди них трудно найти полезные и всё равно их приходится отключать? Отчего же сразу отключать? "Сначала - так, потом - вот так" (с) Сначала компилируем, чтобы без ошибок, потом блох начинаем вычесывать. Потом чисто будет, можно и не проверять. Да, Назначения (Target) можно разные создать, чтоб одной кнопкой мышки... У меня два обычно, Debug и Release. Можно добавить Checked, типа...
|
|
|
|
|
May 8 2016, 09:07
|
Частый гость
 
Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612

|
Цитата(ViKo @ May 8 2016, 08:55)  Прочитав тему еще раз, понял, что топикстартер привел гипотетический пример, который и не пробовал компилировать. И народ кинулся обсуждать, приводить доводы за и против для того, что в реальности невозможно. Предлагаю выдать проверенный компилятором исходный текст. Ну что же Вы право... Если усомнились, что же сами не проверили? example1.c - переменные 16 битные, код не формируется (example1.lst). example2.c - переменные 32 битные, код формируется (example2.lst). Оптимизация - None. Понятно, что в данном конкретном случае, когда присваиваются константы, компилятор на высоком уровне оптимизации может выбросить вообще весь код. Но без оптимизации на этом фрагменте всё воспроизводится так, как я описал.
example.zip ( 2.66 килобайт )
Кол-во скачиваний: 23
|
|
|
|
|
May 8 2016, 10:35
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Keil Example1 CODE ; generated by Component: ARM Compiler 5.06 update 1 (build 61) Tool: ArmCC [4d35ad] ; commandline ArmCC [--c99 --list --split_sections --debug -c --asm --interleave -o.\objects\example1.o --asm_dir=.\Listings\ --list_dir=.\Listings\ --depend=.\objects\example1.d --cpu=Cortex-M3 --apcs=interwork -O0 --diag_suppress=9931 -I"D:\ViKo\Works\Keil works\(Keil) Example\RTE" -I"D:\ViKo\Works\Keil works\(Keil) Example\RTE\Device\STM32F103VC" -IC:\Design\Keil\ARM\PACK\ARM\CMSIS\4.5.0\CMSIS\Include -IC:\Design\Keil\ARM\PACK\Keil\STM32F1xx_DFP\2.1.0\Device\Include -D__UVISION_VERSION=518 -D_RTE_ -DSTM32F10X_HD --omf_browse=.\objects\example1.crf Source\example1.c] THUMB
AREA ||i.main||, CODE, READONLY, ALIGN=1
main PROC ;;;1 int main () 000000 2000 MOVS r0,#0 ;;;2 { ;;;3 unsigned short temp1, temp2; ;;;4 for (unsigned int i = 0; i < 10; i++) 000002 e009 B |L1.24| |L1.4| ;;;5 { ;;;6 temp1 = 0x0001; 000004 2101 MOVS r1,#1 ;;;7 temp2 = 0xFFFE; 000006 f64f72fe MOV r2,#0xfffe ;;;8 if (~temp1 != temp2) continue; 00000a 43cb MVNS r3,r1 00000c 4293 CMP r3,r2 00000e d000 BEQ |L1.18| 000010 e001 B |L1.22| |L1.18| ;;;9 temp2 = temp1; 000012 460a MOV r2,r1 000014 bf00 NOP ;8 |L1.22| 000016 1c40 ADDS r0,r0,#1 ;4 |L1.24| 000018 280a CMP r0,#0xa ;4 00001a d3f3 BCC |L1.4| ;;;10 } ;;;11 } 00001c 2000 MOVS r0,#0 00001e 4770 BX lr ENDP
__ARM_use_no_argv EQU 0
Example2 CODE ; generated by Component: ARM Compiler 5.06 update 1 (build 61) Tool: ArmCC [4d35ad] ; commandline ArmCC [--c99 --list --split_sections --debug -c --asm --interleave -o.\objects\example2.o --asm_dir=.\Listings\ --list_dir=.\Listings\ --depend=.\objects\example2.d --cpu=Cortex-M3 --apcs=interwork -O0 --diag_suppress=9931 -I"D:\ViKo\Works\Keil works\(Keil) Example\RTE" -I"D:\ViKo\Works\Keil works\(Keil) Example\RTE\Device\STM32F103VC" -IC:\Design\Keil\ARM\PACK\ARM\CMSIS\4.5.0\CMSIS\Include -IC:\Design\Keil\ARM\PACK\Keil\STM32F1xx_DFP\2.1.0\Device\Include -D__UVISION_VERSION=518 -D_RTE_ -DSTM32F10X_HD --omf_browse=.\objects\example2.crf Source\example2.c] THUMB
AREA ||i.main||, CODE, READONLY, ALIGN=1
main PROC ;;;1 int main () 000000 2000 MOVS r0,#0 ;;;2 { ;;;3 unsigned int temp1, temp2; ;;;4 for (unsigned int i = 0; i < 10; i++) 000002 e009 B |L1.24| |L1.4| ;;;5 { ;;;6 temp1 = 0x0001; 000004 2101 MOVS r1,#1 ;;;7 temp2 = 0xFFFE; 000006 f64f72fe MOV r2,#0xfffe ;;;8 if (~temp1 != temp2) continue; 00000a 43cb MVNS r3,r1 00000c 4293 CMP r3,r2 00000e d000 BEQ |L1.18| 000010 e001 B |L1.22| |L1.18| ;;;9 temp2 = temp1; 000012 460a MOV r2,r1 000014 bf00 NOP ;8 |L1.22| 000016 1c40 ADDS r0,r0,#1 ;4 |L1.24| 000018 280a CMP r0,#0xa ;4 00001a d3f3 BCC |L1.4| ;;;10 } ;;;11 } 00001c 2000 MOVS r0,#0 00001e 4770 BX lr ENDP
__ARM_use_no_argv EQU 0
Keil победил!
|
|
|
|
|
May 8 2016, 12:13
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(Огурцов @ May 8 2016, 09:05)  о своих действиях - выбросил код, обнаружил невыполняемый или недостижимый код - сообщи Так он выбросил код, проанализировав if(0). Случай исключительно вырожденный, так что и сообщать ему не о чем. Грубо говоря, процесс "ошибки" заложен внутри выражения (~temp1 != temp2) в результате перехода lvalue temp1 16 -> rvalue temp1 32.
|
|
|
|
|
May 8 2016, 12:24
|
Частый гость
 
Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612

|
Цитата(aiwa @ May 8 2016, 15:13)  Так он выбросил код, проанализировав if(0). Случай исключительно вырожденный, так что и сообщать ему не о чем.
Грубо говоря, процесс "ошибки" заложен внутри выражения (~temp1 != temp2) в результате перехода lvalue temp1 16 -> rvalue temp1 32. А давайте утрируем ситуацию: CODE main () { unsigned int temp1, temp2; for (unsigned int i = 0; i < 10; i++) { temp1 = 0x0001; temp2 = 0xFFFE; if (1) continue; temp2 = temp1; } }
Вроде как здесь всё ещё более определено. Так ведь нет. В этом случае видим предупреждение: Warning[Pe111]: statement is unreachable H:\work\test\example2.c 9 Где логика то?
|
|
|
|
|
May 8 2016, 12:29
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(zltigo @ May 8 2016, 06:44)  Маразм процветает  . Причем тут "старые", или "новые" - в огороде бузина а в Киеве дядька  . Компиляция такого "примера" зависит от разрядности int целевой платформы и ни от чего более. Спасибо, конечно, за оценку но речь, как бы не о механизме действия компилятора, - их вполне полно и лаконично уже описал Сергей Борщ. Приведу аналогию: чтобы обойти лишнюю писанину при желании char сделать беззнаковым, компиляторы добавили галочку "считать 'char' как unsigned. В нашем случае требуется добавление лишней писанины для предписания явного преобразования. Галочки не хватает.
|
|
|
|
|
May 8 2016, 12:54
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(amiller @ May 8 2016, 15:24)  Вроде как здесь всё ещё более определено. Так ведь нет. В этом случае видим предупреждение: Warning[Pe111]: statement is unreachable H:\work\test\example2.c 9 Где логика то? Точно не знаю, могу лишь предположить, что в этом случае все уже предопределено на уровне синтаксического разбора, поэтому компилятор выдает предупреждение. Но если Вы поменяете на Код int16u tst = 1; if(tst) continue; то сообщение уже может отсутствовать. Цитата(ViKo @ May 8 2016, 15:34)  И во что же должно продвинуться беззнаковое uint16_t 0xfffe? Разве не в 0x0000fffe, независимо, знаковое или без 32 битовое? И продвигаться надо когда? Когда результат логического сравнения используется? Сказано же, сравнивать 16-битовые беззнаковые. По-моему, IAR накосячил. Продвинутое uint16_t 0xfffe равно 0xfffffffe и оно является строго знаковым, независимо от знаковости или беззнаковости исходной переменной. Процесс продвижки начинается с упоминания имени переменной в выражении, а именно temp1 в выражении означает значение rvalue (signed int 32), полученное из lvalue переменной temp1 с помощью правил расширения.
|
|
|
|
|
May 8 2016, 13:30
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Огурцов @ May 8 2016, 12:53)  >Выбросил (y+2) во втором выражении, заменив на x*3. Сообщать? скорее да, чем нет Зачем??? Это обычная оптимизация никак не влияющая на выполнение кода. Таких оптимизаций в исходниках может быть тысячи случаев. Какая от них польза? Один только вред из-за того, что среди такого мусора пропадут полезные сообщения. Цитата(Огурцов @ May 8 2016, 12:53)  >если DEF_X != 1, то будет выкинута операция if и выражение1. Сообщать? определённо да, ибо иначе использовался ifdef  Каким боком тут ifdef??? Его значение всегда будет true. А смысл этого кода например в том, что есть некий общий модуль исходного кода на 2 разных устройства. В одном устройстве например установлено два чипа SPI-FLASH в другом - один. И данный define задаёт кол-во чипов. Это если Вы не поняли. Цитата(ViKo @ May 8 2016, 13:18)  Отчего же сразу отключать? "Сначала - так, потом - вот так" (с) Сначала компилируем, чтобы без ошибок, потом блох начинаем вычесывать. Потом чисто будет, можно и не проверять. Причём тут ошибки? Ошибок нет. Преобразование типа - это стандартная операция. Тем более - оптимизация и лишний код удаляемый оптимизацией. Таких событий будут тысячи мест в коде. Цитата(aiwa @ May 8 2016, 18:54)  Продвинутое uint16_t 0xfffe равно 0xfffffffe и оно является строго знаковым, независимо от знаковости или беззнаковости исходной переменной. Хмммм.... А что такое "продвинутое uint16_t"? Я отстал от жизни и в си ввели новые "продвинутые" типы? И как именно из беззнакового 0xFFFE получается 0xFFFFFFFE?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|