printf("%p") 并转换为 (void *) [英] printf("%p") and casting to (void *)
问题描述
在最近的一个问题中,有人提到用 printf 打印指针值时,调用者必须将指针强制转换为 void *,如下所示:
In a recent question, someone mentioned that when printing a pointer value with printf, the caller must cast the pointer to void *, like so:
int *my_ptr = ....
printf("My pointer is: %p", (void *)my_ptr);
对于我的生活,我无法弄清楚为什么.我发现了这个问题,其中几乎是一样的.问题的答案是正确的 - 它解释了整数和指针的长度不一定相同.
For the life of me I can't figure out why. I found this question, which is almost the same. The answer to question is correct - it explains that ints and pointers are not necessarily the same length.
这当然是对的,但是当我已经有一个指针时,就像上面的例子,为什么我要从 int *
转换为 无效 *
?什么时候 int * 与 void * 不同?事实上,(void *)my_ptr
什么时候生成任何不同于简单的 my_ptr
的机器码?
This is, of course, true, but when I already have a pointer, like in the case above, why should I cast from int *
to void *
? When is an int * different from a void *? In fact, when does (void *)my_ptr
generate any machine code that's different from simply my_ptr
?
更新:多名知识渊博的响应者引用了该标准,称传递错误的类型可能会导致未定义的行为.如何?我希望 printf("%p", (int *)ptr)
和 printf("%p", (void *)ptr)
生成完全相同的堆栈-框架.两个调用什么时候会生成不同的栈帧?
UPDATE:
Multiple knowledgeable responders quoted the standard, saying passing the wrong type may result in undefined behavior. How? I expect printf("%p", (int *)ptr)
and printf("%p", (void *)ptr)
to generate the exact same stack-frame. When will the two calls generate different stack frames?
推荐答案
%p
转换说明符需要 void *
类型的参数.如果不传递 void *
类型的参数,函数调用将调用未定义的行为.
The %p
conversion specifier requires an argument of type void *
. If you don't pass an argument of type void *
, the function call invokes undefined behavior.
来自 C 标准(C11,7.21.6.1p8 格式化输入/输出函数):
From the C Standard (C11, 7.21.6.1p8 Formatted input/output functions):
"p - 参数应是指向 void 的指针."
"p - The argument shall be a pointer to void."
C 中的指针类型不需要具有相同的大小或相同的表示形式.
Pointer types in C are not required to have the same size or the same representation.
具有不同指针类型表示的实现示例是 Cray PVP,其中 void *
和 char *
的指针类型表示为 64 位,但为 32 位对于其他指针类型.
An example of an implementation with different pointer types representation is Cray PVP where the representation of pointer types is 64-bit for void *
and char *
but 32-bit for the other pointer types.
参见Cray C/C++ 参考手册",9.1.2.2"中的表 3 http://docs.cray.com/books/004-2179-003/004-2179-003-manual.pdf
See "Cray C/C++ Reference Manual", Table 3. in "9.1.2.2" http://docs.cray.com/books/004-2179-003/004-2179-003-manual.pdf
这篇关于printf("%p") 并转换为 (void *)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!