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

 
 
13 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Детская ошибка
amiller
сообщение May 2 2016, 06:22
Сообщение #1


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Недавно столкнулся с одной странностью (по крайней мере для меня). Хотелось бы понять.
Есть фрагмент года (упрощенный до безобразия):
CODE

int16u temp1, temp2;
for (int32u i = 0; i < 10; i++)
{
temp1 = 0x0001;
temp2 = 0xFFFE;
if (~temp1 != temp2) continue;
temp2 = temp1;
}

Так вот, в этом фрагменте условный оператор и код после него никогда не выполняется. В отладчике после выполнения операции "temp2 = 0xFFFE;" происходит сразу переход на начало цикла. Переменные объявлены как int16u (== unsigned short (16 бит беззнаковое))
При этом никаких предупреждений на этапе компиляции.
Если переменные объявить как int32u (== unsigned long (32 бита беззнаковое)), то условный оператор выполняется, но естественно результат всегда true.
И код работает как надо только в таком варианте:
CODE

int16u temp1, temp2;
for (int32u i = 0; i < 10; i++)
{
temp1 = 0x0001;
temp2 = 0xFFFE;
temp1 = ~temp1;
if (temp1 != temp2) continue;
temp2 = temp1;
}

В этом случае выполняются все операторы, входящие в тело цикла.
IAR C/C++ Compiler for ARM 7.40.3.8902 (7.40.3.8902)
Добавлю: Оптимизация отключена. Проект под микроконтроллер STM32F105VCT6

Сообщение отредактировал amiller - May 2 2016, 06:41
Go to the top of the page
 
+Quote Post
AleksBak
сообщение May 2 2016, 07:08
Сообщение #2


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

Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364



А если так:
Код
int16u temp1, temp2;
    for (int32u i = 0; i < 10; i++)
    {
        temp1 = 0x0001;
        temp2 = 0xFFFE;
        if ( (int16u)(~temp1) != temp2 ) continue;
        temp2 = temp1;
    }
Go to the top of the page
 
+Quote Post
amiller
сообщение May 2 2016, 07:16
Сообщение #3


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(AleksBak @ May 2 2016, 10:08) *
А если так:
Код
int16u temp1, temp2;
    for (int32u i = 0; i < 10; i++)
    {
        temp1 = 0x0001;
        temp2 = 0xFFFE;
        if ( (int16u)(~temp1) != temp2 ) continue;
        temp2 = temp1;
    }

Так как Вы предлагаете, тоже работает. Хотя в этом меня тоже смущает один момент. После выполнения оператора "~" не должна меняться размерность переменной.
Но больше всего меня беспокоит результат компиляции первого моего примера. В ассемблерном коде вообще отсутствует условный оператор и всё, что после него.
И при этом никаких предупреждений от компилятора.
Как это можно рассматривать? Бага компилятора? Или есть более простое объяснение?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 2 2016, 07:24
Сообщение #4


Гуру
******

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



QUOTE (amiller @ May 2 2016, 10:16) *
После выполнения оператора "~" не должна меняться размерность переменной.
Может меняться и после и до. В данном случае меняется до. Читайте про неявные приведения типов (implicit type conversion) и правила расширения целых (integer promotion rules).
QUOTE (amiller @ May 2 2016, 10:16) *
Как это можно рассматривать? Бага компилятора? Или есть более простое объяснение?
Как обычно (в 99.99% случев) - компилятор не виноват, просто программист не удосужился изучить язык, который пытается использовать.


--------------------
На любой вопрос даю любой ответ
"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
amiller
сообщение May 2 2016, 07:36
Сообщение #5


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Сергей Борщ @ May 2 2016, 10:24) *
Может меняться и после и до. В данном случае меняется до. Читайте про неявные приведения типов (implicit type conversion) и правила расширения целых (integer promotion rules).
Как обычно - компилятор не виноват, просто программист не удосужился изучить язык, который пытается использовать.

Про неявное приведение типов соглашусь.
Ну а судя по второй фразе, Вы точно знаете причину по которой компилятор удаляет часть кода, и при этом нет ни одного предупреждения?
Так сообщите пожалуйста. Мне это по прежнему непонятно. Речь идёт о самом первом примере.
Поясняю ещё раз. Дело не в том, что результат выполнения условной операции неверный. Дело в том, что условный оператор не выполняется вообще.
В исходной программе после этого условного оператора у меня было под сотню строк кода до окончания цикла. И весь этот код отсутствует в ассемблере.
CODE
\ 00000000 0xB538 PUSH {R3-R5,LR}
68 int16u temp1, temp2;
69
70 for (int32u i = 0; i < 10; i++)
\ 00000002 0x2000 MOVS R0,#+0
\ ??main_0: (+1)
\ 00000004 0x280A CMP R0,#+10
\ 00000006 0xD206 BCS.N ??main_1
71 {
72 temp1 = 0x0001;
\ 00000008 0x2101 MOVS R1,#+1
\ 0000000A 0x000C MOVS R4,R1
73 temp2 = 0xFFFE;
\ 0000000C 0xF64F 0x71FE MOVW R1,#+65534
\ 00000010 0x000D MOVS R5,R1
74 if (~temp1 != temp2) continue;
75 temp2 = temp1;
76 }
\ 00000012 0x1C40 ADDS R0,R0,#+1
\ 00000014 0xE7F6 B.N ??main_0
77
78
79
80


Сообщение отредактировал amiller - May 2 2016, 07:44
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 2 2016, 08:09
Сообщение #6


Гуру
******

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



QUOTE (amiller @ May 2 2016, 10:36) *
Ну а судя по второй фразе, Вы точно знаете причину по которой компилятор удаляет часть кода, и при этом нет ни одного предупреждения?
Так сообщите пожалуйста. Мне это по прежнему непонятно. Речь идёт о самом первом примере.
Да, знаю. После выполнения расширения типов ваше условие выполняется всегда, для любых значений переменных temp1 и temp2 (0xFFFFxxxx всегда не равно 0x0000xxxx). Поэтому условие всегда истинно и проверять его не имеет смысла - вы же хотите, чтобы ваша программа была маленькой и быстрой, поэтому компилятор просто выкинул бессмысленную проверку и весь код, который никогда, ни при каких условиях выполняться не будет.


--------------------
На любой вопрос даю любой ответ
"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
amiller
сообщение May 2 2016, 08:21
Сообщение #7


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Сергей Борщ @ May 2 2016, 11:09) *
Да, знаю. После выполнения расширения типов ваше условие выполняется всегда, для любых значений переменных temp1 и temp2 (0xFFFFxxxx всегда не равно 0x0000xxxx). Поэтому условие всегда истинно и проверять его не имеет смысла - вы же хотите, чтобы ваша программа была маленькой и быстрой, поэтому компилятор просто выкинул бессмысленную проверку и весь код, который никогда, ни при каких условиях выполняться не будет.

Позволю себе усомниться по двум пунктам:
1. Раньше во всех случаях, когда в коде был фрагмент, который никогда не выполняется, я получал от компилятора соответствующее предупреждение. В данном случае - нет.
2. Я уже писал, что если переменные объявить как int32u, то условие тоже всегда истинно. Но в этом случае компилятор не выбрасывает из кода условный оператор и всё что после него.
Есть вероятность, что ответ на этот простой вопрос, как обычно, лежит в более сложных материях.
Кстати уровень оптимизации = Null, поэтому с этой стороны не следует ожидать от компилятора излишней предупредительности.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 2 2016, 11:30
Сообщение #8


Гуру
******

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



Цитата(amiller @ May 2 2016, 10:16) *
Но больше всего меня беспокоит результат компиляции первого моего примера. В ассемблерном коде вообще отсутствует условный оператор и всё, что после него.

Вы будете смеяться, но компилятор вовсе не обязан на каждый чих в исходнике генерить код. Обычно на минимальном уровне оптимизации генерит, но тоже не всегда и не везде. Компилятор отвечает только за то, что сгенерированный код выдаст тот результат, который следует из исходника. Если исходник никакого результата не подразумевает, то компилятор может не генерировать ничего - и будет в своём праве.

Цитата(amiller @ May 2 2016, 11:21) *
1. Раньше во всех случаях, когда в коде был фрагмент, который никогда не выполняется, я получал от компилятора соответствующее предупреждение. В данном случае - нет.

Это вам показалось. Если припомните, какое именно было предупреждение, то поймёте, что в данном случае оно не применимо. А если не припомните, то это просто испорченный телефон. Короче, показалось.

