Перейти к содержанию
    

Ещё раз прочитайте по буквам: причём там ifdef???

Для справки: ifdef - используется для проверки определено ли данное имя или нет.

В моём примере константа всегда определена. Но может принимать разные значения (1, 2, ...).

ещё раз прочитайте ответ - вы обязаны записать это выражение правильно, иначе получайте предупреждение

кто должен разбираться, что там у вас там такое эти 1, 2..., или вы сможете вспомнить через полгода, что оно означало ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Таки да, операция ~temp1 дает число 0xFFFFFFFE. Вот если результат инверсии сохранить в uint16_t, тогда урежется до 0xFFFE.

Я тут внес сумятицу в дискуссию...

Отладчик Кейловский (чемпион!) рулит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Таки да, операция ~temp1 дает число 0xFFFFFFFE. Вот если результат инверсии сохранить в uint16_t, тогда урежется до 0xFFFE.

 

Вот именно. Для правильной генерации кода, наверное, предлагается напомнить компилятору о правильной размерности таким кодом:

if( (int16u)(~temp1) != temp2)

 

Который явно не способствует читабельности.

 

Абыдно, что у С++ масло маслянное.

Изменено пользователем aiwa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если ошибка воспроизводится в такой простой конструкции, то зачем присылать страницы кода?

Переменные 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();
}

 

широко используются при условной компиляции без использования препроцессора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Где-то вы не договариваете. Тот код, что вы привели с локальными переменными, с позиции современных

компиляторов является "мертвым" кодом и может быть выкинут безо всяких предупреждений даже на низших

уровнях оптимизации.

Поверьте, ничего я не "не договариваю". В топике я разместил код в таком виде, в каком проблема (на мой взгляд))

воспроизводилась, и с которой я столкнулся. Я считал что этого достаточно, так как легко можно проверить.

Затем, в сообщении 53 я привел законченные примеры кода и результат компиляции IAR.

Вопрос, как и тема раздела в целом, касается исключительно IAR. Причём на уровне оптимизации - None.

Причём я по прежнему считаю, что логика формирования предупреждений у IAR страдает.

1. Переменные 16 битные - код выбрасывается без предупреждений. Вроде мы обосновали, что это логично.

2. Переменные 32 битные - код присутствует, хотя он в этом случае он не менее бессмысленный.

Хотя здесь может быть такой аргумент: Две 32 битные переменные имеют право сравниваться, а компилятор заранее

не обязан предсказывать результат.

3. В случае "if (true) continue;" предупреждение есть, хотя результат ещё более определен, чем в первом случае.

Для меня лично (по результатам обсуждения) логично бы выглядело наличие предупреждения и в первом пункте.

Но видимо это уже связано с многопроходностью компилятора (код выбрасывается на уровне, когда предупреждения

уже не формируются).

Наверное нельзя это оценивать однозначно как хорошо или как плохо. Просто надо иметь в виду, что такая ситуация

возможна и больше обращать внимание на такие неявные на первый взгляд особенности языка и действий компилятора.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ещё раз прочитайте ответ - вы обязаны записать это выражение правильно, иначе получайте предупреждение

кто должен разбираться, что там у вас там такое эти 1, 2..., или вы сможете вспомнить через полгода, что оно означало ?

Что именно неправильно в моей записи и почему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перепишем ваш пример в более корректную форму:

// глобальные переменные
#define A ((int16u)0x01)  

int16u temp1 =   A;
int16u temp2 = ~A;
............................
void func(void)
{
  if (~temp1 != temp2) 
  {
    printf(" не выполняется закон двойного отрицания ~~A = A");
  }
}

 

В результате работы компилятора будет выполнен выводящий сообщение блок.

Изменено пользователем aiwa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В результате работы компилятора будет выполнен выводящий сообщение блок.

Если "программист" не знает языка и НЕ ХОЧЕТ читать сообщения компилятора ПОДАВИВ ИХ, то да.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если "программист" не знает языка и НЕ ХОЧЕТ читать сообщения компилятора ПОДАВИВ ИХ, то да.

Вы вопрос качества языка постоянно сводите к вопросу качества программиста.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы вопрос качества языка постоянно сводите к вопросу качества программиста.

Язык такой, какой он есть. Де факто стандарт для программирования микроконтроллеров. Мы все крепки задним умом. Было бы неплохо, конечно, обобщить передовой опыт, родить супер-пупер язык для МК, который в 100500 раз более лучше, чем Си, и отправить его на машине времени туда, куда надо. Но что-то мне подсказывает, что троечникам это не поможет. Учебник всё равно надо читать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы вопрос качества языка постоянно сводите к вопросу качества программиста.

Есть язык, он описан. Как любой ЖИВОЙ язык он имеет опоеделенные правила и умолчания. Их надо знать. Если кто не знает языка и более того, плюет на сообщения, которые генерят компиляторы написанные знающими язык людьми, то это есть проблема "качества порограммиста" и только его.

 

 

 

родить супер-пупер язык..

Спасибо, не надо. Уже рожали. Когда пытабтся рожать язык ради языка, а не дела, то получабтся ублюдки типа Ada, Python и иже с ними.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В результате работы компилятора будет выполнен выводящий сообщение блок.

 

И что вас здесь смущает? Левый операнд оператора сравнения будет расширен до размера int, а затем инвертирован, что на 32-х битной архитектуре приведет к установке битов старшего слова в 1. Правый операнд в силу беззнакового типа будет дополнен нулями. Очевидно, что 0xffffxxxx != 0x0000xxxx. Если сделать первый операнд знаковым, то результат может показаться странным, т.к. числа до 0х8000 будут давать другой результат. В любом случае, это полностью документированное в стандарте поведение - никаких неожиданностей здесь нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3. Насчет обязан или не обязан компилер. Конечно не обязан, его дело компилировать. Зато статический анализатор кода сразу завопил бы, с негодованием. Благо в последних IAR встроен C-Stat. Настоятельно рекомендую натравить его на код. Гарантирую(с), он еще много "чудес" выявит в коде. ;)

Если в законе что-то не написано прямым текстом, то работает принцип аналогии.

 

Ещё со времён динозавров, компиляторы паскаля, си и многих других языков выдавали сообщение/варнинг при сравнении беззнаковой переменной со знаковой константой или или переменной с константой вне диапазона этой переменной. В примере топикстартера есть аналогичные признаки: сравнение двух выражений, которые заведомо вне диапазона друг друга. Программер имеет право ожидать, что ОБНАРУЖИВ подобную ситуацию, компилятор укажет на неё аналогично константе.

 

Если компилятор не слишком оптимизирующий, то он действительно может не выдавать сообщение, т.к. во время компиляции эту ситуацию не видит. Компилятор, опознавший always-result в выражении с переменными всё-таки должен (ака вектор эволюции) выдавать сообщение, по аналогии с другими предупреждениями. И профсоюз по защите прав программистов должен лоббировать эти правила )))

 

Молчание ИАРа тянет на недоработку. Если в публичных и непубличных нормативах не было явно указано на данную ситуацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё со времён динозавров, компиляторы паскаля, си и многих других языков выдавали сообщение/варнинг при сравнении беззнаковой переменной со знаковой константой или или переменной с константой вне диапазона этой переменной.

Они и сейчас так делают.

Молчание ИАРа тянет на недоработку. Если в публичных и непубличных нормативах не было явно указано на данную ситуацию.

Никакого МОЛЧАНИЯ у 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

 

Так что может хватит здесь пургу нести?

 

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Python и иже с ними.

Питон-то чем не угодил?

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...