这一警告似乎没有必要. 在我的代码中,我有一个函数指针类型

(void*)(*function_pointer)(void* data)

有些函数需要这种类型的函数指针作为参数,因为它们不依赖于返回类型,它只需要是一个指针.

但是,当我传递像somestruct* function_A(void* data)这样的函数时 对于它,我得到了警告,即使somestruct*可以被隐式转换为void*,就像我可以将somestruct指针传递给函数int function_test(void* data)一样,它将在没有警告的情况下工作.

是的,我可以将function_A定义为void *作为返回类型,但这意味着所有出于其他原因使用该函数的人都必须将其返回值强制转换为somestruct *.我有两个 Select :让它保持原样,忽略让我有点恼火的警告,或者更改函数定义,这会让我更恼火.

因此,我在这里询问是否还有第三种 Select .

推荐答案

允许将任何对象指针转换为void *,但这不会传递到函数指针中的参数和返回类型.

指向函数somestruct* function_A(void*)的指针与类型void* (*function_pointer)(void*)的函数指针不兼容,因为返回类型不兼容.试图通过不兼容的指针类型调用函数将触发undefined behavior.

关于如何确定两种函数类型是否兼容的规则在C standard:

For two function types to be compatible, both shall specify compatible return types.此外,如果参数类型和参数类型都是 目前,应就参数的数量和使用达成一致 省略号终止符;对应的参数应兼容 类型.如果一种类型具有参数类型列表,而另一种类型为 由不是函数一部分的函数声明符指定 定义,并包含一个空标识符列表、参数 列表不应包含省略号终止符以及每个 参数应与从 应用默认参数提升.如果一种类型具有 参数类型列表,另一种类型由函数指定 包含(可能为空的)标识符列表的定义,两者 应就参数的数量和每个参数的类型达成一致 原型参数应与产生的类型兼容 从默认参数提升的应用程序到 相应的标识符.(在类型的确定中 兼容性和复合类型,每个参数都用 函数或数组类型被视为具有调整后的类型,并且每个 使用限定类型声明的参数被视为具有其声明类型的非限定版本.)

粗体部分是与本例相关的部分. void *和和 struct 体指针是不兼容的,即使允许在两者之间转换.

6.3.2.3p8节详细说明了函数指针转换的规则:

指向一种类型的函数的指针可以转换为指向 另一种类型的函数,然后再返回;结果将进行比较 等于原始指针.If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

最后一节用粗体表示,你试图做的事情是不允许的.

您需要将函数的返回类型更改为void *,以与函数指针类型兼容.然而,强制转换返回类型并不是必需的,因为在没有返回类型的情况下允许在对象指针和void *之间进行转换.

C++相关问答推荐

问关于C中的指针和数组

设计处理各种数据类型的方法和数据 struct

为什么输出不是从上到下C

#If指令中未定义宏?

可以将C变量限制为特定的读/写速度吗?

为什么sscanf不能正确地从这个字符串格式中提取所有数字?

Rust FFI--如何用给出返回引用的迭代器包装C风格的迭代器?

向上强制转换C中的数值类型总是可逆的吗?

Make Node函数.S有什么问题吗?

如何在C中打印包含扫描字符和整数的语句?

在基本OpenGL纹理四边形中的一个三角形中进行渲染

每次除以或乘以整数都会得到0.0000

在for循环中指向数组开头之前

为什么用非常数指针变量改变常量静态变量时会出现分段错误?

C I/O:在Windows控制台上处理键盘输入

如何在VSCode中创建和使用我自己的C库?

如何在Rust中处理C的longjmp情况?

使用 SDL2 的 C 程序中的内存泄漏

窗口消息处理函数以某种方式更改了应保持不变的 int 变量的值

如何在C中以0x格式打印十六进制值