Цитата(amiller @ May 2 2016, 11:21) *
Но в этом случае компилятор не выбрасывает из кода условный оператор и всё что после него.
Есть вероятность, что ответ на этот простой вопрос, как обычно, лежит в более сложных материях.

Не надо там искать сложных материй. В одном случае выкинул бессмысленный код, в другом - нет. Подумаешь - бывает сплошь и рядом. Компилятор - это просто программа, а не какое-то высшее существо с высшим разумом.
Go to the top of the page
 
+Quote Post
amiller
сообщение May 2 2016, 11:35
Сообщение #9


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(scifi @ May 2 2016, 14:26) *
Вы будете смеяться, но компилятор вовсе не обязан на каждый чих в исходнике генерить код. Обычно на минимальном уровне оптимизации генерит, но тоже не всегда и не везде. Компилятор отвечает только за то, что сгенерированный код выдаст тот результат, который следует из исходника. Если исходник никакого результата не подразумевает, то компилятор может не генерировать ничего - и будет в своём праве.

В этом с Вами я согласен, но предупредить то надо. Например если поставить внутри функции безусловный return, генерится предупреждение. А в данном случае всё происходит молча. Ну и не совсем понятен алгоритм. В одном случае молча выбрасывает код, а в другом очень похожем случае всё же генерит код, который тем не менее также не выполняется.

Например, если в том же примере заменить строку с условным оператором "if (true) continue;" то получаем предупреждение:
Warning[Pe111]: statement is unreachable - что логично. А в моем примере это происходило "молча".

Тем не менее всем спасибо!
Ошибка локализована. И с утверждением, что компилятор "не обязан", я согласен. Остальное в общем то уже нюансы функционирования программы, которой также является и компилятор.

Сообщение отредактировал amiller - May 2 2016, 11:44
Go to the top of the page
 
+Quote Post
AleksBak
сообщение May 2 2016, 12:20
Сообщение #10


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

Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364



Цитата(amiller @ May 2 2016, 15:35) *
В этом с Вами я согласен, но предупредить то надо. Например если поставить внутри функции безусловный return, генерится предупреждение. А в данном случае всё происходит молча. Ну и не совсем понятен алгоритм. В одном случае молча выбрасывает код, а в другом очень похожем случае всё же генерит код, который тем не менее также не выполняется.
...

Я было подумал, что IAR-овский компилер тут и поэтому может так, а оказывается и gcc аналогично себя ведет в этой ситуации.
Цитата(amiller @ May 2 2016, 15:35) *
... И с утверждением, что компилятор "не обязан", я согласен...

Почему? Ведь мог и написать что-то. Но нет промолчал как рыба.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 2 2016, 13:49
Сообщение #11


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(amiller @ May 2 2016, 15:35) *
В этом с Вами я согласен, но предупредить то надо.

Зря соглашаетесь. Хороший компилятор (и некий стандарт предупреждений) должен уметь определять опечатки и вероятные ошибки. Согласие в данном случае с тем, что он не обязан.

Обнаружил как-то у себя код
Код
{
bla bla bla;
bla bla bla;
} while (++i<10);

В котором в первой строке перед скобкой пропущен do. Просматривая такой код, ошибка не особо и видна. А компилятору заметить здесь что-то неладное совсем не сложно. Абыдно.

----

Но "стандарт предупреждений" неудачное название. История показывает, что каждый (американский) стандартер желает наВрать, где сидит фазан. Лучше "правила" с приоритетами.
Опечатку выделил. Опечатался буквой си.

Сообщение отредактировал GetSmart - May 2 2016, 14:10


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Baser
сообщение May 2 2016, 16:18
Сообщение #12


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(GetSmart @ May 2 2016, 16:49) *
Обнаружил как-то у себя код ...
В котором в первой строке перед скобкой пропущен do. Просматривая такой код, ошибка не особо и видна. А компилятору заметить здесь что-то неладное совсем не сложно. Абыдно.

Пример вы выбрали для подтверждения своей мысли сильно неудачный. Ибо и без do и с do конструкция совершенно легальна, хотя и имеет различную логику работы. А телепатическими способностями, чтобы понять то, что вы не написали, компиляторы уж точно не обладают sm.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 2 2016, 16:19
Сообщение #13


Универсальный солдатик
******

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



Цитата(GetSmart @ May 2 2016, 16:49) *
Обнаружил как-то у себя код
Код
{
bla bla bla;
bla bla bla;
} while (++i<10);

В котором в первой строке перед скобкой пропущен do. Просматривая такой код, ошибка не особо и видна. А компилятору заметить здесь что-то неладное совсем не сложно. Абыдно.

Ой ли?
Код
{
  bla bla bla;
  bla bla bla;
}
while (++i<10);
Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 2 2016, 16:36
Сообщение #14


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(GetSmart @ May 2 2016, 13:49) *
Хороший компилятор (и некий стандарт предупреждений) должен уметь определять опечатки и вероятные ошибки. Согласие в данном случае с тем, что он не обязан.

хороший - обязан (выдать предупреждение), сишный - не обязан
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 3 2016, 15:33
Сообщение #15


Гуру
******

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



Цитата(GetSmart @ May 2 2016, 19:49) *
Код
{
bla bla bla;
bla bla bla;
} while (++i<10);

В котором в первой строке перед скобкой пропущен do. Просматривая такой код, ошибка не особо и видна. А компилятору заметить здесь что-то неладное совсем не сложно. Абыдно.

И что в этом коде неладно???
Следуя Вашей логике, компилятор на выражение:
int x;
тоже должен выдавать варнинг, ведь может Вы там хотели написать:
unsigned int x;
Компилятор не должен думать за программиста.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 3 2016, 16:23
Сообщение #16


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(jcxz @ May 3 2016, 19:33) *
И что в этом коде неладно???

Это должен был быть цикл на 10 итераций с выпрыгиванием из него при определённых обстоятельствах. А получилась только одна итерация.

Искренне считаю, что обнаруживать такую СТРАННУЮ последовательность должен компилятор. Правило: если идёт свободный блок, за которым while без тела, то выдать варнинг. Иначе на while без тела с неволатильными переменными в условии выдавать ремарку. Тело в данном случае - ключевой признак этих правил.

Цитата(Baser @ May 2 2016, 20:18) *
Пример вы выбрали для подтверждения своей мысли сильно неудачный.

Именно такие странности хотелось бы чтобы компилятор "подчёркивал" при компиляции, как Ворд подчёркивает текст при просмотре. Пример тот самый. Как и у ТС.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 3 2016, 19:47
Сообщение #17


Гуру
******

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



QUOTE (GetSmart @ May 3 2016, 19:23) *
Искренне считаю, что обнаруживать такую СТРАННУЮ последовательность должен компилятор. Правило: если идёт свободный блок, за которым while без тела, то выдать варнинг.

Блок может использоваться по причинам совершенно не связанным с ошибкой - локализация объявления переменной, макроподстановка...
Так что не надо стенаний, особенно, если стеной стоите, как мне помится, на "нормальности" while(константа){} sm.gif




--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 3 2016, 21:42
Сообщение #18


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ May 3 2016, 23:47) *
Так что не надо стенаний, особенно, если стеной стоите, как мне помится, на "нормальности" while(константа){} sm.gif

while / if (const) ==> ремарка. Продолжаю считать, как и ранее. Полезные конструкции. С тремя уровнями сообщений компилятора. То бишь с двумя не препятствующими генерации прошивки.

В идеале на pred_while(1) и post_while(0) даже ремарку не выдавать. Если макроса в скобках не было.

Цитата(zltigo @ May 3 2016, 23:47) *
Блок может использоваться по причинам совершенно не связанным с ошибкой - локализация объявления переменной, макроподстановка...

Макроподстановку легко обнаружить и учесть. Логика на порядки проще оптимизации кода.

Сообщение отредактировал GetSmart - May 3 2016, 21:36


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 4 2016, 11:59
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Вообще-то да, это работа не компилятора, но редактора.
Вернее, той особо развитой в последнее его части, которая анализирует код, делает автозавершение, производит выравнивание и прочее.
Вот с его точки зрения легко предположить отсутствие начала в шаблоне do{}while();
Go to the top of the page
 
+Quote Post
Tahoe
сообщение May 6 2016, 04:58
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(amiller @ May 2 2016, 14:35) *
Ошибка локализована. И с утверждением, что компилятор "не обязан", я согласен. Остальное в общем то уже нюансы функционирования программы, которой также является и компилятор.

1. Странно, что локализована. Лично мне резануло глаз присваивание константы в цикле, при том что константа объявлена не volatile. Стало быть, весь цикл вообще теряет смысл. И никакие неявные приведения типов тут вообще ни причем.

