Ответ 1
Во-первых, если вы можете исправить func
(разрешено изменять его источник), тогда исправьте его. Если его вычисления можно сделать с помощью указателей, то сделайте их с указателями и указателями возврата. Иногда есть веские причины для работы с адресами как целые числа (например, связанные с проблемами выравнивания в специальном коде). В этом случае измените func
, чтобы использовать тип uintptr_t
(определенный в stdint.h
). Он предназначен для обработки указателей как целых чисел, когда это необходимо. (Существует также intptr_t
, если по какой-то причине арифметика подписана лучше, но я обычно считаю unsigned uintptr_t
менее неприятным.) Предпочтительно func
должен преобразовать uintptr_t
в указатель при его возврате, поэтому возвращаемый тип func
будет указателем (что-то, возможно, some_struct
или void
).
Если вы не можете исправить func
, то вы можете использовать приведения, чтобы сообщить компилятору, что вы собираетесь выполнять сделанные преобразования. Однако это конкретное сообщение об ошибке сообщает вам, что вы не просто конвертируете целое число в указатель, а то, что вы преобразовываете целое число одного размера (например, четыре байта) в указатель другого размера (например, восемь байтов). Вероятно, этот код был первоначально написан для системы, где целочисленный тип, возвращаемый func
, имел тот же размер, что и тип указателя, но теперь вы компилируете систему, где тип указателя больше или меньше этого целочисленного размера.
В этом случае вы должны убедиться, что вычисление, выполняемое func
, работает в новой архитектуре. Если он возвращает только 32-битное значение, будет ли оно всегда содержать правильное значение? То есть, ничто не будет потеряно отсутствующими высокими 32 битами? Нет адреса, который func
должен вычислять когда-либо превышающий максимальное значение целочисленного типа, который он использует? Если func
использует знаковые целочисленные типы, рассмотрите также знаковый бит.
Если вы гарантировали правильность значения, возвращаемого func
, то вы можете использовать явные приведения, такие как: some_struct *ptr = (some_struct *) (intptr_t) func();
.