|
|
  |
Детская ошибка |
|
|
|
May 8 2016, 22:52
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(ViKo @ May 8 2016, 22:42)  Таки да, операция ~temp1 дает число 0xFFFFFFFE. Вот если результат инверсии сохранить в uint16_t, тогда урежется до 0xFFFE. Вот именно. Для правильной генерации кода, наверное, предлагается напомнить компилятору о правильной размерности таким кодом: if( (int16u)(~temp1) != temp2) Который явно не способствует читабельности. Абыдно, что у С++ масло маслянное.
Сообщение отредактировал aiwa - May 8 2016, 22:53
|
|
|
|
|
May 9 2016, 06:43
|

Профессионал
    
Группа: Свой
Сообщений: 1 003
Регистрация: 20-01-05
Пользователь №: 2 072

|
Цитата(amiller @ May 6 2016, 09:23)  Если ошибка воспроизводится в такой простой конструкции, то зачем присылать страницы кода? Переменные temp1 и temp2 локальные, объявление на строчку выше. В исходном коде переменным присваиваются не константы, а результат, возвращаемый функцией. А после условного оператора ещё сотня строк в цикле. Где-то вы не договариваете. Тот код, что вы привели с локальными переменными, с позиции современных компиляторов является "мертвым" кодом и может быть выкинут безо всяких предупреждений даже на низших уровнях оптимизации. Перепишем ваш пример в более корректную форму: Код unsigned short test1(unsigned short temp1, unsigned short temp2) { for (unsigned i = 0; i < 10; i++) { if (~temp1 != temp2) continue; temp2 = temp1; } return temp2; } и посмотрим на труд комиплятора (gcc -O2): Код movl %esi, %eax ret Все просто превосходно - не правда ли? Цикл заменен единственной инструкцией, а все потому, что сам код при любых значениях входных переменных будет всегда возвращать значение переменной temp2. Компилятор увидел это, и выкинул абсолютно ненужный цикл. Что-же касается молчаливого выбрасывания "мертвого" кода, то это есть следствие многопроходности современных компиляторов и весьма сложных структур внутреннего представления. Кроме того, конструкции вида Код constexpr bool WTF = true; ... if (WTF) { save_the_world(); } else { destroy_the_moon(); } широко используются при условной компиляции без использования препроцессора.
|
|
|
|
|
May 9 2016, 07:54
|
Частый гость
 
Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612