2. Упрощения, это хорошо. Но приводить упрощенный Си-код вне функции, дело бесполезное. Хотя бы потому, что не понятно, переменные temp1 и temp2 локальные или глобальные.

3. Насчет обязан или не обязан компилер. Конечно не обязан, его дело компилировать. Зато статический анализатор кода сразу завопил бы, с негодованием. Благо в последних IAR встроен C-Stat. Настоятельно рекомендую натравить его на код. Гарантирую(с), он еще много "чудес" выявит в коде. wink.gif
Go to the top of the page
 
+Quote Post
amiller
сообщение May 6 2016, 06:23
Сообщение #21


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Tahoe @ May 6 2016, 07:58) *
1. Странно, что локализована. Лично мне резануло глаз присваивание константы в цикле, при том что константа объявлена не volatile. Стало быть, весь цикл вообще теряет смысл. И никакие неявные приведения типов тут вообще ни причем.
2. Упрощения, это хорошо. Но приводить упрощенный Си-код вне функции, дело бесполезное. Хотя бы потому, что не понятно, переменные temp1 и temp2 локальные или глобальные.

Если ошибка воспроизводится в такой простой конструкции, то зачем присылать страницы кода?
Переменные temp1 и temp2 локальные, объявление на строчку выше. В исходном коде переменным присваиваются не константы, а результат, возвращаемый функцией. А после условного оператора ещё сотня строк в цикле.
Меня лично смутило, что компилятор без предупреждений выбросил из программы большой фрагмент кода. Это было главное, на что я обратил внимание.
Но раз общественность не забилась в праведном гневе, значит все считают это нормальным. А тогда вопрос и не стоит обсуждать.
Тем более в коде был грешок с приведением типов, на который мне правильно указали.

Go to the top of the page
 
+Quote Post
Tahoe
сообщение May 6 2016, 08:32
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(amiller @ May 6 2016, 09:23) *
Если ошибка воспроизводится в такой простой конструкции, то зачем присылать страницы кода?

Еще раз. Нет никакой конструкции. Тот огрызок, что приведен, не позволяет нормально определить источник проблемы.

Цитата(amiller @ May 6 2016, 09:23) *
Переменные temp1 и temp2 локальные, объявление на строчку выше. В исходном коде переменным присваиваются не константы, а результат, возвращаемый функцией.

"Не в преферанс, а в лотерею. Не миллион, а пять тыщ. И не выиграл, а проиграл." (с)

Я только не понял, это вот "в исходном коде не константы", это просто поприкалываться захотелось или на полном серьезе?

Цитата(amiller @ May 6 2016, 09:23) *
Но раз общественность не забилась в праведном гневе, значит все считают это нормальным. А тогда вопрос и не стоит обсуждать.Тем более в коде был грешок с приведением типов, на который мне правильно указали.

А, общественность... Все считают... Тогда другое дело. Это заявка на успех. Желаю удачи.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 6 2016, 08:45
Сообщение #23


Гуру
******

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



Цитата(Tahoe @ May 6 2016, 11:32) *
Еще раз. Нет никакой конструкции. Тот огрызок, что приведен, не позволяет нормально определить источник проблемы.

Да ладно, нормальный огрызок. Вот словесное описание путаное, это да. Но вроде бы сразу понятно, что всё упирается в неявное приведение типов и устранение лишнего кода.
Короче, не надо занудствовать, с проблемой уже разобрались.
Go to the top of the page
 
+Quote Post
amiller
сообщение May 6 2016, 08:58
Сообщение #24


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Tahoe @ May 6 2016, 11:32) *
Еще раз. Нет никакой конструкции. Тот огрызок, что приведен, не позволяет нормально определить источник проблемы.


"Не в преферанс, а в лотерею. Не миллион, а пять тыщ. И не выиграл, а проиграл." (с)

Я только не понял, это вот "в исходном коде не константы", это просто поприкалываться захотелось или на полном серьезе?


А, общественность... Все считают... Тогда другое дело. Это заявка на успех. Желаю удачи.


Извините, но я не понял к чему это всё, что Вы написали.
Или Вы считаете, что если я скопирую сюда полный код функции, Вы точно укажете на источник проблемы? Или Вы считаете, что я школьник, и то, что я прислал к делу не имеет отношения, а ошибка в другом месте?
Смею Вас заверить, что это не так.
И проблема воспроизводится именно в том "огрызке", который я разместил, я специально проверял. Для этого больше ничего не нужно, достаточно этот фрагмент разместить в пустом main(). Ну разве что скорректировать названия типов.
И в отзывах была информация, что это характерно не только для компилятора IAR. В gcc тоже проблема воспроизводится.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 6 2016, 13:44
Сообщение #25


Гуру
******

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



QUOTE (amiller @ May 6 2016, 11:58) *
И в отзывах была информация, что это характерно не только для компилятора IAR. В gcc тоже проблема воспроизводится.

Опять sad.gif. Да не проблема это компилятора, ЛЮБОЙ компилятор ОБЯЗАН поступить аналогично. Это АБСОЛЮТНО Ваша проблема связанная с незнаним языка.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
amiller
сообщение May 6 2016, 14:19
Сообщение #26


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(zltigo @ May 6 2016, 16:44) *
Опять sad.gif. Да не проблема это компилятора, ЛЮБОЙ компилятор ОБЯЗАН поступить аналогично. Это АБСОЛЮТНО Ваша проблема связанная с незнаним языка.

Я нигде не писал, что претендую на звание "гуру". Более того, на ошибках учусь с удовольствием, как на своих, так и на чужих.
Но никто не дал на мой вопрос чёткий ответ.
1. Если переменные int16u, то компилятор код выбрасывает. У меня нет вопросов к самому факту этого события. У меня вопрос к тому, почему это происходит без предупреждения (молча). Я не считаю, что это нормальное поведение компилятора.
2. Однако если переменные int32u, то с точки зрения выполнения кода ничего не меняется. Но тем не менее в этом случае, код компилируется (не выбрасывается). Хотя результат также предопределен и известен заранее.
Я уже вроде успокоился по этому поводу, но находятся всё новые люди, которые утверждают, что я не знаю язык, но не дают чёткого ответа, почему компилятор поступает именно так.
Может Вы попробуете?

Go to the top of the page
 
+Quote Post
scifi
сообщение May 6 2016, 15:29
Сообщение #27


Гуру
******

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



Цитата(amiller @ May 6 2016, 17:19) *
1. Если переменные int16u, то компилятор код выбрасывает. У меня нет вопросов к самому факту этого события. У меня вопрос к тому, почему это происходит без предупреждения (молча).

Предупреждения придуманы для удобства. Они помогают отловить ошибки в коде. Нет никаких стандартов, регламентирующих поведение компилятора в этом вопросе. Более того, авторы компилятора тоже никаких обязательств здесь на себя не берут. Следовательно, вопрос "почему" довольно бесперспективный. Если вас так уж гложет, вам надо добыть исходники этого компилятора и разобраться, что там происходит. Или спросить того, кто делает этот компилятор. В этом форуме, понятное дело, вы таких не найдёте.

Цитата(amiller @ May 6 2016, 17:19) *
2. Однако если переменные int32u, то с точки зрения выполнения кода ничего не меняется. Но тем не менее в этом случае, код компилируется (не выбрасывается). Хотя результат также предопределен и известен заранее.
Я уже вроде успокоился по этому поводу, но находятся всё новые люди, которые утверждают, что я не знаю язык, но не дают чёткого ответа, почему компилятор поступает именно так.

Здесь применим тот же ответ, что я дал выше. "Нет никаких стандартов, регламентирующих поведение компилятора в этом вопросе" и далее по тексту.

В общем, не те вопросы задаёте, не о том думаете. Кстати, именно вот эти неправильные вопросы и дают людям повод усомниться в вашем знании языка Си.
Go to the top of the page
 
+Quote Post
Tahoe
сообщение May 6 2016, 16:31
Сообщение #28


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(amiller @ May 6 2016, 17:19) *
1. Если переменные int16u, то компилятор код выбрасывает.

Последний раз, больше даже пытаться не стану. Если десять раз присвоить константу temp1=0x1, хоть что-то изменится, хоть на одном проходе из 10? Если не изменится, то бишь даже без всякой оптимизации, temp1 и temp2 _всегда_ будут иметь одно и то же значение. Результат if (~0x0001!= 0xFFFE) будет отличаться хоть на одном из проходов? И плевать какие там типы, все 10 раз будет одно и то же. А строчка temp2 = temp1; будет вообще игнорироваться.

