Ответ 1
Хорошо ли использовать
intptr_t
как хранилище общего назначения (для хранения указателей и целочисленных значений) вместоvoid*
?
Нет.
intptr_t
не гарантируется. Во-первых, как вы заметили, это было введено на C99. Во-вторых, реализациям не требуется иметь целочисленный тип, достаточно большой для хранения преобразованных значений указателя без потери информации.
Преобразование int
в intptr_t
и обратно вряд ли потеряет информацию, но нет реальной гарантии, что intptr_t
шире, чем int
.
Если вы хотите сохранить значения указателя, сохраните их в объектах указателя. Для чего предназначены объекты указателя.
Любой указатель на объект или неполный тип может быть преобразован в void*
и обратно без потери информации. Для указателей на функции нет такой гарантии, но любой тип указателя на функцию может быть преобразован в любой другой тип указателя на функцию и обратно без потери информации. (Я имею в виду стандарт C, я думаю, что POSIX предоставляет некоторые дополнительные гарантии.)
Если вы хотите сохранить целое число или значение указателя в одном и том же объекте, первое, что вам нужно сделать, это пересмотреть свой дизайн. Если вы уже это сделали и пришли к выводу, что вы действительно этого хотите, подумайте об использовании объединения (и тщательно отслеживайте, какое значение вы сохранили в последнее время).
Существуют API, которые используют аргумент void*
для передачи произвольных данных; см., например, функцию POSIX pthread_create()
. Это можно оскорбить, добавив целочисленное значение в void*
, но безопаснее передать адрес целочисленного объекта.