c ++: приведение от "const variable *" к "uint32" теряет точность - PullRequest
0 голосов
/ 08 июня 2018

У меня есть две структуры rom и Transfer.

    typedef struct
    {
    const uint32 data;
    }rom;

    typedef struct
    {
    const rom* const read;
    }transfer;

    extern const transfer num;

В другой программе на C я объявил

transfer* count;

и

count = (transfer*)(*((uint32*)((uint32)&num) + 2*seqno));

Выше код компилируется вкомпилятор gcc.Но когда я включаю extern "C" {}, сохраняю файл как .cpp и собираю его с помощью компилятора g ++, я получаю ошибку.Поскольку прямое приведение типов невозможно с компилятором g ++.ошибка

ошибка: приведение от 'const Transfer *' к 'uint32 {{aka unsigned int}' теряет точность [-fpermissive]

Как мы можем выполнить типдля компилятора c ++?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Приведение указателя к целому числу, выполнение арифметики с этим целым числом и приведение к указателю является неопределенным поведением.Это верно даже для intptr_t.Единственный способ сделать арифметику указателя - непосредственно на указателе.

Это потому, что сопоставление между значениями указателя и значениями intptr_t определяется реализацией и не требует, чтобы они были одинаковыми.

0 голосов
/ 08 июня 2018

В этой строке так много неправильного.

  • Не используйте целочисленные типы домашнего приготовления.Используйте stdint.h / cstdint.То есть uint32_t, а не uint32.Это относится как к С, так и к С ++.
  • uint32_t или его домашний эквивалент не гарантирует возможности удерживать значение указателя.Вероятно, это источник сообщения компилятора.Вместо этого вы должны использовать uintptr_t.Который можно найти в stdint.h / cstdint.
    (Возможно, проблема не столько в С, сколько в С ++, а в том, что один компилятор использует 64-битные адреса, но не другой, или что-то подобное.)

  • *(uint32_t*)&some_struct - это строгое нарушение псевдонимов в C и C ++.
    (Как оказалось, вы можете перейти от uint32_t к типу структуры, если структура содержит uint32_t среди своих членов, ноне наоборот.)

    Если вы не представляете, что означает строгое алиасинг , просто не выполняют преобразования с использованием диких указателей, подобные этому, это неопределенное поведение.В частности, не делайте этого на gcc / g ++, потому что это имеет тенденцию сходить с ума, если вы делаете.(Формально он имеет право сходить с ума по стандарту ...)

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