В итоге, имеем несколько строчек бессмысленного кода, который вырождается в пару присваиваний. И никакого цикла здесь нет. Другой вопрос, когда вместо констант будет присваиваться результат функции. В этом случае, может и дойдет до кривых типов. Но в приведенном куске, с константами, до этого дело даже не доходит.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 6 2016, 21:37
Сообщение #29


Гуру
******

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



QUOTE (amiller @ May 6 2016, 17:19) *
2. Однако если переменные int32u, то с точки зрения выполнения кода ничего не меняется.
Меняется. При приведении int16_t -> int32_t происходит расширение знака.


--------------------
На любой вопрос даю любой ответ
"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
amiller
сообщение May 7 2016, 02:52
Сообщение #30


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Tahoe @ May 6 2016, 19:31) *
Последний раз, больше даже пытаться не стану. Если десять раз присвоить константу temp1=0x1, хоть что-то изменится, хоть на одном проходе из 10? Если не изменится, то бишь даже без всякой оптимизации, temp1 и temp2 _всегда_ будут иметь одно и то же значение. Результат if (~0x0001!= 0xFFFE) будет отличаться хоть на одном из проходов? И плевать какие там типы, все 10 раз будет одно и то же. А строчка temp2 = temp1; будет вообще игнорироваться.

В итоге, имеем несколько строчек бессмысленного кода, который вырождается в пару присваиваний. И никакого цикла здесь нет. Другой вопрос, когда вместо констант будет присваиваться результат функции. В этом случае, может и дойдет до кривых типов. Но в приведенном куске, с константами, до этого дело даже не доходит.

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


Цитата(Сергей Борщ @ May 7 2016, 00:37) *
Меняется. При приведении int16_t -> int32_t происходит расширение знака.

Уточнение: мои типы int16u и int32u соответствуют uint16_t u uint32_t. Не уверен, что в этом случае можно говорить о расширении знака.
Когда я говорил "ничего не меняется", я имел в виду, что условие в условном операторе по прежнему всегда true (не зависит от типа переменных), но в одном случае код компилируется, а в другом выбрасывается.
Go to the top of the page
 
+Quote Post
Tahoe
сообщение May 7 2016, 05:14
Сообщение #31


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(amiller @ May 7 2016, 05:52) *
Представленный фрагмент кода имеет только один смысл - продемонстрировать наличие проблемы в действиях компилятора.

Представленный фрагмент ничего не демонстрирует, от слова "вообще". Особенно, проблем с компилером. Единственное, что он демонстрирует, это лень и, как следствие, дурную манеру изложения, в стиле "Рабинович напел".
Go to the top of the page
 
+Quote Post
amiller
сообщение May 7 2016, 05:37
Сообщение #32


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Tahoe @ May 7 2016, 08:14) *
Представленный фрагмент ничего не демонстрирует, от слова "вообще". Особенно, проблем с компилером. Единственное, что он демонстрирует, это лень и, как следствие, дурную манеру изложения, в стиле "Рабинович напел".

А кроме голословных утверждений Вам есть что сообщить? В чём именно заключается лень или дурные манеры?
Чтобы убедиться в том, а чём я пишу, достаточно:
1. Вставить в программу фрагмент кода (соответствующим образом изменив названия типов).
2. Откомпилировать. Убедиться, что начиная с условного оператора в листинге код не формируется, а предупреждений не выдается.
3. Поменять типы на int32u (или uint32_t, как удобно).
4. Снова откомпилировать,убедиться, что в листинге код есть, хотя результат условного оператора также предопределен, как и в первом случае.
5. Задуматься, возможно сделать выводы.
6. Если понятна причина такого поведения компилятора, рассказать автору вопроса.
7. Если причина неизвестна, то лучше промолчать, а не опускаться до стиля "сам дурак".
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 7 2016, 07:59
Сообщение #33


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(amiller @ May 7 2016, 08:37) *
2. .....Убедиться, что начиная с условного оператора в листинге код не формируется, а предупреждений не выдается.


Стандарт С++. 5.3.1 Unary operators.
8 The operand of the unary - operator .....
Integral promotion is performed on integral or enumeration operands. .....
The type of the result is the type of the promoted operand.

Т.е. стандарт предписывает все целочисленные типы, а это харе-образные, с "int" и enum, расширять до знакового int и так далее в зависимости от размера.
Тип результата - расширенный операнд.
В случае с int16u результатом операции будет "signed int". Также как и ,например, результат операции (char) + (char) -> signed int;

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

Сообщение отредактировал aiwa - May 7 2016, 08:00
Go to the top of the page
 
+Quote Post
svss
сообщение May 7 2016, 09:24
Сообщение #34


Местный
***

Группа: Свой
Сообщений: 231
Регистрация: 19-12-08
Из: Новосибирск
Пользователь №: 42 594



Цитата(amiller @ May 7 2016, 11:37) *
...
5. Задуматься, возможно сделать выводы.
...
Предлагаю один: не полагаться на компилятор /что он все приведения типов и приоритеты операций соблюдёт/
Расставляйте скобки и явные касты. (это не я придумал: жизнь учит)

Одноразовое изделие - одно, о нём и темы нет. Как только нужна переносимость кода весь геморрой - ваш.
Если соломку не стелить регулярно.
Темы о глюках компиляторов, стандартах и их (не)соблюдении вечны как и холивар.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 7 2016, 10:25
Сообщение #35


Гуру
******

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



QUOTE (svss @ May 7 2016, 12:24) *
не полагаться на компилятор /что он все приведения типов и приоритеты операций соблюдёт/

Вообще то он СОБЛЮДЕТ! Лет 25 уже основные компиляторы сколь-нибудь явных ошибок НЕ допускают.
QUOTE
Расставляйте скобки и явные касты. (это не я придумал: жизнь учит)

А вот это скоерее, да. Только НЕ для компилятора, а для себя, ибо в отличие от компилятора человку сложнее держать в голове те же 15 уровней приоритета.
Но и маниакально распихивать скобки и приведения типов тоже не дело.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Tahoe
сообщение May 7 2016, 13:47
Сообщение #36


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(amiller @ May 7 2016, 08:37) *
А кроме голословных утверждений Вам есть что сообщить?
...
2. Откомпилировать. Убедиться, что начиная с условного оператора в листинге код не формируется, а предупреждений не выдается.

Я все сообщил еще в своем первом ответе. И почему код отсутствует, и что запустить, что бы увидеть желаемое предупреждение.

Код, приведенный в первом посте - бессмысленный. С какой стати компилер должен предупреждать об этом? Это широко распространенный прием, например при условной компиляции, когда часть кода намеренно превращается бессмысленное. С какой стати компилеру лезть не в свое дело? Откуда он знает, это программер бестолково пишет, как в данном случае или код заточен под 100500 вариантов? А вот статический анализатор, тот не просто предупредит, вопить будет. Однако отсутствие вопросов и комментариев по статическому анализатору, говорит о том, что даже не понятно, о чем вообще речь. Так может, чем продолжать дерзить, запустить хоть раз C-STAT или хотя бы выяснить, что это такое?
Go to the top of the page
 
+Quote Post
amiller
сообщение May 7 2016, 14:04
Сообщение #37


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Tahoe @ May 7 2016, 16:47) *
Так может, чем продолжать дерзить, запустить хоть раз C-STAT или хотя бы выяснить, что это такое?

Ну извините пожалуйста. Я сразу не обратил внимание, что Вы из Москвы. Простите молодого пятидесятилетнего провинциала, что я вообще вступил с Вами в дискуссию.
Мне надо было посыпать голову пеплом и с восторгом внимать Вам.
Только напомните мне пожалуйста, что именно Вы сказали по существу конкретного вопроса, который я задал?
Go to the top of the page
 
+Quote Post
Tahoe
сообщение May 7 2016, 16:06
Сообщение #38


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(amiller @ May 7 2016, 17:04) *
сразу не обратил внимание, что Вы из Москвы. Простите молодого пятидесятилетнего провинциала

Не понял, как это относится к запуску C-STAT, зато стало ясно, что имею дело с очередным не признанным гением. В этом месте позвольте откланяться. Удачи.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 7 2016, 16:57
Сообщение #39


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(scifi @ May 6 2016, 16:29) *
Предупреждения придуманы для удобства. Они помогают отловить ошибки в коде. Нет никаких стандартов, регламентирующих поведение компилятора в этом вопросе. Более того, авторы компилятора тоже никаких обязательств здесь на себя не берут.

странно, в одном случае берут, в другом таком же - не берут
а не проще ли было писать компилятор так, что во всех случаях выдавать предупреждение, а не когда как
Go to the top of the page
 
