我似乎无法将参数传递给期望不同参数的函数(或实现第一个类型的子集的其他_Generic宏)。
#define DEBUG_PRINT(x,...) _Generic((x), \
debug_print_options *: DEBUG_PRINT_CUSTOM_TYPE(x, __VA_ARGS__), \
default: DEBUG_PRINT_BASIC_TYPE(x, __VA_ARGS__))
#define DEBUG_PRINT_BASIC_TYPE(x,...) debug_print_printf_specifier((#x), (x), TYPE_TO_PRINTF_SPECIFIER(x), __FILE__, __LINE__, _my_func__, &((struct debug_print_options){__VA_ARGS__}))
#define DEBUG_PRINT_CUSTOM_TYPE(x,...) debug_print_custom_to_debug_string((#x), (x), GET_CREATE_DEBUG_STRING_FUNC(x), __FILE__, __LINE__, _my_func__, &((struct debug_print_options){__VA_ARGS__}))
给出了编译错误:
debug_print.h:123:46: error: ‘_Generic’ selector of type ‘struct debug_print_options *’ is not compatible with any association
这使得它似乎在每个分支都得到了评估。如果我注释掉默认值,它就会编译。
有办法解决这个问题吗?
答案 0 :(得分:3)
您的编译器错误不是来自宏本身,而是来自它们的一些调用。因此,如果您发布了导致错误的调用,那将会有所帮助。话虽如此,我将解决关于_Generic表达式的一般问题。
标准说明如下(6.5.1.1,'语义'):
不评估通用选择的控制表达式。如果是通用选择 具有与类型名称兼容的通用关联 控制表达式,然后通用选择的结果表达式是 在该通用关联中表达。否则,泛型的结果表达式 selection是默认通用关联中的表达式。没有表达 来自任何其他通用选择的通用关联的评估。
因此,在回答您的评论时,请添加您的问题,不,只评估所选分支。
_Generic表达式是表达式,而不是宏。宏不需要具有适当的语法。它甚至不需要在括号内平衡。宏认为需要做的唯一事情是每次使用它时都会扩展为有效的代码。表达方式不同。他们需要匹配语言的语法。
对于_Generic表达式,每个项的语法可以是任何有效的C表达式,它没有逗号运算符,而不是括号(或条件运算符)屏蔽。如果_Generic满足此条件,并且所选语句不会导致问题,那么它将起作用。因此,只要语法有效,它就可以工作。
如果您不知道变量的类型,请使用正确的语法可能有点棘手。如果您遇到问题,可以在' x'上插入显式强制转换。在需要的地方,将其转换为该分支上的类型。这样代码就是有效的,而且强制转换是多余的,并且会被优化掉。
至于您所遇到的特定错误,如果您没有与您的输入相匹配且您没有默认声明的类型,则听起来就像您所得到的错误。再一次,没有看到你的调用,很难说。但是我确保你完全匹配包含限定符的类型。我要问的一个特殊问题是,如果debug_print_options是一个typedef,就好像它只被定义为一个结构标记,那么你需要把结构标记放在一起。在_Generic中正确识别类型。