2024 年 8 月 1 日:
- C23 后确定的前两次 C 会议结束,开始致力于 C2y。决定此周期不采用“先修复 bug 再发布”的方式,避免像 C11 到 C17 期间那样失去动力和活跃贡献者,此次同时处理 bug 修复和新特性。
通用选择(Generic Selection):
_Generic
是用于通用选择的关键字,C11 引入,通过传入表达式确定其类型并进行匹配,可插入表达式实现基于类型的行为,如:
int f () { return 45; } int main () { const int a = 1; return _Generic(a, int: a + 2, default: f() + 4 ); }
存在两个问题:
- “l 值转换”问题:表达式进入
_Generic
表达式时会进行“l 值转换”,数组转为指针,修饰符被剥离,这有助于确定类型但会导致一些问题,如TYPE_MATCHES_EXPR
宏在判断const
类型时会失败,可通过typeof
创建空指针表达式来解决,但这种方式较复杂。 - 仅接受表达式:输入到类型通用宏的总是表达式,
_Generic
也仅接受表达式,这导致实现测试时需使用指针技巧,后来有人提出可以做得更好。
- “l 值转换”问题:表达式进入
推动改进:实现者抱怨无法直接匹配类型,Aaron Ballman 决定改进
_Generic
,将类型放入通常放表达式的位置,使其能直接匹配且无 l 值转换,如TYPE_MATCHES_EXPR
可写为:#define TYPE_MATCHES_EXPR(DESIRED_TYPE,...) \ _Generic(typeof((__VA_ARGS__)),\ DESIRED_TYPE: 1,\ default: 0\ )
Clang 几个月内实现,GCC 也在其主干中实现,该特性已正式进入 C2y,但其他编译器可能需要一些时间跟进,在某些场景下使用可能会引起混淆,如上述代码在使用类型匹配时不再匹配
int
,且暴露了一些关于表达式导致特定类型的问题,_Generic
仍需一些改进。- 标签:[C]、[C 标准]、[_Generic]、[📜]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。