+Quote Post
amiller
сообщение May 7 2016, 17:33
Сообщение #40


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(Tahoe @ May 7 2016, 19:06) *
Не понял, как это относится к запуску C-STAT, зато стало ясно, что имею дело с очередным не признанным гением. В этом месте позвольте откланяться. Удачи.

Как же Вы любите ярлыки навешивать... Вообще то мои слова появились в ответ на Ваше "продолжать дерзить".
По моему Вы вообще не поняли, о чём идёт речь.
1. Я не прошу помощи в написании кода или в оценке его качества.
2. Не нужно советов по использованию дополнительного ПО, так как это совсем не относится к делу.
3. И речь не шла о правильности или эффективности примера, его (примера) задача - продемонстрировать описанную проблему.
В своем сообщении я описал проблему в работе компилятора, которую увидел.
И хотел выяснить нормальное это поведение или нет и почему компилятор ведёт себя по разному в похожих случаях.
А конкретная задача в написании программы была решена ещё до того, как было написано сообщение.
Ведь не все вопросы обязаны быть на тему "помогите, не работает...".
Go to the top of the page
 
+Quote Post
scifi
сообщение May 7 2016, 18:27
Сообщение #41


Гуру
******

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



Цитата(Огурцов @ May 7 2016, 19:57) *
а не проще ли было писать компилятор так, что во всех случаях выдавать предупреждение, а не когда как

Не знаю. Сколько компиляторов вы сделали? Я - ни одного. Потому и не знаю.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 7 2016, 20:41
Сообщение #42


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Огурцов @ May 7 2016, 19:57) *
а не проще ли было писать компилятор так, что во всех случаях выдавать предупреждение, а не когда как

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


Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 7 2016, 21:59
Сообщение #43


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



вы можете между собой договориться, есть в предписании стандарта речь про предупреждения или нет ?
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 7 2016, 22:31
Сообщение #44


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Огурцов @ May 8 2016, 00:59) *
вы можете между собой договориться, есть в предписании стандарта речь про предупреждения или нет ?

А о чем должно быть предупреждение?
В сухом остатке получается переменная булевого типа, равная нулю. А само нарушение закона двойного отрицания происходит
в процессе обработки выражения.
Причем, в старых 16-битных компиляторах обработка происходит корректно.

Go to the top of the page
 
+Quote Post
zltigo
сообщение May 8 2016, 03:44
Сообщение #45


Гуру
******

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



QUOTE (aiwa @ May 8 2016, 01:31) *
Причем, в старых 16-битных компиляторах обработка происходит корректно.

Маразм процветает sad.gif. Причем тут "старые", или "новые" - в огороде бузина а в Киеве дядька sad.gif. Компиляция такого "примера" зависит от разрядности int целевой платформы и ни от чего более.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 05:55
Сообщение #46


Универсальный солдатик
******

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



Прочитав тему еще раз, понял, что топикстартер привел гипотетический пример, который и не пробовал компилировать. И народ кинулся обсуждать, приводить доводы за и против для того, что в реальности невозможно.
Предлагаю выдать проверенный компилятором исходный текст.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 8 2016, 06:05
Сообщение #47


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(aiwa @ May 7 2016, 22:31) *
А о чем должно быть предупреждение?

о своих действиях - выбросил код, обнаружил невыполняемый или недостижимый код - сообщи
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 8 2016, 06:18
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 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. Сообщать?
...и т.п.
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 06:18
Сообщение #49


Универсальный солдатик
******

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



Цитата(Огурцов @ May 8 2016, 09:05) *
о своих действиях - выбросил код, обнаружил невыполняемый или недостижимый код - сообщи

Он так и сделает, будьте patient.
У Кейла есть ключик компилятора -remarks. И тогда он мне кидает больше сотни предупреждений. Один недостаток, трудно сообщения об ошибках искать. Задаю поиск "error". sm.gif
Может, ИАР тоже так может?
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 8 2016, 06:32
Сообщение #50


Гуру
******

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



Цитата(ViKo @ May 8 2016, 12:18) *
У Кейла есть ключик компилятора -remarks. И тогда он мне кидает больше сотни предупреждений. Один недостаток, трудно сообщения об ошибках искать. Задаю поиск "error". sm.gif
Может, ИАР тоже так может?

IAR всё может. Только какая польза от такого кол-ва предупреждений, если среди них трудно найти полезные и всё равно их приходится отключать?
Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 8 2016, 06:53
Сообщение #51


Гуру
******

Группа: Участник
Сообщений: 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) *
если среди них трудно найти полезные

пишите так, чтобы не было неполезных
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 07:18
Сообщение #52


Универсальный солдатик
******

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



Цитата(jcxz @ May 8 2016, 09:32) *
IAR всё может. Только какая польза от такого кол-ва предупреждений, если среди них трудно найти полезные и всё равно их приходится отключать?

Отчего же сразу отключать? "Сначала - так, потом - вот так" (с) Сначала компилируем, чтобы без ошибок, потом блох начинаем вычесывать. Потом чисто будет, можно и не проверять.
Да, Назначения (Target) можно разные создать, чтоб одной кнопкой мышки... У меня два обычно, Debug и Release. Можно добавить Checked, типа...
Go to the top of the page
 
+Quote Post
amiller
сообщение May 8 2016, 09:07
Сообщение #53


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

Группа: Участник
Сообщений: 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




Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 10:35
Сообщение #54


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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 победил! biggrin.gif
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 12:13
Сообщение #55


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Огурцов @ May 8 2016, 09:05) *
о своих действиях - выбросил код, обнаружил невыполняемый или недостижимый код - сообщи

Так он выбросил код, проанализировав if(0). Случай исключительно вырожденный, так что и сообщать ему не о чем.

Грубо говоря, процесс "ошибки" заложен внутри выражения (~temp1 != temp2)
в результате перехода lvalue temp1 16 -> rvalue temp1 32.

Go to the top of the page
 
+Quote Post
amiller
сообщение May 8 2016, 12:24
Сообщение #56


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

Группа: Участник
Сообщений: 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
Где логика то?

Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 12:29
Сообщение #57


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(zltigo @ May 8 2016, 06:44) *
Маразм процветает sad.gif. Причем тут "старые", или "новые" - в огороде бузина а в Киеве дядька sad.gif. Компиляция такого "примера" зависит от разрядности int целевой платформы и ни от чего более.

Спасибо, конечно, за оценку но речь, как бы не о механизме действия компилятора, - их вполне полно и лаконично уже описал Сергей Борщ.

Приведу аналогию: чтобы обойти лишнюю писанину при желании char сделать беззнаковым, компиляторы добавили галочку "считать 'char' как unsigned.
В нашем случае требуется добавление лишней писанины для предписания явного преобразования. Галочки не хватает.

Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 12:34
Сообщение #58


Универсальный солдатик
******

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



И во что же должно продвинуться беззнаковое uint16_t 0xfffe? Разве не в 0x0000fffe, независимо, знаковое или без 32 битовое?
И продвигаться надо когда? Когда результат логического сравнения используется? Сказано же, сравнивать 16-битовые беззнаковые.
По-моему, IAR накосячил.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 12:54
Сообщение #59


Местный
***

Группа: Участник
Сообщений: 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 с помощью правил расширения.

Go to the top of the page
 
+Quote Post
jcxz
сообщение May 8 2016, 13:30
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 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

wacko.gif Каким боком тут 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?
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 14:27
Сообщение #61


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(jcxz @ May 8 2016, 16:30) *
Хмммм.... А что такое "продвинутое uint16_t"? Я отстал от жизни и в си ввели новые "продвинутые" типы?
И как именно из беззнакового 0xFFFE получается 0xFFFFFFFE?

Продвинутый - это буквальный перевод термина "promotions", наверное неудачный.
Правила "integral promotions" предписывают расширение до типа способного полностью представить исходное значение
в порядке int, unsigned int, long int, unsigned long int, и т.д.
Первый тип для 32-го компилятора - знаковый int может полностью представить весь диапазон значений uint16_t, поэтому
и происходит расширение uint16_t - > signed int (32).
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 14:37
Сообщение #62


Универсальный солдатик
******

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



Правильно, продвигается до знакового целого. Но почему 65534 должно "превратиться в -1?
jcxz, об чем вы, о каких ошибках? Я где хочу,там пишу с ошибками, а компилятор их ловит. Где хочу читаю все ремарки.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 14:43
Сообщение #63


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(ViKo @ May 8 2016, 17:37) *
Правильно, продвигается до знакового целого. Но почему 65534 должно "превратиться в -1?
jcxz, об чем вы, о каких ошибках? Я где хочу,там пишу с ошибками, а компилятор их ловит. Где хочу читаю все ремарки.

