当分配到void
- 指针时,不需要强制转换(C99§6.3.2.2sub 1/§6.5.16.1sub 1)。将(例如int
- )指针传递给期望void
- 指针的函数时,这也是正确的吗?
例如:
void foo(void * p){
// Do something
}
int main(){
int i = 12;
foo(&i); // int * to void *: no cast needed?
}
当我使用GCC(4.8.1,MinGW-32)编译时,我既没有错误也没有警告(使用-Wall
& -pedantic
)。
相比之下in this answer建议此调用需要强制转换(以消除-Wformat
警告):
int main(){
int i = 12;
printf("%p\n", &i);
}
但在我的情况下,海湾合作委员会并没有抱怨。
那么:将非void
指针传递给需要void
- 指针的函数时需要强制转换吗?
答案 0 :(得分:6)
区别在于printf
是一个可变函数,可变函数在其尾随参数上遵循不同的转换规则。
foo(&i);
此处不需要强制转换,因为foo
是原型函数。 C表示&i
转换为p
的类型,就像通过赋值一样,在C中,所有对象指针类型之间都隐含void *
。
printf
的情况不同,因为像printf
这样的可变参数函数对其余参数有默认参数提升,并且指针类型的参数不会发生转换。
关于原型函数:
(C99,6.5.2.2p7)“如果表示被调用函数的表达式具有包含原型的类型,则参数被隐式转换,就像通过赋值一样,转换为相应参数的类型,每个参数的类型是其声明类型的非限定版本。“
关于可变函数的C:
(C99,6.5.2.2p7)“(C99,6.5.2.2p7)”函数原型声明符中的省略号表示法导致参数类型转换在最后声明的参数之后停止。默认参数促销在尾随时执行 参数“。
那么:将非void指针传递给需要void指针的函数时需要强制转换吗?
对于printf
,p
转化说明符需要void *
个参数。如果参数的类型不同,则函数调用将调用未定义的行为。因此,如果p
的参数是对象指针类型,则需要(void *)
强制转换。
(C99,7.19.6.1p8)“p参数应为指向void的指针。”