天嵌 ARM开发社区

 找回密码
 注册
查看: 2358|回复: 0

【分享】用函数内联取代宏

[复制链接]
happem 发表于 2012-9-1 10:57:52 | 显示全部楼层 |阅读模式
C++语言支持函数,其目的是为了提高函数的执行效率。

在C程序中,可以用宏代码提高执行效率,宏代码本身不是函数,但使用起来像函数,编译预处理器用拷贝宏代码的方式取代函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return等过程,从而提高了速度。使用宏代码最大的缺点是容易出错,预处理在拷贝宏代码时常常产生生意想不到的边际效应。例如:

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

语句:

  Result=MAX(i,j)+2;

  将被预处理器扩展为:

   Result=(i)>(j)?(i):(j)+2;

由于运算符”+”比运算符”?:”的优先级高,所以上述语句并不等价于期望的:

  Result=(i)>(j)?(i):(j)+2;

如果把宏代码改写为:

#defineMAX(a,b)(a)>(b)?(a):(b)

则可以解决由优先级引起的错误,但是即使使用修改后的宏代码也不是万无一失的。

例如语句:

  Result=MAX(i++,j);

  将被预处理器解释为:

  Result=(i++)?(j)?(i++)(j); //在不同一个表达式中i被两次求值

宏的另一个缺点就是不可调试,但是内联函数是可以调试的。内联函数不是也像宏一样进行代码展开吗?其实内联函数的可调试不是说它展开后还能调试,而是在程序的调试版本里它根本就没有真正内联,编译器像普通函数那样为它生成含有调试信息可执行代码。在程序的发行版本里,编译器才会实施真正的内联。有的编译器可以设置函数内联开关。例如Visual C++。

对于C++而言,使用宏代码还是另一种缺点:无法操作累的私有数据成员。

对任何内联函数,编译器在符号表里放入函数的声明,包括名字。参数类型,返回值类型。如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。在调用一个内联函数时,编译器首先检查调用是否正确,如果正确,内联函数的代码就会直接替换函数调用语句,于是省去了函数调用的开销,这个过程与预处理器有显著的不同,因为预处理器不能进行类型安全检查和自动类型转换,假如内联函数是成员函数,对象的地址会被放在合适的地方,这也是预处理器办不到的。
来自:http://www.lirenedu.org/index.php?ack=xinwen&id=1159
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-4-19 05:02 , Processed in 1.046882 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表