关于inline函数的问题

yyg990441 2010-05-01 09:23:39
我对于inline函数的理解是:它基本上是用来取代C中带参数的宏.
比如对于函数:
inline f(int a){return sizeof(a);}

调用f(5);/*只考虑实参为常量表达式的情况*/
在编译的时候将被展开为 sizeof(5)进而被编译器算出
结果是4

也就是说f(5)可以认为是一个常量表达式//对不对?我觉得是

可是对于:

int main(){
enum{ A=f(5) };
}

为什么编译报错?//VC6和VS2005下都报错?
说f(5)的地方需要一个常量表达式.

这是怎么回是?编译器的问题吗?
...全文
177 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
dutor 2010-05-03
  • 打赏
  • 举报
回复
希望楼主接受这种说法,如果你没学过编译原理,那就默默地接受。
这个问题到现在已经很清楚了。
[Quote=引用 20 楼 cattycat 的回复:]

我没看到权威的说法,但我根据编译原理课程中学到的,编译器的过程中推断的,你即使不是inline的,在enum中调用函数也不对吧。编译器首先扫描程序,生成各种符号表,在语法分析阶段看到enum里面的函数调用就不对了。有可能在生成符号表的时候就会认为enum中函数调用不对。
当然你可以看 提高c++性能中关于内联的介绍部分。
[/Quote]
cattycat 2010-05-01
  • 打赏
  • 举报
回复
我没看到权威的说法,但我根据编译原理课程中学到的,编译器的过程中推断的,你即使不是inline的,在enum中调用函数也不对吧。编译器首先扫描程序,生成各种符号表,在语法分析阶段看到enum里面的函数调用就不对了。有可能在生成符号表的时候就会认为enum中函数调用不对。
当然你可以看 提高c++性能中关于内联的介绍部分。
2010-05-01
  • 打赏
  • 举报
回复
常量表达式不包含函数调用表达式,所以这个从语法上就是错的,无论编译器如何分析都不能违背这一点……
yyg990441 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 cattycat 的回复:]
inline不是在语法分析之前展开的,先语法分析,最后生成汇编的时候才给你展开的。
[/Quote]
cattycat这么说有什么权威的根据吗?
cattycat 2010-05-01
  • 打赏
  • 举报
回复
inline不是在语法分析之前展开的,先语法分析,最后生成汇编的时候才给你展开的。
dutor 2010-05-01
  • 打赏
  • 举报
回复
呃……
yyg990441 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 ivanff 的回复:]
也就是说,inline首先就是一个函数,函数可以返回任何值,inline也可以返回任何值。inline的展开不是在预处理期(区别于宏),而是在编译器,语法分析之后。enum需要常量,但函数不保证返回常量(当然),所以语法分析就会产生错误。
[/Quote]
inline展开确实在编译期,但是应该在编译期的第一步...所以还是在语法分析之前啊
dutor 2010-05-01
  • 打赏
  • 举报
回复
也就是说,inline首先就是一个函数,函数可以返回任何值,inline也可以返回任何值。inline的展开不是在预处理期(区别于宏),而是在编译器,语法分析之后。enum需要常量,但函数不保证返回常量(当然),所以语法分析就会产生错误。
dutor 2010-05-01
  • 打赏
  • 举报
回复

我认为这里的问题不是会不会内联的问题,”内联是一种请求“,大部分人都知道。不管这里的inline会不会被内联,都不能通过编译,这是语法问题!
[Quote=引用 11 楼 zhoutanliang 的回复:]

引用 3 楼 loaden 的回复:

用户的inline声明,只是向编译器提出的建议!



说的很到位啊
[/Quote]
dutor 2010-05-01
  • 打赏
  • 举报
回复
想楼上各位说的,你这里定义的enum、sizeof、inline没有任何关系。
inline函数不一定返回常量,所以在展开之前enum{A=f(5)}在语法上就无法通过编译,因为f是函数,返回值不确定。
但是这样当然是可以的enum{A=sizeof(int)},因为sizeof总是(被替换)为常量。
AlanBruce 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 loaden 的回复:]

用户的inline声明,只是向编译器提出的建议!

[/Quote]

说的很到位啊
yyg990441 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 thefirstz 的回复:]
up Loaden~~
inline 只是对编译器提出要求,编译器会根据具体情况决定是否把函数代码嵌入到调用的地方
枚举中也不应该有函数~~
[/Quote]
你说的是,如果inline请求没有被编译器接受,那么我的枚举中才算有函数.但是如果inline请求被编译器接受了呢?是不是就不算在enum中调用函数?从而编译可以通过?
2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yyg990441 的回复:]
我觉得
inline f(int a){return sizeof(a);}
这样的inline请求应该会被编译器接受,而且我用release模式编译的.
[/Quote]
语法和优化是两码事。

函数始终是函数,无论它有没有被内联(况且还是个“建议”内联)。
而函数调用表达式是不包括在常量表达式里面的。
yyg990441 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 loaden 的回复:]
与常量没有任何关系。
一些资料在介绍宏的危害时,可能会提到inline函数有宏的效率,但两者不是一回事。
inline与否,取决于编译器。
用户的inline声明,只是向编译器提出的建议!

一般来讲,在类的定义体中写的成员函数,默认都会被编译器inline掉,甚至连inline的声明都不需要。
编译器的参数,可以控制inline的尺度:比如VC的/Ob0 /Ob1
[/Quote]
我觉得
inline f(int a){return sizeof(a);}
这样的inline请求应该会被编译器接受,而且我用release模式编译的.
yyg990441 2010-05-01
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cattycat 的回复:]
有可能在某些情况下,一些inline被优化成常量。
你这里enum跟inline没什么关系吧,enum定义类型,中不能调用函数吧。编译器无法给你替换。
[/Quote]
inline f(int a){return sizeof(a);}
f(5);
我觉得这里就是你所说的"某些情况下,一些inline被优化成常量。"

既然优化为常量了,f(5)就不算调用函数,而算常量表达式
从而enum{ A=f(5) };也就不算调用函数了是不是?
acdbxzyw 2010-05-01
  • 打赏
  • 举报
回复
书上说的是展开。。。
昵称很不好取 2010-05-01
  • 打赏
  • 举报
回复
up Loaden~~
inline 只是对编译器提出要求,编译器会根据具体情况决定是否把函数代码嵌入到调用的地方
枚举中也不应该有函数~~
YT158828 2010-05-01
  • 打赏
  • 举报
回复
enum不能这么用吧...

老邓 2010-05-01
  • 打赏
  • 举报
回复
与常量没有任何关系。
一些资料在介绍宏的危害时,可能会提到inline函数有宏的效率,但两者不是一回事。
inline与否,取决于编译器。
用户的inline声明,只是向编译器提出的建议!

一般来讲,在类的定义体中写的成员函数,默认都会被编译器inline掉,甚至连inline的声明都不需要。
编译器的参数,可以控制inline的尺度:比如VC的/Ob0 /Ob1
cattycat 2010-05-01
  • 打赏
  • 举报
回复
inline函数在它被调用的地方被展开,省去了调用的堆栈开销。有可能在某些情况下,一些inline被优化成常量。

你这里enum跟inline没什么关系吧,enum定义类型,中不能调用函数吧。编译器无法给你替换。
加载更多回复(1)

64,687

社区成员

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

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