C99:使用不同数量的参数强制转换回调

伊万诺·波诺(Ivano Bono):

在下面的示例中,我对不应该包含参数的函数进行了CAST转换,该指针指向应接收参数的函数。假设它给出了预期的结果,那么此过程是否可能导致某些故障?在线测试:https//onlinegdb.com/SJ6QzzOKI

typedef void (*Callback)(const char*);
Callback cb;

void inserisce_cb(void* c) {
    cb=c;
}

void esegue_cb(){
    cb("pippo");
}

void scriveTitolo(const char* titolo) {
    Uart_Println(titolo);
}

void scriveTitolo2() {
    Uart_Println("pluto");
}

void main(){
    inserisce_cb(scriveTitolo);
    esegue_cb();
    inserisce_cb(scriveTitolo2);
    esegue_cb();
}
埃里克·Postpischil:

根据c 6.3.2.3 8,由c标准定义了将一个函数的指针转换为另一个函数的指针,但是使用结果指针来调用类型不兼容的函数并非如此:

可以将指向一种类型的函数的指针转换为指向另一种类型的函数的指针,然后再次返回。结果应等于原始指针。如果使用转换后的指针来调用其类型与引用的类型不兼容的函数,则该行为是不确定的。

该声明void scriveTitolo2() { … }定义了一个没有参数类型列表的函数(它使用标识符列表的旧C样式,该列表为空)并且不接受任何参数。一个Callback指针指向具有参数类型列表,并采取了一个函数const char *的参数。这些与C 2018 6.7.6.3 15不兼容:

为了使两种功能类型兼容,…如果一种类型具有参数类型列表,而另一种类型由包含(可能为空)标识符列表的功能定义指定,则两种参数的数量必须相同,…

由于它们在参数数量上不一致,因此不兼容。

上面只谈到了从转换void (*)()void (*){const char *)并使用结果调用函数的问题。还有一个单独的问题,就是将函数指针传递给inserisce_cb,该指针采用类型void *为实参的指针,该类型是指向对象类型的指针。C标准没有定义将指针转换为函数类型到对象类型的行为。为了解决这个问题,inserisce_cb应声明为采用指向函数类型的指针,例如void inserisce_cb(Callback c)

如果scriveTitolo2可以更改,则可以通过将其更改为采用const char *未使用参数并将其定义更改为来解决兼容性问题void scriveTitolo2(const char *)

(请注意,最好scriveTitolo2使用现代C风格声明as void scriveTitolo2(void) { … },而不要使用void。声明。这与问题无关,因为它不会使函数类型兼容,但是此声明格式为编译器提供了更多信息很多情况下。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Julia中使用不同数量的参数迭代不同的函数

使用不同数量的参数进行函数调用和定义

在Rust宏中使用不同数量的参数调用函数

使用不同数量的 WHERE 子句条件参数化查询

使用不同数量的参数运行 Powershell Cmdlet

使用不同数量的元素转换嵌套数据框

在CMake中强制C99(以使用“ for”循环初始声明)

如何在 clang 中使用 -std=c99 强制 Werror=declaration-after-statement

使用C99的Netbeans C GCC

在clang中强制符合C99的编译

在C99中的结构内强制枚举值的宽度

获取C99可变参数函数的参数类型

C ++使用参数返回指针-不同指针类型之间的比较缺少强制转换

可变参数宏中的C99兼容嵌套调用

如何强制使用相同URL但使用不同哈希参数的href

如何转换回调结果?

使用不同数量的列作为参数的具有动态条件的子集数据框

如何使用不同数量的命令行参数构建对象?

在对类进行专业化处理时,如何使用不同数量的模板参数?

C# 使用不同的参数重新启动线程

使用不同的类重新转换 c# 变量

使用可变参数参数将函数转换回原始签名

在C99中的宏中使用对与错

如何使用make和C99进行编译?

使用ISO C99进行咖喱/装订

在Linux上使用c99截断

使用每列使用不同参数的函数转换多列

'ISO C99在可变参数宏中至少需要一个用于“ ...”的参数'当专门使用c11和-Wno-variadic-macros时

通过强制转换或重复使用不同的对象类型来重复使用相同的功能