c11 _Generic泛型关联的结果表达式的每个分支都必须有效吗?

时间:2015-03-20 06:55:42

标签: c interface c11

我似乎无法将参数传递给期望不同参数的函数(或实现第一个类型的子集的其他_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

这使得它似乎在每个分支都得到了评估。如果我注释掉默认值,它就会编译。

有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

您的编译器错误不是来自宏本身,而是来自它们的一些调用。因此,如果您发布了导致错误的调用,那将会有所帮助。话虽如此,我将解决关于_Generic表达式的一般问题。

标准说明如下(6.5.1.1,'语义'):

  

不评估通用选择的控制表达式。如果是通用选择   具有与类型名称兼容的通用关联   控制表达式,然后通用选择的结果表达式是   在该通用关联中表达。否则,泛型的结果表达式   selection是默认通用关联中的表达式。没有表达   来自任何其他通用选择的通用关联的评估。

因此,在回答您的评论时,请添加您的问题,不,只评估所选分支。

_Generic表达式是表达式,而不是宏。宏不需要具有适当的语法。它甚至不需要在括号内平衡。宏认为需要做的唯一事情是每次使用它时都会扩展为有效的代码。表达方式不同。他们需要匹配语言的语法。

对于_Generic表达式,每个项的语法可以是任何有效的C表达式,它没有逗号运算符,而不是括号(或条件运算符)屏蔽。如果_Generic满足此条件,并且所选语句不会导致问题,那么它将起作用。因此,只要语法有效,它就可以工作。

如果您不知道变量的类型,请使用正确的语法可能有点棘手。如果您遇到问题,可以在' x'上插入显式强制转换。在需要的地方,将其转换为该分支上的类型。这样代码就是有效的,而且强制转换是多余的,并且会被优化掉。

至于您所遇到的特定错误,如果您没有与您的输入相匹配且您没有默认声明的类型,则听起来就像您所得到的错误。再一次,没有看到你的调用,很难说。但是我确保你完全匹配包含限定符的类型。我要问的一个特殊问题是,如果debug_print_options是一个typedef,就好像它只被定义为一个结构标记,那么你需要把结构标记放在一起。在_Generic中正确识别类型。