Ах, точно, Вы правы - у меня опечятка: в результате расширения получается знаковый 0x0000FFFE.
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 14:45
Сообщение #64


Универсальный солдатик
******

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



О! Может, топикстартер все же напутал с определением своего типа беззнакового?
Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 8 2016, 14:53
Сообщение #65


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(jcxz @ May 8 2016, 13:30) *
Каким боком тут ifdef???

таким, что если бы я хотел написать нечто осмысленное, то использовал ifdef
а так как написан if, то вероятно тут косяк, о коем компилятор обязан сообщить
Go to the top of the page
 
+Quote Post
amiller
сообщение May 8 2016, 15:04
Сообщение #66


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

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(ViKo @ May 8 2016, 17:45) *
О! Может, топикстартер все же напутал с определением своего типа беззнакового?

Когда я разместил примеры в файлах - там уже стандартные названия сишных типов, как раз чтобы не было путаницы.

Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 15:24
Сообщение #67


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(ViKo @ May 8 2016, 17:45) *
О! Может, топикстартер все же напутал с определением своего типа беззнакового?

Знаковость тут присутствует лишь в силу упоминания правил "integral promotions".
В случае, если бы temp1 и temp2 были знаковыми, результат был совершенно тем же.

Грубо говоря, написанный код if (~temp1 != temp2) компилятор видит как if(~rvalue32(temp1)!=rvalue32(temp2))

~rvalue32(temp1) совершенно другое значение нежели ~temp1.

Сообщение отредактировал aiwa - May 8 2016, 15:40
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 15:45
Сообщение #68


Универсальный солдатик
******

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



Почему никто не комментирует листинги от Кейла? Все пытаются оправдать ИАР.

Цитата(amiller @ May 8 2016, 18:04) *
Когда я разместил примеры в файлах - там уже стандартные названия сишных типов, как раз чтобы не было путаницы.

И Кейл их скомпилировал, как надо.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 15:53
Сообщение #69


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(ViKo @ May 8 2016, 18:40) *
Почему никто не комментирует листинги от Кейла? Все пытаются оправдать ИАР.

Кто такой Билл наслышан, Кейла не знаю?
ИАР действует в соответствии со стандартом, а этот результат заложен там.
И это не оправдание, а всего лишь констатация печального факта.


Цитата(ViKo @ May 8 2016, 18:45) *
И Кейл их скомпилировал, как надо.


С АРМами пока не работал, но если не ошибаюсь, то Вы компилировали для 16-ти битного режима.
А в нем же uint16_t совпадает с unsigned int, поэтому происходит расширение до rvalue16(temp1).
При этом ~rvalue16(temp1) полностью совпадает с ~temp1.

Сообщение отредактировал aiwa - May 8 2016, 15:54
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 15:57
Сообщение #70


Универсальный солдатик
******

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



Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков.
aiwa, ошибаетесь.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 16:20
Сообщение #71


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(ViKo @ May 8 2016, 18:57) *
Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков.
aiwa, ошибаетесь.

Я ничего не утверждаю - увидел в Ваших листингах "THUMB" вот и высказал предположение.
Если он компилирует верно и для 32-разрядного режима, то только можно этому порадоваться.
Есть надежда, что и в стандарт внесут соответствующие изменения.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 8 2016, 16:41
Сообщение #72


Гуру
******

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



Цитата(ViKo @ May 8 2016, 20:37) *
Правильно, продвигается до знакового целого. Но почему 65534 должно "превратиться в -1?
jcxz, об чем вы, о каких ошибках? Я где хочу,там пишу с ошибками, а компилятор их ловит. Где хочу читаю все ремарки.

Я не знаю о каких ошибках писали Вы. Не узнаёте свои слова? Уже начали отмечать или ещё не закончили? biggrin.gif

Цитата(Огурцов @ May 8 2016, 20:53) *
таким, что если бы я хотел написать нечто осмысленное, то использовал ifdef
а так как написан if, то вероятно тут косяк, о коем компилятор обязан сообщить

Ещё раз прочитайте по буквам: причём там ifdef???
Для справки: ifdef - используется для проверки определено ли данное имя или нет.
В моём примере константа всегда определена. Но может принимать разные значения (1, 2, ...).
И то, что там написан if - вполне нормально, а никакой не косяк. Поэтому компилятор правильно и молчит.
В си аргумент оператора if - выражение, которое может состоять из переменных и констант.
На этапе выполнения значение этого выражения вычисляется. На этапе компиляции может осуществляться оптимизация этого выражения.
Варнингов на приведённые мною примеры не должно быть никаких. Что и подтверждает IAR.

PS: Тут уже все отмечают что-ль??? santa2.gif

Цитата(ViKo @ May 8 2016, 21:45) *
Почему никто не комментирует листинги от Кейла? Все пытаются оправдать ИАР.

Может потому что его никто не пользует? sm.gif
И зачем оправдывать IAR? Он не выдал варнинг? Так и правильно сделал!
Go to the top of the page
 
+Quote Post
scifi
сообщение May 8 2016, 16:43
Сообщение #73


Гуру
******

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



Цитата(ViKo @ May 8 2016, 18:57) *
Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков.

Да? Именно поэтому сразу после покупки АРМ заменил кейловский убогий компилятор своим (он же RealView)? biggrin.gif
Кейл неплохо делает всё остальное (среда, отладчик, поддержка огромного зоопарка МК), но в компиляторах они точно не чемпионы.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 8 2016, 17:00
Сообщение #74


Гуру
******

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



Цитата(ViKo @ May 8 2016, 21:57) *
Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков.
aiwa, ошибаетесь.

Посмотрел Ваш результат компиляции Кейл. Результат этот не делает чести Кейлу - теперь точно не променяю IAR на него! laughing.gif
IAR на этапе компиляции правильно оптимизировал выражение выкинув ненужный код.
Кейл-же оставил бессмысленный код. Значение выражения всегда будет "истина".
Так что: MVNS и CMP - лишние, а BEQ надо заменить на безусловный B.

Цитата(aiwa @ May 8 2016, 21:53) *
С АРМами пока не работал, но если не ошибаюсь, то Вы компилировали для 16-ти битного режима.
А в нем же uint16_t совпадает с unsigned int, поэтому происходит расширение до rvalue16(temp1).
При этом ~rvalue16(temp1) полностью совпадает с ~temp1.

Бред.
В ARM разрядность операций и регистров не зависит от режима - хоть Thumb хоть ARM - всё равно 32 бита.
Режимы ARM и Thumb - определяют только способ кодирования инструкций и их количество.
К тому-же, указанный ТС-ом МК, имеет ядро Cortex-M, которое знает только набор инструкций Thumb2.
Учите матчасть!
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 18:11
Сообщение #75


Универсальный солдатик
******

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



Дополню для ясности. У Cortex-M команды - THUMB2 - смесь 16-битовых и 32пбитовых команд. А регистры, естественно, 32-битовые.
jcxz, я не отмечаю... Но подлечиться не помешает. Перестаю понимать людей.
Что касается Кейла, то он сделал то, что ему задали. Задам ему оптимизацию, посмотрим, что выдаст... Кто чемпион... чем сердце успокоится...
scifi, значит, RealView чемпион. Мне одинаково хорошо.

Задал -o3. Но, поскольку temp не volatile, Кейл выкинул всё. В обоих случаях снова все одинаково.
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 -O3 --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
;;;311 /* end of stdint.h */
;;;3 int main ()
000000 2000 MOVS r0,#0
|L1.2|
;;;4 {
;;;5 uint16_t temp1, temp2;
;;;6 for (unsigned int i = 0; i < 10; i++)
000002 1c40 ADDS r0,r0,#1
000004 280a CMP r0,#0xa
;;;7 {
;;;8 temp1 = 0x0001;
;;;9 temp2 = 0xFFFE;
;;;10 if (~temp1 != temp2) continue;
000006 d3fc BCC |L1.2|
;;;11 temp2 = temp1;
;;;12 }
;;;13 }
000008 2000 MOVS r0,#0
00000a 4770 BX lr
ENDP


__ARM_use_no_argv EQU 0
Go to the top of the page
 
+Quote Post
Огурцов
сообщение May 8 2016, 18:19
Сообщение #76


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(jcxz @ May 8 2016, 17:41) *
Ещё раз прочитайте по буквам: причём там ifdef???
Для справки: ifdef - используется для проверки определено ли данное имя или нет.
В моём примере константа всегда определена. Но может принимать разные значения (1, 2, ...).

