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

如何使用没有错误或警告的函数指针初始化联合? 该代码针对嵌入式,必须在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

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

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


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

sousou0263 回答:C和C ++的联合函数指针初始化

在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

,

不是很漂亮,但是有一些可能性。 C ++具有构造函数重载。 C具有_Generic和指定的初始值设定项。

typedef int foo_t (int num,int data);
typedef int fee_t (int num,float data);

typedef struct List
{
  union 
  {
    foo_t* foo;
    fee_t* fee;
  };

  #ifdef __cplusplus
    List(foo_t* f) :foo(f){}
    List(fee_t* f) :fee(f){}  

    #define FOO_INIT(f) List(f)
    #define FEE_INIT(f) List(f)
  #else
    #define FOO_INIT(f) { .foo = _Generic((f),foo_t*: (f)) }
    #define FEE_INIT(f) { .fee = _Generic((f),fee_t*: (f)) }
  #endif   
} List;

int the_foo (int num,int data){ return 0;}
int the_fee (int num,float data){ return 0;}

int main (void)
{
  List list_foo = FOO_INIT(the_foo);
  List list_fee = FEE_INIT(the_fee);
  return 0;
}

无论使用哪种语言,都应该输入安全类型。

本文链接:https://www.f2er.com/3015789.html

大家都在问