在C11中,有_Generic宏可以允许很酷的泛型函数.但是,使用true和false会导致在正常情况下不正确的推论:
- #include <stdio.h>
- #include <stdbool.h>
- #define TypeName(x) \
- _Generic((x),\
- bool: "bool",\
- int: "int",\
- default: "unknown")
- #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && (__bool_true_false_are_defined)
- # undef true
- # define true ((bool)(1))
- # undef false
- # define false ((bool)(0))
- #endif
- int main(void)
- {
- printf("1: %s\n",TypeName(1));
- printf("true: %s\n",TypeName(true));
- printf("false: %s\n",TypeName(false));
- }
这打印:
- 1: int
- true: bool
- false: bool
但是没有重新定义真假的中间位:
- 1: int
- true: int
- false: int
这意味着您无法执行_Generic功能,例如:
- struct Variant * const int32 = variant_create(1);
- struct Variant * const boolean = variant_create(true);
所以我的问题是:
>重新定义片段是安全的吗?
>这是C11标准中的疏忽还是GCC和Clang中的错误?
解决方法
这两种类型都是宏:
7.18 Boolean type and values
- The remaining three macros are suitable for use in #if preprocessing directives.
They are:
true which expands to the integer constant 1,
false which expands to the integer constant 0,
and
__bool_true_false_are_defined which expands to the integer constant 1.
最后一条规则说您可以重新定义宏:
Notwithstanding the provisions of 7.1.3,a program may undefine and perhaps then
redefine the macros bool,true,and false. 259)259) See ‘‘future library directions’’ (7.31.9)
尽管引用了规则:
7.1.3 Reserved identifiers
- If the program removes (with #undef) any macro definition of an identifier in the first
group listed above,the behavior is undefined.
规则7.31.9说重新定义可能不是一个好主意:
7.31.9 Boolean type and values
- The ability to undefine and perhaps then redefine the macros bool,and false is
an obsolescent feature.
所以我建议你创建自己的my_true和my_false宏,这些宏被转换为_Bool.
@H_403_21@ @H_403_21@