c11 _Generic泛型关联的结果表达式的每个分支都必须有效吗? [英] Does each branch of c11 _Generic generic association's result expressions have to be valid?

查看:105
本文介绍了c11 _Generic泛型关联的结果表达式的每个分支都必须有效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法将参数传递给需要不同参数的函数(或传递给实现第一个类型子集的其他_Generic宏).

I can't seem to pass the arguments to functions expecting different arguments (or to other _Generic macros which implement a subset of the types of the first one).

#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

似乎每个分支都对其进行评估.如果我注释掉默认值,它将编译.

which makes it seem like it's getting evaluated at every branch. If I comment out the default it compiles.

有没有办法解决这个问题?

Is there a way to work around this?

推荐答案

您的编译器错误不是来自宏本身,而是来自它们的某些调用.因此,如果您发布导致错误的调用,这将有所帮助.话虽如此,我将解决似乎是您对_Generic表达式的一般性问题.

Your compiler error is not comming from the macros themselves, but from some invocation of them. So, it would help if you posted the invocation that is causing the error. That being said, I will address what seem to be your general questions on _Generic expressions.

该标准规定以下内容(语义"下为6.5.1.1):

The standard says the following (6.5.1.1, under 'semantics'):

不评估通用选择的控制表达式.如果是通用选择 具有与类型名称兼容的通用名称,该名称与 控制表达式,则通用选择的结果表达式为 通用关联中的表达式.否则,泛型的结果表达式 选择是默认通用关联中的表达式.没有表达 从通用选择的任何其他通用关联中求值.

The controlling expression of a generic selection is not evaluated. If a generic selection has a generic association with a type name that is compatible with the type of the controlling expression, then the result expression of the generic selection is the expression in that generic association. Otherwise, the result expression of the generic selection is the expression in the default generic association. None of the expressions from any other generic association of the generic selection is evaluated.

因此,要回答您的评论,请附加您的问题,不,仅对选定的分支进行评估.

So, in answer to your comment add on to your question, no, only the selected branch is evaluated.

_泛型表达式是表达式,而不是宏.宏不需要具有正确的语法.它甚至不需要在括号内保持平衡.宏唯一需要做的就是每次使用宏时都将其扩展为有效代码.表达式是不同的.他们需要匹配语言的语法.

_Generic expressions are expressions, not macros. A macro does not need to have proper syntax. It does not even need to be parenthetically balanced. The only think a macro needs to do is expand into valid code each time it is used. Expressions are different. They need to match the syntax of the language.

对于_Generic表达式,每个项目的语法可以是任何有效的C表达式,这些表达式不具有不带括号的逗号运算符(或条件运算符).如果您的_Generic满足此条件,并且所选语句不会引起问题,则它将起作用.因此,只要语法有效,就可以使用.

In the case of a _Generic expression, the syntax of each item can be any valid C expression that does not have a comma operator that is not parenthetically (or conditional operator) shielded. If your _Generic meets this criteria, and the selected statement does not cause a problem, then it will work. So, as long as the syntax is valid, it will work.

当您不知道变量的类型时使用正确的语法可能会有些棘手.如果您对此有疑问,可以在需要的地方在'x'上插入显式强制转换,并将其强制转换为该分支上的类型.这样,代码是有效的,并且强制类型转换是多余的,并且将被优化.

Having proper syntax when you don't know the type of your variable can be a little tricky. If you are having trouble with that, you can insert explicit casts on 'x' where needed, casting it to the type it would be on that branch. This way the code is valid, and the casts are redundant and will be optimized out.

对于您遇到的特定错误,如果您没有与输入匹配的类型并且没有默认语句,这听起来像是您会遇到的错误.同样,在没有看到您的调用的情况下,很难说.但我会确保您完全匹配包含限定符的类型.我要问的一个特定问题是,debug_print_options是否为typedef,就好像它仅被定义为结构标记一样,则需要在_Generic中放入"struct"以正确识别类型.

As for the particular error you got, it sounds like the error you'd get if you did not have a type that matched your input and you had no default statement. Again, without seeing your invocation, it is hard to say. But I'd make sure you are matching the type exactly including qualifiers. One particular question I'd ask is if debug_print_options is a typedef, as if it is only defined as a structure tag then you need to put 'struct' in your _Generic to correctly identify the type.

这篇关于c11 _Generic泛型关联的结果表达式的每个分支都必须有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