|
|
  |
Детская ошибка |
|
|
|
May 8 2016, 14:27
|
Местный
  
Группа: Участник
Сообщений: 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).
|
|
|
|
|
May 8 2016, 14:43
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(ViKo @ May 8 2016, 17:37)  Правильно, продвигается до знакового целого. Но почему 65534 должно "превратиться в -1? jcxz, об чем вы, о каких ошибках? Я где хочу,там пишу с ошибками, а компилятор их ловит. Где хочу читаю все ремарки. Ах, точно, Вы правы - у меня опечятка: в результате расширения получается знаковый 0x0000FFFE.
|
|
|
|
|
May 8 2016, 15:04
|
Частый гость
 
Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612

|
Цитата(ViKo @ May 8 2016, 17:45)  О! Может, топикстартер все же напутал с определением своего типа беззнакового? Когда я разместил примеры в файлах - там уже стандартные названия сишных типов, как раз чтобы не было путаницы.
|
|
|
|
|
May 8 2016, 15:24
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
May 8 2016, 15:53
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
May 8 2016, 16:20
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(ViKo @ May 8 2016, 18:57)  Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков. aiwa, ошибаетесь. Я ничего не утверждаю - увидел в Ваших листингах "THUMB" вот и высказал предположение. Если он компилирует верно и для 32-разрядного режима, то только можно этому порадоваться. Есть надежда, что и в стандарт внесут соответствующие изменения.
|
|
|
|
|
May 8 2016, 16:41
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ May 8 2016, 20:37)  Правильно, продвигается до знакового целого. Но почему 65534 должно "превратиться в -1? jcxz, об чем вы, о каких ошибках? Я где хочу,там пишу с ошибками, а компилятор их ловит. Где хочу читаю все ремарки. Я не знаю о каких ошибках писали Вы. Не узнаёте свои слова? Уже начали отмечать или ещё не закончили?  Цитата(Огурцов @ May 8 2016, 20:53)  таким, что если бы я хотел написать нечто осмысленное, то использовал ifdef а так как написан if, то вероятно тут косяк, о коем компилятор обязан сообщить Ещё раз прочитайте по буквам: причём там ifdef??? Для справки: ifdef - используется для проверки определено ли данное имя или нет. В моём примере константа всегда определена. Но может принимать разные значения (1, 2, ...). И то, что там написан if - вполне нормально, а никакой не косяк. Поэтому компилятор правильно и молчит. В си аргумент оператора if - выражение, которое может состоять из переменных и констант. На этапе выполнения значение этого выражения вычисляется. На этапе компиляции может осуществляться оптимизация этого выражения. Варнингов на приведённые мною примеры не должно быть никаких. Что и подтверждает IAR. PS: Тут уже все отмечают что-ль???  Цитата(ViKo @ May 8 2016, 21:45)  Почему никто не комментирует листинги от Кейла? Все пытаются оправдать ИАР. Может потому что его никто не пользует?  И зачем оправдывать IAR? Он не выдал варнинг? Так и правильно сделал!
|
|
|
|
|
May 8 2016, 16:43
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(ViKo @ May 8 2016, 18:57)  Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков. Да? Именно поэтому сразу после покупки АРМ заменил кейловский убогий компилятор своим (он же RealView)? Кейл неплохо делает всё остальное (среда, отладчик, поддержка огромного зоопарка МК), но в компиляторах они точно не чемпионы.
|
|
|
|
|
May 8 2016, 17:00
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ May 8 2016, 21:57)  Кейл, он же Кайл, он же Keil (нем.), он же куплен ARM (АРМ), поскольку, как выясняется, компилирует без косяков. aiwa, ошибаетесь. Посмотрел Ваш результат компиляции Кейл. Результат этот не делает чести Кейлу - теперь точно не променяю IAR на него! 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. Учите матчасть!
|
|
|
|
|
May 8 2016, 18:11
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 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
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|