如何使用没有错误或警告的函数指针初始化联合?该代码针对嵌入式,必须在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 types
或designated 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},
},
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句