ошибка: приведение от 'Foo *' к 'unsigned int' теряет точность - PullRequest
0 голосов
/ 10 октября 2010

Я пытаюсь привести указатель к int (или к unsigned int), и независимо от того, что я пытаюсь, он не хочет работать.

Я пробовал static_cast<intptr_t>(obj), reinterpret_cast<intptr_t>(obj) и различные комбинации приведения в стиле C, intptr_t, unsigned int, и я включаю stdint.h. Из того, что я прочитал, одна из многих вещей, которые я пробовал, должна работать. Что дает?

Я не стал включать код, потому что это именно то, что я описал, но так как вы спросили, я попробовал все эти и другие комбинации:

void myfunc(Foo* obj)
{
    // ...
    uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
    uintptr_t temp = static_cast<uintptr_t>(obj);
    uintptr_t temp = (uintptr_t)obj;
    intptr_t temp = reinterpret_cast<intptr_t>(obj);
    intptr_t temp = static_cast<intptr_t>(obj);
    intptr_t temp = (intptr_t)obj;
    unsigned int temp = reinterpret_cast<unsigned int>(obj);
    unsigned int temp = static_cast<unsigned int>(obj);
    unsigned int temp = (unsigned int)obj;
    // ...
}

Все они дают одинаковую ошибку.

Ответы [ 2 ]

5 голосов
/ 10 октября 2010

Вы либо на платформе, где sizeof (Foo*) > sizeof (unsigned), либо ваш компилятор настроен на предупреждение о непереносимом коде.Обратите внимание, что большинство 64-битных компиляторов, как LP64, так и LLP64, попадают в эту категорию.

Нет требования, чтобы указатель помещался в int.В этом весь смысл intptr_t.

Если вы используете стороннюю библиотеку, которая предоставляет только int для пользовательского контекста во время callbacls, вы можете передать индекс в таблицу поиска, поэтомусам указатель хранится в таблице поиска.Это дает дополнительное преимущество, заключающееся в том, что он безопасен для типов и не нарушает допущения по алиасингу.( Comeau "tryitout" очень удобно)

#include <stdint.h>

void myfunc(class Foo* obj)
{
    uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
}

Comeau C / C ++ 4.3.10.1 (6 октября 2008 11:28:09) для ONLINE_EVALUATION_BETA2 Copyright 1988-2008Comeau Computing.Все права защищены.РЕЖИМ: строгие ошибки C ++ C ++ 0x_extensions

"ComeauTest.c", строка 5: предупреждение: переменная "temp" была объявлена, но на нее никогда не ссылались uintptr_t temp = reinterpret_cast (obj); reinterpret_cast (obj);

В строгом режиме, с -tused, компиляция прошла успешно (но помните, онлайн-компилятор Comeau не связывает).Скомпилировано с включенными расширениями C ++ 0x.

В режиме C89 это также работает:

#include <stdint.h>

void myfunc(struct Foo* obj)
{
    uintptr_t temp = (uintptr_t)obj;
}

Comeau C / C ++ 4.3.10.1 (6 октября 2008 г. 11:28:09) для ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing.Все права защищены.РЕЖИМ: строгие ошибки C90

"ComeauTest.c", строка 3: предупреждение: объявление не видно вне функции void myfunc (struct Foo * obj) ^

"ComeauTest.c",строка 5: предупреждение: переменная "temp" была объявлена, но на нее никогда не ссылались uintptr_t temp = (uintptr_t) obj;^

В строгом режиме с -tused, Compile успешно (но помните, онлайн-компилятор Comeau не связывает).

0 голосов
/ 30 апреля 2019

Конечно, лучше освоить преобразование типов с помощью явного приведения. И предыдущие ответы говорят об этом хорошо.

Но у меня есть предложение обойти компилятор. Существует опция, позволяющая компилятору принять фактическую потерю точности:

gcc -fpermissive
...