标准是否要求在调用函数时显式转换为 void * 参数?

问题描述 投票:0回答:1

考虑以下函数声明:

void foo(void *);

标准有关于函数调用的明确段落

6.5.2.2/p7

如果表示被调用函数的表达式的类型为 确实包含原型,参数被隐式转换,如 如果通过赋值,则给对应参数的类型,取 每个参数的类型是其非限定版本 声明类型。

因此,参数转换就像通过简单赋值一样执行。现在考虑简单赋值的规则

6.5.16.1/p1
:

左操作数具有原子、限定或非限定指针类型, 和(考虑左操作数在左值之后的类型 转换)一个操作数是指向对象类型的指针,另一个操作数是 是指向 void 的限定或非限定版本的指针,并且 左边指向的类型具有所指向类型的所有限定符 到右边;

因此,从

void *
到任何指针类型的转换(但反之亦然)是由赋值运算符的规则保证的。现在,由于
6.3.2.3/p1
保证了转换为
void *
的合法性:

指向 void 的指针可以与指向任何对象的指针相互转换 类型。

为了调用函数,需要显式

(void *)
。示例:

struct some_struct *ptr = //...
foo(ptr) // non conforming
foo((void *) ptr) //conforming

问题: 在调用上面示例中的函数时是否需要显式转换为

void *
才能保持一致性,还是我错过了某些内容?

c function pointers
1个回答
0
投票

你错过了一些东西 - 即使你引用了它。

考虑问题中代码的稍微修改版本:

void foo(void *p);

struct some_struct *ptr;
foo(ptr);

当我们调用

foo
时,我们将其参数
p
赋值为

void *p = ptr;

这是完全有效的,因为

  1. 左操作数具有...非限定指针类型,并且
  2. 一个操作数(即
    ptr
    是指向对象类型的指针,另一个
    p
    是指向
    void
    的限定或非限定版本的指针,并且
  3. 左侧指向的类型具有右侧指向的类型的所有限定符(即两侧都没有限定符)。
© www.soinside.com 2019 - 2024. All rights reserved.