C和C ++的联合函数指针初始化

耶隆3

如何使用没有错误或警告的函数指针初始化联合?该代码针对嵌入式,必须在C和C ++中进行编译。

但是,我遇到的问题是,直接初始化会产生与C不兼容的指针的警告,并且在C ++中不赞成使用指定的初始化,而在C ++中会出错。

在C和C ++中,有没有警告和错误的方法吗?

最小示例:

struct List {
    union {
        int (*foo)(int num, int data);
        int (*fee)(int num, float  data);
    };
};

int foo_fun(int pnum, int data);
int fee_fun(int pnum, float  data);

static const struct List list[] = {
{
    {foo_fun},
},

{
    {fee_fun},
/* C = warning: incompatible pointer types initializing 'int (*)(int, int)'
 * with an expression of type 'int (int, float)'
 */
/* C++ = error: cannot initialize a member subobject of type 'int (*)(int, int)'
 * with an lvalue of type 'int (int, float)':
 * type mismatch at 2nd parameter ('int' vs 'float')
 */
},

/* With C++ */
{
    {.fee = fee_fun},
/*   ^^^^^^^^^^^^^
 * C++ = warning: designated initializers are a C99 feature
 */
},

};

该代码确实可以处理警告incompatible pointer typesdesignated initializers are a C99 feature

粗略的方法是删除联合并使用void指针。但是,由于明显的缺点,这远远低于我的首选选项列表。

由alinsoar正确评价。确保调用正确的函数是示例中当前省略的List中其他元素的工作。


指定的初始化将在C ++ 20中再次变得完全可用。
在此之前,它们不起作用。除了工会似乎仍在工作的地方。(减去警告)

马克斯·兰霍夫

在C ++中(在C ++ 20之前),初始化联合成员的唯一方法是联合中的构造函数。

初始化联合成员超出C中的第一个成员的唯一方法是指定的初始值设定项。

这不会留下很大的回旋余地。当心,前面的丑陋:

// For convenience
typedef int (*fooPtr)(int, int);
typedef int (*feePtr)(int, float);


#ifndef __cplusplus
#define INITIALIZE(x) .x =
#else
#define INITIALIZE(x)
#endif


struct List {
    union X {
#ifdef __cplusplus
        constexpr X(fooPtr foo_) : foo(foo_) {}
        constexpr X(feePtr fee_) : fee(fee_) {}
#endif
        fooPtr foo;
        feePtr fee;
    } x;
};

int foo_fun(int pnum, int data);
int fee_fun(int pnum, float  data);

static const struct List list[] = {
    {
        {INITIALIZE(foo) foo_fun},
    },
    {
        {INITIALIZE(fee) fee_fun},
    },
};

https://godbolt.org/z/pd42HT

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章