приведение от учар * к уинт * дает непредсказуемый результат - PullRequest
0 голосов
/ 14 января 2019

Я компилирую этот код с C99 (с некоторыми другими определениями типов, такими как uint32 вместо uint32_t) для старой архитектуры arm.

    uint32 x2 = *((uint32 *) &data[t]);
    uint32 x3;
    memcpy(&x3, &data[t], 4);
    printf("%d %d %d %d %d %d", x2, x3, data[t], data[t + 1], data[t + 2], data[t + 3]);

(данные uchar * и имеют длину> t + 4)

но на удивление вывод такой:

-268435454 2 2 0 0 0

что не так с этим кастингом?

Ответы [ 3 ]

0 голосов
/ 14 января 2019

У вас есть несколько вопросов здесь. Не используйте указатель, используйте для него союзы.

Ваш printf формат также неверен. Вы должны использовать %u вместо %d.

0 голосов
/ 14 января 2019

Как прокомментировали остальные ответы, проблема возникает из-за неприсоединенного доступа . В то время как доступ без выравнивания абсолютно поддерживается x64 или x86, вы не можете сказать, что он полностью (un / -) поддерживается ARM, потому что он зависит от версии ARM. Есть три возможности:

  • до ARMv5 (в комплекте). ARM не поддерживал невыровненный доступ, что и делает uint32 x2 = *((uint32 *) &data[t]); (с точки зрения LDR, три из четырех байтов 32-битной переменной не выровнены в 4, и только один выровнен), поэтому результат не определен (отсюда и ошибка). Учитывая это, проблема должна быть решена программным обеспечением (для ARM __packed для не выровненных указателей или структур полезно).
  • после ARMv7 (входит в комплект) они разрешают доступ без выравнивания *, поэтому код должен быть действительным, без ошибок (однако производительность - это совершенно другая тема, и я уверен, что она будет медленнее по сравнению с выравниваемым доступом к 32-битному , но эта тема заслуживает отдельной записи).
  • ARMv6. Обычно в ARM есть что-то, что делает вещи более смешными, и выравнивание не будет другим. Здесь они добавили немного , чтобы выбрать, какой путь вы предпочитаете (ARMv5 или ARMv7).

    Учитывая "для старой архитектуры рук" комментарий, ваш случай выглядит как первый, но если вы включите свой ассемблерный код и архитектуру, это было бы здорово для полного ответа.

* некоторые инструкции не будут выполнены, поскольку они не могут его поддерживать (т. Е. STM)

0 голосов
/ 14 января 2019

Строка x2 вызывает неопределенное поведение. Во-первых, data[t] может не иметь 32-битного выравнивания, а во-вторых, возможно, строгое нарушение псевдонимов при чтении 32-битного значения из этого местоположения.

Просто удалите эту строку и используйте версию x3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...