美文网首页
C语言预处理器之宏扩展 [C陷阱与缺陷]

C语言预处理器之宏扩展 [C陷阱与缺陷]

作者: yiltoncent | 来源:发表于2017-03-08 23:25 被阅读86次

C语言中宏是一个很好的工具,但也容易引起错误。

1. 宏不是函数

#define max(a,b) ((a)>(b)?(a):(b))

请注意宏定义中的括号,它们的作用就是预防引起与优先级有关的问题。没有这些括号,当宏展开的时候就可能引起意外的结果

biggest = x[0];
i = 1;
while(i < n)
    biggest = max(biggest, x[i++]);

如果max是一个真正的函数,上面的代码可以正常工作,但是max如果是一个宏,那么就不能正常工作。展开一下:

biggest = ((biggest)>(x[i++])?(biggest):(x[i++]));

首先变量biggest与x[i++]比较。假设此时i值为1,同时biggest小于x[1],那么关系运算结果为false。注意,因为i++有副作用,在比较后i递增为2,所以三目运算结果是x[2]。这明显不符合我们的预期,同时冒号后面的表达式还要经历一次副作用,整条语句结束后i的值是3。
而解决此类问题的一个办法是,确保max中的参数没有副作用

2. 宏不是语句

__FILE____LINE__是内建于C语言预处理器中的宏。

assert宏

#define assert(e) if (!(e)) assert_error(__FILE__,__LINE__)

assert宏这个定义,即使用在一个再明白不过的情形中,也会有一些难以察觉的错误:

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);

因为C语言规定,else与它上面最相邻的if语句对齐。
所以这样的情况下,还是老实一点填写上括号比较好。

3.宏并不是类型定义

#define T1 struct foo *
typedef struct foo * T2;

从上面两个定义来看,T1和T2从概念上完全相同,都是指向结构foo的指针。但是,当我们试图用它们来声明多个变量时,问题来了:

T1 a, b;
T2 a, b;

第一个声明被扩展为:

struct foo *a, b;

第二个声明则不同,它定义了a和b都是指向结构的指针,因为这里T2的行为完全与一个真实的类型相同。

相关文章

  • C语言预处理器之宏扩展 [C陷阱与缺陷]

    C语言中宏是一个很好的工具,但也容易引起错误。 1. 宏不是函数 请注意宏定义中的括号,它们的作用就是预防引起与优...

  • C语言 宏陷阱与缺陷

    1. 不能忽视宏定义中的空格 #define f (x) ((x)-1) 上面的宏定义中展开后变成 (x) ((x...

  • 书籍推荐

    1.《C primer plus》----《C程序设计语言》-----《C和指针》、《C专家编程》、《C缺陷与陷阱...

  • 我的书单

    已经读完的书 linux/unix设计思想 黑客与画家 数学之美 浪潮之巅 深入理解c指针 c陷阱与缺陷 c程序设...

  • C语言陷阱「词法陷阱 之字符与字符串」

    C语言陷阱【词法陷阱 之字符与字符串】 字符与字符串 C语言中的单引号' ',与双引号" ",含义不同。 用单引号...

  • C语言中的词法陷阱

    该文章为笔记,因此许多内容摘抄自《C陷阱与缺陷》。《C陷阱与缺陷》,全书不厚,但是感觉十分有提醒与启迪作用,值得阅...

  • C语言基础教程之预定义和宏处理

    define看起来很炫酷!C语言基础教程之预处理和宏定义 C语言预处理器 C语言预处理器不是编译器的组成部分,但是...

  • 第三章、程序的

    程序的机器级表示: 程序编码: C语言 ---【预处理器】--->扩展后的C ---【编译器】---> 汇编语言 ...

  • 初识css预编译之Less

    什么是less less是CSS的预处理器,学过C语言的同学应该对预处理器挺熟悉的把,C语言的编译过程就分为:预处...

  • 阅读书单

    《嵌入式Linux应用开发完全手册》 《抛弃c程序设计中的谬误与恶习》 《c陷阱与缺陷》 《征服c指针》 《c专家...

网友评论

      本文标题:C语言预处理器之宏扩展 [C陷阱与缺陷]

      本文链接:https://www.haomeiwen.com/subject/eliigttx.html