SII 0 8 февраля, 2023 Опубликовано 8 февраля, 2023 · Жалоба Проверил union. Не работает. Заодно проверил, достаточно ли объявить как volatile только First, но не Last. Тоже недостаточно: ER_IROM1:0000202A STRH R7, [R0,#8] ER_IROM1:0000202C STR R5, [R0,#0xC] ER_IROM1:0000202E STRB R2, [R0,#0x10] ER_IROM1:00002030 STRD.W R2, R6, [R0] ER_IROM1:00002034 LDR R1, [R4,#4] ER_IROM1:00002036 LDR R3, [R4,#8] ER_IROM1:00002038 CMP R1, R0 ER_IROM1:0000203A STR R0, [R3] ER_IROM1:0000203C ADD.W R3, R8, #1 ER_IROM1:00002040 STR R0, [R4,#8] ER_IROM1:00002042 STRB.W R3, [R4,#0x40] ER_IROM1:00002046 BNE loc_20A2 Загрузка First и Last выполняется двумя отдельными командами (2034 и 2036), однако выборка First опять произошла до записи по Last. 1 час назад, amaora сказал: Так значит типы разные все таки бывают при работе с First и Last? Фактически -- да. First всегда указывает на первый элемент очереди (FIFO_LNK) или содержит нуль, если очередь пуста. А вот Last указывает либо на последний элемент очереди (FIFO_LNK), либо на поле First самого заголовка (или, если угодно, на сам заголовок -- FIFO_HDR). 1 час назад, jcxz сказал: Странно, а мы видим иное: запись по адресу в Last, как видим, происходит непосредственно после загрузки First. Эм... Почему? Выборка из Last идёт по адресу 2080 (самая первая LDR), запись по Last -- в 208E, а выборка First -- в 2090. В 2092 идёт запись в Last. 1 час назад, Arlleex сказал: Я, так понял, здесь классическая "грабля" с оптимизацией при strict aliasing, которую каждая тематическая статья приводит в пример Похоже на то. В общем, не глюк компилятора, а оптимизация. Правда, остаётся непонятным, почему именно он выкидывал кусок кода в моём самом первом сообщении этой темы (в операции new): вроде б не должен столь своевольно обращаться с кодом, тем более, что в delete он уже не умничал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 8 февраля, 2023 Опубликовано 8 февраля, 2023 · Жалоба 1 час назад, SII сказал: Правда, остаётся непонятным, почему именно он выкидывал кусок кода в моём самом первом сообщении этой темы (в операции new): вроде б не должен столь своевольно обращаться с кодом, тем более, что в delete он уже не умничал. Все вполне может быть объяснено тем же самым механизмом строгого alias. Компилятор, видя строчку reinterpret_cast<puint32>(Ptr) сразу отмечает undefined behavior и, соответственно, генерирует то, что ему вздумается. Компилятор считает, что полученный uint32_t * не может указывать туда же, куда указывает Ptr. А раз не указывает, а от функции требуется вернуть Ptr, то вся работа с uint32_t * выкидывается за ненадобностью, ибо никакие манипуляции с uint32_t * (тем, куда этот указатель смотрит) теоретически (так предполагает компилятор при strict aliasing) не изменят Ptr. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 8 февраля, 2023 Опубликовано 8 февраля, 2023 · Жалоба 1 час назад, Arlleex сказал: Все вполне может быть объяснено тем же самым механизмом строгого alias А почему тогда в delete не выбрасывает? Действия-то принципиально одинаковые выполняются... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 8 февраля, 2023 Опубликовано 8 февраля, 2023 · Жалоба Дык на то он и UB, чтобы фокусы на ровном месте показывать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться