Подтвердить что ты не робот

Использование указателей void на разных платформах

Я слышал, что указатели сначала должны быть отброшены в void для обеспечения согласованности значений на разных платформах и должны использовать спецификатор формата %p. Почему это и какие именно проблемы?

int x=100;
int *pi=&x;
printf("value of pi is: %p",(void*)pi);
4b9b3361

Ответ 1

printf - это вариационная функция и должны быть переданы аргументы правильных типов. В стандарте говорится, что %p принимает void *.

Неявный бросок не выполняется для вариационных функций.

Цитата из N1570 7.21.6.1 Функция fprintf

p: Аргумент должен быть указателем на void. Значение указателя преобразованный в последовательность печатных символов, в определенном реализацией образом.

Ответ 2

Внутреннее представление или размер разных типов указателей не обязательно одинаково.

Например, в одной системе sizeof(void*) может быть 2, но sizeof(int*) равно 1.

Так как printf - переменная функция аргумента, она не может проверять типы входящих параметров. Если вы передали ему int*, он будет читать неправильное количество байтов, потому что он ожидает void*.

Ответ 3

p Спецификация преобразования в printf требует аргумента типа void *. C говорит, что если вы передаете аргумент другого типа, вызов вызывает поведение undefined.

Кроме того, для объектов-указателей разных типов не требуется одинаковое представление: C не гарантирует, что sizeof (void *) == sizeof (int *) например. C гарантирует, что void * имеет то же представление, что и указатели на типы символов.