ещё раз прочитайте ответ - вы обязаны записать это выражение правильно, иначе получайте предупреждение
кто должен разбираться, что там у вас там такое эти 1, 2..., или вы сможете вспомнить через полгода, что оно означало ?
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 8 2016, 19:42
Сообщение #77


Универсальный солдатик
******

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



Таки да, операция ~temp1 дает число 0xFFFFFFFE. Вот если результат инверсии сохранить в uint16_t, тогда урежется до 0xFFFE.
Я тут внес сумятицу в дискуссию...
Отладчик Кейловский (чемпион!) рулит.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 8 2016, 22:52
Сообщение #78


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
halfdoom
сообщение May 9 2016, 06:43
Сообщение #79


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

Группа: Свой
Сообщений: 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();
}


широко используются при условной компиляции без использования препроцессора.
Go to the top of the page
 
+Quote Post
amiller
сообщение May 9 2016, 07:54
Сообщение #80


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

Группа: Участник
Сообщений: 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;" предупреждение есть, хотя результат ещё более определен, чем в первом случае.
Для меня лично (по результатам обсуждения) логично бы выглядело наличие предупреждения и в первом пункте.
Но видимо это уже связано с многопроходностью компилятора (код выбрасывается на уровне, когда предупреждения
уже не формируются).
Наверное нельзя это оценивать однозначно как хорошо или как плохо. Просто надо иметь в виду, что такая ситуация
возможна и больше обращать внимание на такие неявные на первый взгляд особенности языка и действий компилятора.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 9 2016, 08:59
Сообщение #81


Гуру
******

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



Цитата(Огурцов @ May 9 2016, 00:19) *
ещё раз прочитайте ответ - вы обязаны записать это выражение правильно, иначе получайте предупреждение
кто должен разбираться, что там у вас там такое эти 1, 2..., или вы сможете вспомнить через полгода, что оно означало ?

Что именно неправильно в моей записи и почему?
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 9 2016, 11:10
Сообщение #82


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 9 2016, 11:56
Сообщение #83


Гуру
******

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



QUOTE (aiwa @ May 9 2016, 14:10) *
В результате работы компилятора будет выполнен выводящий сообщение блок.

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



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 9 2016, 12:41
Сообщение #84


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(zltigo @ May 9 2016, 14:56) *
Если "программист" не знает языка и НЕ ХОЧЕТ читать сообщения компилятора ПОДАВИВ ИХ, то да.

Вы вопрос качества языка постоянно сводите к вопросу качества программиста.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 9 2016, 12:49
Сообщение #85


Гуру
******

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



Цитата(aiwa @ May 9 2016, 15:41) *
Вы вопрос качества языка постоянно сводите к вопросу качества программиста.

Язык такой, какой он есть. Де факто стандарт для программирования микроконтроллеров. Мы все крепки задним умом. Было бы неплохо, конечно, обобщить передовой опыт, родить супер-пупер язык для МК, который в 100500 раз более лучше, чем Си, и отправить его на машине времени туда, куда надо. Но что-то мне подсказывает, что троечникам это не поможет. Учебник всё равно надо читать.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 9 2016, 13:38
Сообщение #86


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
halfdoom
сообщение May 9 2016, 14:51
Сообщение #87


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

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



Цитата(aiwa @ May 9 2016, 14:10) *
В результате работы компилятора будет выполнен выводящий сообщение блок.


И что вас здесь смущает? Левый операнд оператора сравнения будет расширен до размера int, а затем инвертирован, что на 32-х битной архитектуре приведет к установке битов старшего слова в 1. Правый операнд в силу беззнакового типа будет дополнен нулями. Очевидно, что 0xffffxxxx != 0x0000xxxx. Если сделать первый операнд знаковым, то результат может показаться странным, т.к. числа до 0х8000 будут давать другой результат. В любом случае, это полностью документированное в стандарте поведение - никаких неожиданностей здесь нет.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 9 2016, 16:00
Сообщение #88


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Tahoe @ May 6 2016, 08:58) *
3. Насчет обязан или не обязан компилер. Конечно не обязан, его дело компилировать. Зато статический анализатор кода сразу завопил бы, с негодованием. Благо в последних IAR встроен C-Stat. Настоятельно рекомендую натравить его на код. Гарантирую(с), он еще много "чудес" выявит в коде. wink.gif

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

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

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

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


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 9 2016, 16:11
Сообщение #89


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
dxp
сообщение May 9 2016, 16:29
Сообщение #90


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (zltigo @ May 9 2016, 19:38) *
Python и иже с ними.

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

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 9 2016, 16:51
Сообщение #91


Гуру
******

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



Цитата(scifi @ May 9 2016, 18:49) *
Было бы неплохо, конечно, обобщить передовой опыт, родить супер-пупер язык для МК, который в 100500 раз более лучше, чем Си, и отправить его на машине времени туда, куда надо. Но что-то мне подсказывает, что троечникам это не поможет. Учебник всё равно надо читать.

Неумехи просто станут делать другие ошибки. И опять будут во всём винить компилятор. А больше ничего не изменится.
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 9 2016, 16:57
Сообщение #92


Гуру
******

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



QUOTE (dxp @ May 9 2016, 19:29) *
Питон - великолепный язык, очень простой, но при этом необычайно мощный, гибкий.

Ага. Беды начинаются, когда "обучившиеся программированию" начинают на нем программировать sad.gif.
QUOTE
И создавался он не ради языка, а как язык для обучения программированию

Вот то, что он создавался для обучения программированию - вот это и есть родимое пятно всех "языков ради языка". Ни Си ни Си++, ни тот же Perl не создавались для обучения, они создавались для РАБОТЫ.
QUOTE
, но оказался очень эффективным и для решения практических задач.

"Мама мыла раму..." © sad.gif. В реальности, все хуже - не далее, как месяц назад очередная утилитка тупо отказалась запускаться вываливаясь с характерными питоновскими воплями sad.gif. Утилитка о NXP/Jennic просто командная строка, но зачем то размером 250K и DLL-ок на полмега. За что?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 9 2016, 23:30
Сообщение #93


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(halfdoom @ May 9 2016, 17:51) *
Если сделать первый операнд знаковым, то результат может показаться странным, т.к. числа до 0х8000 будут давать другой результат.

Вот как раз если первый операнд сделать знаковым, то в случае операции ~ красота картинки сохранится:
temp2 = 0xFFFE расширится его до 0xFFFFFFFE, а последующая операция ~temp2 обнулит лишние старшие навязанные два байта.

Поэтому в начальном примере код if(~(signed int16)temp2 !=temp1) continue; даст ожидаемый результат.

Цитата(halfdoom @ May 9 2016, 17:51) *
И что вас здесь смущает?


Согласно великому классику "В компиляторе все должно быть прекрасно...".
В нашем конкретном случае с логическими побитовыми операциями вынужденность добавления явных преобразований похожих на
Код
if(~(signed int16)temp2 !=temp1) continue;

либо

if( (unsigned int16)(~temp2) !=temp1) continue;

наводит на мысль, что некоторые моменты в стандарте шиворот-навыворот.

Сообщение отредактировал aiwa - May 9 2016, 23:31
Go to the top of the page
 
+Quote Post
halfdoom
сообщение May 10 2016, 04:20
Сообщение #94


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

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



Цитата(aiwa @ May 10 2016, 02:30) *
наводит на мысль, что некоторые моменты в стандарте шиворот-навыворот.


Стандарт не обязан быть логичным для всех, потому что это стандарт. Однако если вспомнить, что все операции над переменными типа char и short производятся только после приведения к типу int, то многое становится понятным. Почему к int? Потому что существовали и, видимо, существуют архитектуры в которых арифметические операции возможны только для операндов с размером машинного слова, которое и представлено типом int. Иными словами, правила преобразований в С архитектурно зависимы, и в спорных случаях следует использовать явное приведение типов.

Кроме того, попробуйте разобраться, как должны работать следующие операторы:
Код
unsigned short a, b;

if (~(a + b) & ~0xf) {...}

short a, b;

if (~(a + b) & ~0xf) {...}
Go to the top of the page
 
+Quote Post
svss
сообщение May 10 2016, 05:13
Сообщение #95


Местный
***

Группа: Свой
Сообщений: 231
Регистрация: 19-12-08
Из: Новосибирск
Пользователь №: 42 594



Цитата(zltigo @ May 9 2016, 17:56) *
Если "программист" не знает языка и НЕ ХОЧЕТ читать сообщения компилятора ПОДАВИВ ИХ, то да.

