C11_Generic将true和false推断为整数

在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

  1. 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.

最后一条规则说您可以重新定义宏:

  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

  1. 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

  1. The ability to undefine and perhaps then redefine the macros bool,and false is
    an obsolescent feature.

所以我建议你创建自己的my_true和my_false宏,这些宏被转换为_Bool.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...