[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4630517#p4630517"]Обычно хватает ЯВУ и знаний, как тот или иной код должен работать и как он компилится в асм.[/uquote]Ой, вот только не надо называть Си языком высокого уровня! Во-первых, он и создавался-то как язык среднего уровня, типа весьма продвинутого макроассемблера. А во-вторых, как только вы пишете что-то типа:
Код: Выделить всё
PORTB |= 0x03 компилится (-О1) в три команды - IN, ORI, OUT
PORTB |= 0x01;PORTB |= 0x02; - в две команды SBI
так сразу же опускаетесь на низкий уровень, ибо не ЯВУшное это дело — ногами портов дрыгать. Программист должен понимать и постоянно помнить, что PORTB — это не переменная в ОЗУ, а какая-то периферия, и в ней может быть всё не так, как в ОЗУ, вплоть до того, что записал одно, а считал другое.
Я уже говорила - Язык Си - он мазохист. И получает цифровое удовольствие, когда программист стреляет себе в ногу.
uint16_t a = 40000, b = 30000;
uint32_t ab = a + b;
чему равно ab ?
Правильный ответ : 4464.
Ну так правильный же! Что в нём неправильного? Надо просто помнить, что это язык среднего уровня.
[uquote="OKF",url="/forum/viewtopic.php?p=4630556#p4630556"]Беда в том что Асм он под конкретную архитектуру, его не перенесёшь куда то.[/uquote]Just_Fluffy, вот здесь товарищ правильно пишет. И строчки типа PORTB|=0x01 — они тоже под конкретную архитектуру, их не перенесёшь куда-то, скажем, даже на соседнюю тиньку 24/44/84, у которой порта В почти нет (от него всего один бит, и он не только не нулевой , но даже и не первый), а есть только А. На самом деле этот вопрос чуть шире, чем градация между низким и высоким уровнем. Я как-то давненько говорил, что задачи бывают вычислительные и управленческие. Для вычислительных прекрасно подходят ЯВУ. А вот управленческие задачи на ЯВУ не решить без прибегания к низкому уровню, отсюда и костыли в Си для дрыгания ногами периферии. Отсюда же и радостные лозунги о предпочтительности ассемблера.
[uquote="Adrift",url="/forum/viewtopic.php?p=4630958#p4630958"]Стандарт говорит компилятору
все что не влазит в int сначала приводить к int:[/uquote]Нет в стандарте фразы "все что не влазит". Напротив, стандарт предписывает вести вычисления с равным приоритетом слева направо, то есть начинать с типа первого операнда, а он в примере Белой и Пушистой 16-разрядный. А у неё ещё и второй такой же. А приведение к типу результата будет выполняться только после завершения вычисления всей строки, когда результат уже будет усечён до 16 разрядов, то есть от него останется 4 тыщи с копейками. Поэтому переопределение типа (uint32_t) в этом примере достаточно дать только первому операнду. А вот расширения стандарта были всякие разные, их всех и не упомнишь.
Всего доброго.
Евгений.