Бывает хуже. Например IAR выдаёт предупреждение "unreachable code", а Keil то же место тихо-спокойно пропускает.
(прямо относится к исходному мессаджу)

О сколько нам открытий трудных..
Go to the top of the page
 
+Quote Post
dxp
сообщение May 10 2016, 06:57
Сообщение #96


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (zltigo @ May 9 2016, 22:57) *
Ага. Беды начинаются, когда "обучившиеся программированию" начинают на нем программировать sad.gif.

Беспредметное, безосновательное утверждение.

QUOTE (zltigo @ May 9 2016, 22:57) *
Вот то, что он создавался для обучения программированию - вот это и есть родимое пятно всех "языков ради языка". Ни Си ни Си++, ни тот же Perl не создавались для обучения, они создавались для РАБОТЫ.

Языком для обучения он позиционировался в 1990 году, с тех пор практически сразу стал языком для решения практических задач. Его ни в коем случае нельзя сравнивать с C/C++ - совершенно разные возможности и ниши, но если сравнивать с перлом, то сравнение будет не в пользу последнего.

QUOTE (zltigo @ May 9 2016, 22:57) *
"Мама мыла раму..." © sad.gif. В реальности, все хуже - не далее, как месяц назад очередная утилитка тупо отказалась запускаться вываливаясь с характерными питоновскими воплями sad.gif. Утилитка о NXP/Jennic просто командная строка, но зачем то размером 250K и DLL-ок на полмега. За что?

Понятия не имею, в чём вы. Программа на питоне - это текстовый скрипт. Для исполнения она требует исполняемой среды. Про какие dll речь, мне не ведомо.

Если наводите критику, так делайте это предметно. Конкретно что кривого в питоне, какие косяки в его дизайне. Про Аду не спрашиваю, про неё сам знаю. И Ада - действительно искусственно созданный ЯП по ТЗ МО США. Но питон - нет, у него совершенно другая история и свой путь развития. И питону уже не надо доказывать своё право на существование - он давно это доказал делом. Когда я познакомился с питоном лет 10 назад, так забыл как страшный сон эти sed'ы и awk, и с тех пор все утилиты для себя пишу на питоне, ни разу не пришлось разочароваться. И у всех, кого знаю, кто познакомился с питоном, чем плотнее знакомство, тем выше оценка. Подозреваю, что вы с ним реально почти не знакомы, но пришлось столкнуться с парой образчиков говнокода, отсюда и мнение о языке. Тут можно напомнить, что на сях легко наговнкодить так, что питонам и не снилось. Но это не характеризует сам язык.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 10 2016, 07:58
Сообщение #97


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(halfdoom @ May 10 2016, 07:20) *
Стандарт не обязан быть логичным для всех, потому что это стандарт.

Полностью согласен, но мне кажется он должен при возможности следовать канонам формальной логики.
Компилятору желательно еще быть и удобным: повторюсь с примером, когда знаковый тип 'char' компилятор всегда
трактует как 'unsigned char' по желанию пользователя.


Цитата(halfdoom @ May 10 2016, 07:20) *
Потому что существовали и, видимо, существуют архитектуры в которых арифметические операции возможны только для операндов с размером машинного слова, которое и представлено типом int. Иными словами, правила преобразований в С архитектурно зависимы, и в спорных случаях следует использовать явное приведение типов.

Да этот вопрос как бы и не касается архитектуры - только небольшая рокировка явного и неявного преобразования типов исключительно для операции ~: операции результат которой остается в разрядной рамке операнда.
Если компилятор способен сгенерировать ожидаемый код при явном приведении типов ((uint16_t)~temp1), то неплохо бы иметь такую возможность по умолчанию, не мозоля пальцы на явное преобразование и впоследствии глаза при чтении текста.
Для полноты картины при бинарных операциях неплохо бы проводить расширение к большему по размеру операнду.

Цитата(halfdoom @ May 10 2016, 07:20) *
Кроме того, попробуйте разобраться, как должны работать следующие операторы:
Код
unsigned short a, b;

if (~(a + b) & ~0xf) {...}

short a, b;

if (~(a + b) & ~0xf) {...}


Все довольно просто: результат (unsigned short+unsigned short) не будет 'unsigned short' потому что операция суммирования выходит за пределы разрядной сетки 'unsigned short' и результат будет зависеть от архитектуры в согласии с правилами целочисленного расширения.

Сообщение отредактировал aiwa - May 10 2016, 08:05
Go to the top of the page
 
+Quote Post
scifi
сообщение May 10 2016, 08:13
Сообщение #98


Гуру
******

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



Цитата(aiwa @ May 10 2016, 10:58) *
повторюсь с примером, когда знаковый тип 'char' компилятор всегда трактует как 'unsigned char' по желанию пользователя.

Тип char можно назвать знаковым только по неведению. Не забивайте себе голову лишними предрассудками, а просто загляните в стандарт. Да, неопределённость в вопросе знаковости типа char раздражает. Видимо, есть "исторические причины". Тем не менее, с типом char не надо делать арифметику. Тип char - он для букв, а не чисел.

Цитата(aiwa @ May 10 2016, 10:58) *
Если компилятор способен сгенерировать ожидаемый код при явном приведении типов ((uint16_t)~temp1), то неплохо бы иметь такую возможность по умолчанию, не мозоля пальцы на явное преобразование и впоследствии глаза при чтении текста.

Код, который для вас кажется ожидаемым, для кого-то другого легко может быть неожиданным. Логика стандарта при приведении типов абсолютно понятна: она заточена под традиционную арифметику с числами. Операции над битами - это нечто иное. Ну что ж, привыкайте. Почитайте стандарт, и тогда компилятор не будет выдавать "неожиданный код".
Go to the top of the page
 
+Quote Post
halfdoom
сообщение May 10 2016, 08:49
Сообщение #99


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

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



Цитата(aiwa @ May 10 2016, 10:58) *
Все довольно просто: результат (unsigned short+unsigned short) не будет 'unsigned short' потому что операция суммирования выходит за пределы разрядной сетки 'unsigned short' и результат будет зависеть от архитектуры в согласии с правилами целочисленного расширения.

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

Цитата(dxp @ May 10 2016, 09:57) *
Языком для обучения он позиционировался в 1990 году, с тех пор практически сразу стал языком для решения практических задач. Его ни в коем случае нельзя сравнивать с C/C++ - совершенно разные возможности и ниши, но если сравнивать с перлом, то сравнение будет не в пользу последнего.

Это, конечно, жуткий оффтопик, но здесь с вами согласен - сравнивать питон следует только с перлом или авк.

Цитата(dxp @ May 10 2016, 09:57) *
Если наводите критику, так делайте это предметно. Конкретно что кривого в питоне, какие косяки в его дизайне.


Претензий к нему не много, но они вшиты намертво и меняться не будут:

отвратительный дизайн ООП модели (числа и строки не являются объектами, никуда не годный синтаксис доступа к родительским классам - сравните с C++);
очень медленные треды (из-за кривого дизайна интерпретатора), решается вывертами типа мультипроцессинга;
global/nonlocal - это вообще без комментариев;
де-факто существуют две несовместимые версии языка: python2/python3, а так-же наблюдается антагонизм сторонников как первого, так и второго;
однострочные лямбды - ограничение, видимо, произрастает из семантической значимости величины отступа.

Мы попытались перенести проект написанный на C++ и убедились, что овчинка совершенно не стоит выделки. А вот для скриптов, тест-модулей и прочих несложных программ питон подходит просто идеально, но здесь с ним в конкуренцию вступает Ruby.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 10 2016, 09:43
Сообщение #100


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(scifi @ May 10 2016, 11:13) *
Код, который для вас кажется ожидаемым, для кого-то другого легко может быть неожиданным.

Я не имею ввиду себя или еще кого-то конкретно. Ожидаемый - с точки зрения формальной логики: если b=~а то-> ~b == а.

Цитата(halfdoom @ May 10 2016, 11:49) *
Пример немного не об этом, но уж раз вы завели речь о разрядной сетке - при использовании uint8_t вместо short все равно будет расширение типа до int, хотя результат помещается в short.

Я описал только первый вариант Вашего примера потому что для второго, где short, действия совершенно аналогичны - в силу того, что разряд суммы выходит за пределы двухбайтной сетки.
Но в обоих случаях тип операнда для ~ уже не является типом разрядности short по априори, до выполнения самой арифметической операции с необходимостью расширения операндов.

В принципе, все сводится к случаю, когда источником операнда для ~ является lvalue-значение.

Go to the top of the page
 
+Quote Post

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

 


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


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