我喜欢voverload一个C函数。我找到了以下内容:Function overloading in C using GCC - functions with mutiple arguments。这非常好,但现在我想根据两个参数的类型选择函数。
#define dataioWriteBin(file, data, len) \
(__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint8_t ) && __builtin_types_compatible_p(typeof(len), uint64_t ), dataioWriteBin_uint8Data_uint64Len, \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint8_t ) && __builtin_types_compatible_p(typeof(len), uint32_t ), dataioWriteBin_uint8Data_uint32Len, \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint32_t ) && __builtin_types_compatible_p(typeof(len), uint64_t ), dataioWriteBin_uint32Data_uint64Len, \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint32_t ) && __builtin_types_compatible_p(typeof(len), uint32_t ), dataioWriteBin_uint32Data_uint32Len, \
(void)0))))(file, data, len))
但是使用这段代码我得到了一个编译跟随错误:
错误:被调用对象不是函数或函数指针 (__builtin_choose_expr(__ builtin_types_compatible_p(typeof运算(*数据), uint8_t)
任何人都有一个想法,是不是可能派遣两个argumnents。构造本身也有效。它失败了我用uint32_t数据和uint32_t长度调用函数。使用uint8_t的函数调用正在运行。
感谢您的帮助。
答案 0 :(得分:0)
您可以使用C.11的_Generic
:
#define uint8Data_(file, data, len) \
_Generic((len), \
uint64_t : dataioWriteBin_uint8Data_uint64Len, \
uint32_t : dataioWriteBin_uint8Data_uint32Len)
#define uint32Data_(file, data, len) \
_Generic((len), \
uint64_t : dataioWriteBin_uint32Data_uint64Len, \
uint32_t : dataioWriteBin_uint32Data_uint32Len)
#define dataioWriteBin(file, data, len) \
_Generic( \
(data), \
uint8_t * : uint8Data_(file, data, len), \
const uint8_t * : uint8Data_(file, data, len), \
uint32_t * : uint32Data_(file, data, len), \
const uint32_t * : uint32Data_(file, data, len) \
)(file, data, len)
accepted answer to the question you cited in your post中描述了使用GCC __builtin_choose_expr
的表达式选择语法。
答案 1 :(得分:0)
这可能不是基于类型的重载的最佳用法(无论是基于__builtin_choose_expr
还是标准化的_Generic
),但这里有一个示例,表明您的代码可以使用uint32_t *data
和uint32_t
len。代码编译:
#include <stdint.h>
#include <stdio.h>
//prototypes
void dataioWriteBin_uint8Data_uint64Len(FILE *f, uint8_t const *data, uint64_t len);
void dataioWriteBin_uint8Data_uint32Len(FILE *f, uint8_t const *data, uint32_t len);
void dataioWriteBin_uint32Data_uint64Len(FILE *f, uint32_t const *data, uint64_t len);
void dataioWriteBin_uint32Data_uint32Len(FILE *f, uint32_t const *data, uint32_t len);
//
#define dataioWriteBin(file, data, len) \
(__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint8_t ) && __builtin_types_compatible_p(typeof(len), uint64_t ), dataioWriteBin_uint8Data_uint64Len, \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint8_t ) && __builtin_types_compatible_p(typeof(len), uint32_t ), dataioWriteBin_uint8Data_uint32Len, \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint32_t ) && __builtin_types_compatible_p(typeof(len), uint64_t ), dataioWriteBin_uint32Data_uint64Len, \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(*data), uint32_t ) && __builtin_types_compatible_p(typeof(len), uint32_t ), dataioWriteBin_uint32Data_uint32Len, \
(void)0))))(file, data, len))
//
void use_it(void)
{
uint32_t data[4]={};
dataioWriteBin(stdout,data,(uint32_t)sizeof(data));
}