Отформатированное значение указателя печати - PullRequest
0 голосов
/ 25 марта 2019

Я обнаружил, что мы можем напечатать значение указателя с помощью спецификатора формата %p.N1570 7.21.6.1(p8):

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

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

struct test_t{
    int a;
}

void foo(){
    struct test_t *test_ptr = malloc(sizeof(*test_ptr));
    printf("Pointer test_ptr = %p\n", test_ptr);
}

Здесь я не преобразовал его в void *, предполагая, что компилятор сделает это за меня.Это соответствует?Или я должен преобразовать такие указатели в void * самостоятельно, например

printf("Pointer test_ptr = %p\n", (void *) test_ptr);

. Стандарт определяет, что представление и выравнивание void * такое же, как char *.Не указывается, если void * представление / выравнивание должно совпадать с любым типом объекта.

1 Ответ

2 голосов
/ 25 марта 2019

Версия с (void *) верна, и ваш исходный код вызывает неопределенное поведение. (Вы уже предоставили соответствующую стандартную цитату, поэтому мне не нужно добавлять дополнительные цитаты).

Поскольку указатель на void может быть преобразован в указатель на любой другой тип объекта, мне любопытно, нужно ли преобразование вручную

«может быть» означает, что есть вероятность того, что конверсия произойдет. Такое преобразование фактически происходит только тогда, когда оно было запрошено, причем языковой стандарт определяет, какие конструкции запрашивают преобразование.

Для аргументов printf применяются только продвижения аргументов по умолчанию. Других преобразований нет.

...