【发布时间】:2021-08-05 18:04:33
【问题描述】:
我正在使用几个类似的函数,并希望使其中一个可重载。
基本函数需要3个参数,其连续展开需要4个或更多。
#define register_read_write(action, parameter, reg_value, ...)
_Generic(&(uint32_t[]){__VA_ARGS__},
uint32_t(*)[2]: register_read_write_with_limits,
uint32_t(*)[1]: register_read_write_with_upper_limit)
((action), (parameter), (reg_value), (__VA_ARGS__))
声明
void register_read_write_with_limits(access_t action, parameter_t parameter, uint16_t *reg_value,
uint32_t value_min, uint32_t value_max);
void register_read_write_with_upper_limit(access_t action, parameter_t parameter, uint16_t *reg_value,
uint32_t value_max);
它工作正常,但我无法添加带有 3 个参数的基本函数:
void register_read_write(access_t action, parameter_t parameter, uint16_t *reg_value)
我试试:
#define register_read_write(action, parameter, reg_value, ...)
_Generic(&(uint32_t[]){__VA_ARGS__},
uint32_t(*)[2]: register_read_write_with_limits,
uint32_t(*)[1]: register_read_write_with_upper_limit,
uint32_t(*)[0]: register_read_write)
((action), (parameter), (reg_value), (__VA_ARGS__))
但是:
错误:'uint32_t ()[0]' {aka 'long unsigned int ()[0]'} 类型的 '_Generic' 选择器与任何关联都不兼容 #define register_read_write(action, parameter, reg_value, ...) _Generic(&(uint32_t[]){VA_ARGS},
紧随其后....
我正在开发我的通用函数,但遇到了另一个问题。
#define FIRST_ARG(value, ...) (value)
#define generic_uint8_read_write(action, parameter, ...)
_Generic(&(uint32_t[]){(uintptr_t)__VA_ARGS__},
uint32_t(*)[1]: register_uint8_read_write)(action, parameter, __VA_ARGS__)
#define generic_uint16_read_write(action, parameter, ...) _Generic(&(uint32_t[]){(uintptr_t)__VA_ARGS__},
uint32_t(*)[2]: register_read_write_with_limits,
uint32_t(*)[1]: register_read_write_with_upper_limit,
uint32_t(*)[0]: register_read_write)(action, parameter, __VA_ARGS__)
#define generic_read_write(action, parameter, ...)
_Generic(FIRST_ARG(__VA_ARGS__),
uint8_t*: generic_uint8_read_write(action, parameter, __VA_ARGS__),
uint16_t* : generic_uint16_read_write(action, parameter, __VA_ARGS__))
我不知道为什么,但它没有正确检测指针类型。
我变了
#define generic_read_write(action, parameter, value, ...)
_Generic((value),
uint8_t*: generic_uint8_read_write(action, parameter, value, __VA_ARGS__),
uint16_t* : generic_uint16_read_write(action, parameter, value, __VA_ARGS__))
还是失败了:-(
请给我一些建议。
问候
附言我正在寻找关于“_Generic”功能如何工作的好教程。
【问题讨论】:
-
顺便说一句,这是对参数计数执行通用选择的一个非常聪明的技巧。
-
有理由使用
Generic吗?你似乎根本不关心参数的类型,你只是将它们转换为uint32_t[]。只需在参数数量上重载宏即可。 -
but it doesn't detect pointer type correctly宏被预处理器扩展,_Generic被编译器解析。所以modbus_generic_uint8_read_write(stuf)总是扩展,因为预处理器扩展了它。我仍然没有完全理解使用&(uint32_t[])的意义。 -
@KamilCuk 我找到了一个例子并采用了它。我还不太明白_Generec的语法
标签: c variadic-macros