C++ printf和指针
可能重复:C++ printf和指针,c++,c,C++,C,可能重复: 使用printf打印指针时,是否需要将指针强制转换为void*?换句话说,在类似于 #include <stdio.h> int main() { int a; printf("address of a = %p\n", &a); } #包括 int main(){ INTA; printf(“a=%p\n”的地址,&a); } 参数真的应该是(void*)&agcc在没有进行显式转换时似乎不会给出任何警告。我认为可能有必要进行转换。我们确定
使用
printf
打印指针时,是否需要将指针强制转换为void*
?换句话说,在类似于
#include <stdio.h>
int main() {
int a;
printf("address of a = %p\n", &a);
}
#包括
int main(){
INTA;
printf(“a=%p\n”的地址,&a);
}
参数真的应该是(void*)&a
<代码>gcc在没有进行显式转换时似乎不会给出任何警告。我认为可能有必要进行转换。我们确定指针的大小总是相同的吗?我确信我最近在stackoverflow上读到,struct*
的大小(或者可能只是对齐?)可能与union*
的大小不同。这意味着其中一个或两个可以与void*
的大小不同
因此,即使值在转换过程中变化不大,或者根本没有变化,也可能需要强制转换来确保指针本身的大小是正确的
在
print
中,%p
需要一个void*
,因此您应该显式地强制转换它。如果您不这样做,并且如果您幸运的话,那么指针大小和指针表示可能会节省时间。但是你应该明确地把它确定为——任何其他都是技术上未定义的行为。< /P> < P>这是C还是C++问题?对于C++,根据5.2.2[ExpReleCule]第7段,似乎没有任何隐式转换为<代码> VUL*。C99的6.5.2.2第6段似乎也不意味着指针类型的任何显式提升。这意味着需要显式转换为void*
,因为指针类型可以具有不同的大小(至少在C++中是这样):如果不同指针类型的布局不相同,则最终会出现未定义的行为。有人能指出,在使用变量参数列表时,在哪里可以保证以适当的大小传递指针
当然,作为C++程序员,这不是一个很大的问题:只是不要使用具有可变数量的参数的函数。但是,在C语言中,这不是一种可行的方法。是的,需要转换为
void*
int a;
printf("address of a = %p\n", &a);
&a
类型为int*
;printf的“%p”
格式需要类型为void*
的参数。int*
参数不会隐式转换为void*
,因为printf
的声明不提供除第一个参数(格式字符串)以外的其他参数的类型信息。格式字符串后的所有参数都应用了默认参数升级;这些促销不会将int*
转换为void*
可能的结果是,printf
看到一个真正属于int*
类型的参数,并将其解释为void*
类型。这是类型双关,而不是转换,并且它具有未定义的行为。如果int*
和void*
恰好具有相同的表示形式,那么它可能会起作用,但语言标准不能保证这一点,即使是暗示。我描述的双关语只是一种可能的行为;该标准实际上没有说明会发生什么
(如果您对具有可见原型的非变量函数执行相同的操作,那么编译器在调用时知道参数的类型为
void*
,那么它将生成代码来执行隐式int*
-到-void*
转换。这里不是这种情况。)是,在C语言中,您必须强制转换为void*
(我对C++一无所知)。阅读7.19.6.1中的“p--参数应该是指向void的指针”。@MrLister:不,这是错误的。您必须为printf
强制转换的原因是它是一个可变函数。原型无法告诉编译器每个参数所需的类型,因此隐式转换为void*
对您没有帮助。你真的需要演员阵容。@SethCarnegie:我认为“宗教”这个词有误导性。如果您不强制转换为void*
,在实际系统中,它将失败。@SethCarnegie:我没有一个具体的例子。我曾在void*
和int*
具有不同表示的系统上工作过(Cray T90,本机地址指向64位字,void*
和char*
在指针的高阶3位中存储字节偏移量,所有这些在软件中处理缓慢),但即使在该系统上,有效的int*
指针也是指向同一地址的有效void*
指针。但我相信也有类似的系统,字节偏移量不存储在指针本身中,void*
比int*
大@Keith:我认为问题不在于未来指针大小不同的系统。谢天谢地,这种落后已经过去了。现在的问题是优化。为了执行积极的优化,允许编译器假定您的程序只执行具有明确定义结果的操作。这可能会导致优化,导致具有未定义行为的程序(即使从天真的角度来看,未定义的行为似乎无害)严重崩溃。您的答案解决了实现中可能发生故障的机制,但关键的一点是,接口联系人要求您将正确的类型传递给printf
,如果不遵循此要求,将导致UB。@H2CO3,我不会在这个问题上的任何地方进行向下投票。至少还有一个人提出了其他的理论,也许还有很多其他人在埋伏并投反对票。我没有投反对票,但我可以看到“我不确定,但可能是这样…”这样的回答怎么会被其他人认为值得投反对票。无论如何,遗憾的是,这是迄今为止最好的答案,也是唯一一个没有完全错误的答案。@R:希望这个问题以重复的形式结束;另一个问题