C相当于C ++的decltype

时间:2018-01-10 07:56:09

标签: c++ c macros decltype

在我的C项目中,有一个由另一位同事创建的结构,包含一些函数指针:

struct tools {  
    int (*tool_a) (int, int, int);
    ...
};

我无权更改此结构和相关文件。

现在我用结构编码 我必须定义一个函数,其返回类型和参数列表必须与tools.tool_a相同 这意味着我的功能必须如下:

int my_func(int, int, int);

问题是结构发生了很大变化,特别是返回类型,例如int今天被size_t取代,所以我必须经常更改我的代码。
< / p>

我知道C ++中的decltype可以帮助我,所以我只想知道C是否有相同的东西?

我想我可能会使用宏但我不知道怎么样,我甚至不知道它是否可能。

REAL CASE

我正在为使用C.的Linux内核开发一些测试工具 我公司的其他组有很多版本的自定义内核。由于历史原因,其中一些使用int,其他人使用size_tssize_t等等。

现在当我编码时,我必须这样做:

// int my_func(int a, int b, int c)
size_t my_func(int a, int b, int c)
// ssize_t my_func(int a, int b, int c)
{}
struct tools my_tool = {
    .tool_a = my_func;
}

我必须继续评论和取消注释......

3 个答案:

答案 0 :(得分:9)

理智的解决方案是强制执行typedef。如果这是不可能的,并且函数可能具有的替代类型的数量是有限的,就像在这种情况下一样,你可以使用C11 _Generic烹饪。

创建具有不同名称的多个函数,而不是使用名为my_func的单个函数。根据返回类型为其名称添加前缀。然后有一个宏,它反过来根据传递的类型重定向到适当的函数。

示例:

#include <stdio.h>

/*** the struct that cannot be changed ***/
struct tools {  
    int (*tool_a) (int, int, int);
};

/*** any number of functions with different types ***/
int int_my_func(int a, int b, int c) 
{ 
  puts(__func__); 
}

size_t size_t_my_func(int a, int b, int c) 
{ 
  puts(__func__); 
}

/*** macro to select the appropriate function based on type ***/
#define my_func_typeof(type)                           \
  _Generic( (type),                                    \
            int(*)(int,int,int)    : int_my_func,      \
            size_t(*)(int,int,int) : size_t_my_func)

/*** caller code ***/
int main (void)
{
  struct tools my_tool = {
    .tool_a = my_func_typeof( (struct tools){0}.tool_a )
  };

  my_tool.tool_a(1,2,3);

}

这里我使用复合文字(struct tools){0}.tool_a来创建与tool_a相同类型的虚拟对象,然后将其传递给选择适当函数的宏。如果不支持该类型,则会出现编译器错误,因为找不到匹配的_Generic关联。

答案 1 :(得分:6)

嗯,这不是decltype但是如果您可以说服您的同事使用类型别名,则可以进行静态类型检查。

如果可以说服你的同事这样做:

typedef int tool_a_prototype(int, int, int);

struct tools {  
    tool_a_prototype *tool_a;
};

然后你可以声明你的功能:

tool_a_prototype my_tool_a;

int my_tool_a(int a, int b, int c) {
  //Whatever
}

你的友好编译器会告诉你原型是否存在不匹配。

答案 2 :(得分:0)

  

问题是结构变化很大,尤其是返回值   类型,例如int今天已被size_t取代,所以我必须   更改我的代码很多。

     

我知道C ++中的decltype可以帮助我,所以我只想知道C   有等同的东西吗?

如果您愿意使用非标准 gcc扩展名,则可以使用typeof

struct tools {  
    int (*tool_a) (int, int, int);
};

typedef typeof( ((struct tools*)NULL)->tool_a ) tool_a_type;
typedef typeof( ((tool_a_type)NULL)(0,0,0) ) tool_a_return_type;

tool_a_return_type my_func(int x, int y, int z)
{

}

struct tools my_tool = {
    .tool_a = my_func
};