• C陷阱与缺陷 第6章 预处理器 6.3 宏并不是语句


    assert宏,它的参数是一个表达式,如果该表达式为0,就使程序终止执行,并给出一条适当的出错信息。把assert作为宏来处理,这样就使得我们可以在出错信息中包含文件名和断言失败处的行号。也就是说, 
    assert(x > y);
    在x大于y时什么也不做,在其他情况下则会终止程序。
    第一次尝试: 
    #define assert(e) if (!e) assert_error(__FILE__, __LINE__)
    因为考虑到宏assert的使用人员会加上一个分号,所以在宏定义中并没有包括分号。
    __FILE__和__LINE__是内建于C语言处理器中的宏,它们会扩展为所在文件的文件名和所处代码行的行号。 

    if (x > 0 && y > 0) 
        assert(x > y);
    else 
        assert(y > x);

    上面例子的展开形式: 
    if (x > 0 && y > 0) 
        if (!(x > y)) assert_error("foo.c", 37);
    else 
        if (!(y > x)) assert_error("foo.c", 39);
    将上面的代码做适当的缩排处理,我们就能够看清它实际的流程结构与我们期望的结构有怎样的区别:
    if (x > 0 && y > 0) 
        if (!(x > y))
            assert_error("foo.c", 37);
        else 
            if (!(y > x))
                assert_error("foo.c", 39);
    在宏assert的定义中用大括号把宏整个给括起来,就能避免这样的问题产生: 
    #define assert(e) \
    {
        if (!e) assert_error(__FILE__, __LINE__); 
    }
    这个又带来了新的问题: 
    if (x > 0 && y > 0) 
    {
            if (!(x > y)) assert_error(__FILE__, __LINE__);
    };
    else 
    {
        if (!(x > y)) assert_error(__FILE__, __LINE__);
    };
    在else之前的分号是一个语法错误。要解决这个问题,一个办法是对assert的调用在后面不再跟
    一个分号,但这样的用法显得有些“怪异”: 
    y = distance(p, q);
    assert(y > 0)
    x = sqrt(y);
    这个定义看起来像一个表达式,不是类似于一个语句 
    #define assert(e) \
    ((void)((e) || _assert_error(__FILE__, __LINE__)))
    这个定义实际上利用了||运算符对两侧的操作数依次顺序求值的性质。如果e为true(真),表达式 
    (void)((e) || _assert_error(__FILE__, __LINE__))
    的值没有求出其右侧表达式 
    _assert_error(__FILE__, __LINE__)
    的值的情况下就可以确定最终的结果为真。如果e为false(假),右侧表达式 
    _assert_error(__FILE__, __LINE__)
    的值必须求出,此时_assert_error将被调用,并打印出一条恰当的“断言失败”的出错消息。 

  • 相关阅读:
    chapter 11 in C primer plus
    深度学习自编码器 - 引言篇
    PyTorch ConvTranspose2d 的定义与计算过程
    vue3前端开发-小兔鲜项目-添加购物车操作第一步
    消防设备电源监控系统在城市建筑中的应用
    mongoose httpserver webcommand
    Zookeeper的api使用
    二十三种设计模式全面解析-深入解析桥接模式:解锁软件设计的灵活性
    【Unity ShaderGraph】| 制作一个 高级流体水球效果
    【39. 最长公共子序列】
  • 原文地址:https://blog.csdn.net/weixin_40186813/article/details/126045345