提问人:St.Antario 提问时间:10/15/2023 更新时间:10/16/2023 访问量:76
标准是否要求在调用函数时显式强制转换以取消 * 参数?
Does the Standard require explicit casting to void * argument when calling a function?
问:
请考虑以下函数声明:
void foo(void *);
该标准有关于函数调用的明确段落:6.5.2.2/p7
如果表示被调用函数的表达式的类型 确实包含一个原型,参数是隐式转换的,因为 如果通过赋值,则对相应的参数类型进行,取 每个参数的类型是其 声明的类型。
因此,参数转换就像通过简单的赋值一样执行。现在考虑简单分配的规则:6.5.16.1/p1
左操作数具有原子、限定或非限定指针类型, 和 (考虑左操作数在左值之后的类型 conversion) 一个操作数是指向对象类型的指针,另一个操作数是指向对象类型的指针 是指向 void 的限定或非限定版本的指针,并且 left 指向的 type 具有 point 类型的所有限定符 到右边;
因此,从任何指针类型转换为指针类型(反之亦然)由赋值运算符规则保证。现在,由于保证了转换为以下内容的合法性:void *
6.3.2.3/p1
void *
指向 void 的指针可以转换为指向任何对象的指针,也可以从指向任何对象的指针转换 类型。
为了调用函数,显式是必需的。例:(void *)
struct some_struct *ptr = //...
foo(ptr) // non conforming
foo((void *) ptr) //conforming
问题:在调用上面示例中的函数时,是否需要显式转换为符合要求,或者我错过了某些内容?void *
答:
3赞
Toby Speight
10/15/2023
#1
你错过了一些东西——即使你引用了它。
考虑问题中代码的这个略微修改的版本:
void foo(void *p);
struct some_struct *ptr;
foo(ptr);
当我们调用 时,我们分配它的参数,就好像foo
p
void *p = ptr;
这是完全有效的,因为
- 左操作数有......非限定指针类型,以及
- 一个操作数(即 )是指向对象类型的指针,并且
ptr
- 另一个操作数 () 是指向
void
的限定或非限定版本的指针,并且p
- 左边指向的类型具有右边指向的类型的所有限定符(即两边都没有限定符)。
评论
void *
free
volatile int *
volatile
const Anything *
const
const void *
const
volatile
void* vptr = ptr
vptr