细细品味宏与内联(inline)

freeskyo 2010-08-25 02:37:59
1/ 宏只是预编译时一一展开,没有类型检查,可能产生二义性;同时宏写的函数不容易直观看懂。

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


2/ 并不总是被内联,inline 对于编译器不是强制性的,缟译器根椐该内联函数的代码行数决定是否参于内联,从编译后生成的目标代码就能看出到底编译器是否真的内联了,调用1次和调用2次目标代码空间是不一样的。

template<typename T>
inline void Count( const T& a, const T& b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");

int c = a + b;
}


3/ 那么我们就强置内联好了,编译时会出现什么问题呢?

template<typename T>
inline __attribute__((always_inline)) void Count( const T& a,const T& b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");

int c = a + b;
}


Test.h:25: sorry, unimplemented: inlining failed in call to 'void Count(const T&, const T&) [with T = int]': function body not available
// 说明模板不能参于强制内联,这个有谁能说明原因吗?

4/ 去掉模板声明,采取的强制内联是有效果的,并且随着调用次数的增加目标代码是不断增大,说明强制内联起作用了,那它真正达到宏的作用了吗?

inline __attribute__((always_inline)) void Count( int a,int b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");

int c = a + b;
}



5/ 那我们改一下再和宏比较, 发再调用强制Count版本两次,即然没报变量c被重复定义,不知道为什么? 哪道可以获取到每一次调用Count的函数地址吗(实际GDB时就没有Count函数的概念)? 如果调用宏版本的Count是会报变量c被重复定义,简单替换啦.(这个为什么有大家给出答案!)

inline __attribute__((always_inline)) void Count( int a,int b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");

int c = a + b;
}
#define Count(a,b) \
printf("always_inline?"); \
printf("always_inline?"); \
printf("always_inline?"); \
int c = a + b



...全文
321 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
老邓 2010-08-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 freeskyo 的回复:]

引用 2 楼 loaden 的回复:
说明模板不能参于强制内联,这个有谁能说明原因吗?
========
可能只是GCC的这个强制内联的选项不能用在模板上而已。

即然没报变量c被重复定义,不知道为什么?
=====
这个变量c的作用域仅限于这个函数,调用一次后,这个c就被销毁了。
再调用,再创建,自然没有重复定义一说。


内联函数不存在调用的问题,也就不存在被销毁吧,我……
[/Quote]
从语法上仍然是调用的。
只是编译器给内联了,自然没有了call。
但作用域仍然是有效的。
freeskyo 2010-08-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xgw369 的回复:]
微软的关键字__forceinline可以强制inline模板。
[/Quote]

谢谢,提供了一个信息,有知道Linux,或类Linux下的GCC支持的吗?
奋斗小青年 2010-08-25
  • 打赏
  • 举报
回复
等下来看
xgw369 2010-08-25
  • 打赏
  • 举报
回复
微软的关键字__forceinline可以强制inline模板。
freeskyo 2010-08-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 loaden 的回复:]
说明模板不能参于强制内联,这个有谁能说明原因吗?
========
可能只是GCC的这个强制内联的选项不能用在模板上而已。

即然没报变量c被重复定义,不知道为什么?
=====
这个变量c的作用域仅限于这个函数,调用一次后,这个c就被销毁了。
再调用,再创建,自然没有重复定义一说。
[/Quote]

内联函数不存在调用的问题,也就不存在被销毁吧,我GDB了,两次调用,进行bt时没有看到Count函数栈,只是简单替换。单步执行也是,没看到函数。只是顺序执行下面的两次。
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");

int c = a + b;
老邓 2010-08-25
  • 打赏
  • 举报
回复
说明模板不能参于强制内联,这个有谁能说明原因吗?
========
可能只是GCC的这个强制内联的选项不能用在模板上而已。

即然没报变量c被重复定义,不知道为什么?
=====
这个变量c的作用域仅限于这个函数,调用一次后,这个c就被销毁了。
再调用,再创建,自然没有重复定义一说。
董小尾 2010-08-25
  • 打赏
  • 举报
回复
消灭沙发~~~

报到学习

64,661

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