|
Цитата(halfdoom @ May 9 2016, 09:43)  Где-то вы не договариваете. Тот код, что вы привели с локальными переменными, с позиции современных компиляторов является "мертвым" кодом и может быть выкинут безо всяких предупреждений даже на низших уровнях оптимизации. Поверьте, ничего я не "не договариваю". В топике я разместил код в таком виде, в каком проблема (на мой взгляд)) воспроизводилась, и с которой я столкнулся. Я считал что этого достаточно, так как легко можно проверить. Затем, в сообщении 53 я привел законченные примеры кода и результат компиляции IAR. Вопрос, как и тема раздела в целом, касается исключительно IAR. Причём на уровне оптимизации - None. Причём я по прежнему считаю, что логика формирования предупреждений у IAR страдает. 1. Переменные 16 битные - код выбрасывается без предупреждений. Вроде мы обосновали, что это логично. 2. Переменные 32 битные - код присутствует, хотя он в этом случае он не менее бессмысленный. Хотя здесь может быть такой аргумент: Две 32 битные переменные имеют право сравниваться, а компилятор заранее не обязан предсказывать результат. 3. В случае "if (true) continue;" предупреждение есть, хотя результат ещё более определен, чем в первом случае. Для меня лично (по результатам обсуждения) логично бы выглядело наличие предупреждения и в первом пункте. Но видимо это уже связано с многопроходностью компилятора (код выбрасывается на уровне, когда предупреждения уже не формируются). Наверное нельзя это оценивать однозначно как хорошо или как плохо. Просто надо иметь в виду, что такая ситуация возможна и больше обращать внимание на такие неявные на первый взгляд особенности языка и действий компилятора.
|
|
|
|
|
May 9 2016, 11:10
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(halfdoom @ May 9 2016, 09:43)  Перепишем ваш пример в более корректную форму: Код // глобальные переменные #define A ((int16u)0x01)
int16u temp1 = A; int16u temp2 = ~A; ............................ void func(void) { if (~temp1 != temp2) { printf(" не выполняется закон двойного отрицания ~~A = A"); } } В результате работы компилятора будет выполнен выводящий сообщение блок.
Сообщение отредактировал aiwa - May 9 2016, 11:12
|
|
|
|
|
May 9 2016, 12:41
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(zltigo @ May 9 2016, 14:56)  Если "программист" не знает языка и НЕ ХОЧЕТ читать сообщения компилятора ПОДАВИВ ИХ, то да. Вы вопрос качества языка постоянно сводите к вопросу качества программиста.
|
|
|
|
|
May 9 2016, 12:49
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(aiwa @ May 9 2016, 15:41)  Вы вопрос качества языка постоянно сводите к вопросу качества программиста. Язык такой, какой он есть. Де факто стандарт для программирования микроконтроллеров. Мы все крепки задним умом. Было бы неплохо, конечно, обобщить передовой опыт, родить супер-пупер язык для МК, который в 100500 раз более лучше, чем Си, и отправить его на машине времени туда, куда надо. Но что-то мне подсказывает, что троечникам это не поможет. Учебник всё равно надо читать.
|
|
|
|
|
May 9 2016, 13:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (aiwa @ May 9 2016, 15:41)  Вы вопрос качества языка постоянно сводите к вопросу качества программиста. Есть язык, он описан. Как любой ЖИВОЙ язык он имеет опоеделенные правила и умолчания. Их надо знать. Если кто не знает языка и более того, плюет на сообщения, которые генерят компиляторы написанные знающими язык людьми, то это есть проблема "качества порограммиста" и только его. QUOTE (scifi @ May 9 2016, 15:49)  родить супер-пупер язык.. Спасибо, не надо. Уже рожали. Когда пытабтся рожать язык ради языка, а не дела, то получабтся ублюдки типа Ada, Python и иже с ними.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 9 2016, 16:00
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Tahoe @ May 6 2016, 08:58)  3. Насчет обязан или не обязан компилер. Конечно не обязан, его дело компилировать. Зато статический анализатор кода сразу завопил бы, с негодованием. Благо в последних IAR встроен C-Stat. Настоятельно рекомендую натравить его на код. Гарантирую(с), он еще много "чудес" выявит в коде.  Если в законе что-то не написано прямым текстом, то работает принцип аналогии. Ещё со времён динозавров, компиляторы паскаля, си и многих других языков выдавали сообщение/варнинг при сравнении беззнаковой переменной со знаковой константой или или переменной с константой вне диапазона этой переменной. В примере топикстартера есть аналогичные признаки: сравнение двух выражений, которые заведомо вне диапазона друг друга. Программер имеет право ожидать, что ОБНАРУЖИВ подобную ситуацию, компилятор укажет на неё аналогично константе. Если компилятор не слишком оптимизирующий, то он действительно может не выдавать сообщение, т.к. во время компиляции эту ситуацию не видит. Компилятор, опознавший always-result в выражении с переменными всё-таки должен (ака вектор эволюции) выдавать сообщение, по аналогии с другими предупреждениями. И профсоюз по защите прав программистов должен лоббировать эти правила ))) Молчание ИАРа тянет на недоработку. Если в публичных и непубличных нормативах не было явно указано на данную ситуацию.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 9 2016, 16:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (GetSmart @ May 9 2016, 19:00)  Ещё со времён динозавров, компиляторы паскаля, си и многих других языков выдавали сообщение/варнинг при сравнении беззнаковой переменной со знаковой константой или или переменной с константой вне диапазона этой переменной. Они и сейчас так делают. QUOTE Молчание ИАРа тянет на недоработку. Если в публичных и непубличных нормативах не было явно указано на данную ситуацию. Никакого МОЛЧАНИЯ у IAR, как и других нет, если не не подавлять сообщения. IAR в отношении сообщалок о возможном непонимании, пожалуй даже говорливее всех других: temp2 = ~A; [Pa091]: operator operates on value promoted to int (with possibly unexpected result) if( ~temp1 != temp2) [Pa091]: operator operates on value promoted to int (with possibly unexpected result) [Pe068]: integer conversion resulted in a change of sign Так что может хватит здесь пургу нести?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|