比如对于函数:
inline f(int a){return sizeof(a);}
调用f(5);/*只考虑实参为常量表达式的情况*/
在编译的时候将被展开为 sizeof(5)进而被编译器算出
结果是4
也就是说f(5)可以认为是一个常量表达式//对不对?我觉得是
可是对于:
int main(){
enum{ A=f(5) };
}
为什么编译报错?//VC6和VS2005下都报错?
说f(5)的地方需要一个常量表达式.
这是怎么回是?编译器的问题吗?
21 个解决方案
#1
楼主在说啥?
int main(){
enum{ A=f(5) };
}
这个跟inline有联系么?A是什么?
int main(){
enum{ A=f(5) };
}
这个跟inline有联系么?A是什么?
#2
inline函数在它被调用的地方被展开,省去了调用的堆栈开销。有可能在某些情况下,一些inline被优化成常量。
你这里enum跟inline没什么关系吧,enum定义类型,中不能调用函数吧。编译器无法给你替换。
你这里enum跟inline没什么关系吧,enum定义类型,中不能调用函数吧。编译器无法给你替换。
#3
一些资料在介绍宏的危害时,可能会提到inline函数有 宏的效率,但两者不是一回事。
inline与否,取决于编译器。
用户的inline声明,只是向编译器提出的建议!
一般来讲,在类的定义体中写的成员函数,默认都会被编译器inline掉,甚至连inline的声明都不需要。
编译器的参数,可以控制inline的尺度:比如VC的/Ob0 /Ob1
#4
enum不能这么用吧...
#5
up Loaden~~
inline 只是对编译器提出要求,编译器会根据具体情况决定是否把函数代码嵌入到调用的地方
枚举中也不应该有函数~~
inline 只是对编译器提出要求,编译器会根据具体情况决定是否把函数代码嵌入到调用的地方
枚举中也不应该有函数~~
#6
书上说的是展开。。。
#7
inline f(int a){return sizeof(a);}
f(5);
我觉得这里就是你所说的"某些情况下,一些inline被优化成常量。"
既然优化为常量了,f(5)就不算调用函数,而算常量表达式
从而enum{ A=f(5) };也就不算调用函数了是不是?
#8
我觉得
inline f(int a){return sizeof(a);}
这样的inline请求应该会被编译器接受,而且我用release模式编译的.
#9
语法和优化是两码事。
函数始终是函数,无论它有没有被内联(况且还是个“建议”内联)。
而函数调用表达式是不包括在常量表达式里面的。
#10
你说的是,如果inline请求没有被编译器接受,那么我的枚举中才算有函数.但是如果inline请求被编译器接受了呢?是不是就不算在enum中调用函数?从而编译可以通过?
#11
说的很到位啊
#12
想楼上各位说的,你这里定义的enum、sizeof、inline没有任何关系。
inline函数不一定返回常量,所以在展开之前enum{A=f(5)}在语法上就无法通过编译,因为f是函数,返回值不确定。
但是这样当然是可以的enum{A=sizeof(int)},因为sizeof总是(被替换)为常量。
inline函数不一定返回常量,所以在展开之前enum{A=f(5)}在语法上就无法通过编译,因为f是函数,返回值不确定。
但是这样当然是可以的enum{A=sizeof(int)},因为sizeof总是(被替换)为常量。
#13
我认为这里的问题不是会不会内联的问题,”内联是一种请求“,大部分人都知道。不管这里的inline会不会被内联,都不能通过编译,这是语法问题!
#14
也就是说,inline首先就是一个函数,函数可以返回任何值,inline也可以返回任何值。inline的展开不是在预处理期(区别于宏),而是在编译器,语法分析之后。enum需要常量,但函数不保证返回常量(当然),所以语法分析就会产生错误。
#15
inline展开确实在编译期,但是应该在编译期的第一步...所以还是在语法分析之前啊
#16
呃……
#17
inline不是在语法分析之前展开的,先语法分析,最后生成汇编的时候才给你展开的。
#18
cattycat这么说有什么权威的根据吗?
#19
常量表达式不包含函数调用表达式,所以这个从语法上就是错的,无论编译器如何分析都不能违背这一点……
#20
我没看到权威的说法,但我根据编译原理课程中学到的,编译器的过程中推断的,你即使不是inline的,在enum中调用函数也不对吧。编译器首先扫描程序,生成各种符号表,在语法分析阶段看到enum里面的函数调用就不对了。有可能在生成符号表的时候就会认为enum中函数调用不对。
当然你可以看 提高c++性能中关于内联的介绍部分。
当然你可以看 提高c++性能中关于内联的介绍部分。
#21
希望楼主接受这种说法,如果你没学过编译原理,那就默默地接受。
这个问题到现在已经很清楚了。
这个问题到现在已经很清楚了。
#1
楼主在说啥?
int main(){
enum{ A=f(5) };
}
这个跟inline有联系么?A是什么?
int main(){
enum{ A=f(5) };
}
这个跟inline有联系么?A是什么?
#2
inline函数在它被调用的地方被展开,省去了调用的堆栈开销。有可能在某些情况下,一些inline被优化成常量。
你这里enum跟inline没什么关系吧,enum定义类型,中不能调用函数吧。编译器无法给你替换。
你这里enum跟inline没什么关系吧,enum定义类型,中不能调用函数吧。编译器无法给你替换。
#3
一些资料在介绍宏的危害时,可能会提到inline函数有 宏的效率,但两者不是一回事。
inline与否,取决于编译器。
用户的inline声明,只是向编译器提出的建议!
一般来讲,在类的定义体中写的成员函数,默认都会被编译器inline掉,甚至连inline的声明都不需要。
编译器的参数,可以控制inline的尺度:比如VC的/Ob0 /Ob1
#4
enum不能这么用吧...
#5
up Loaden~~
inline 只是对编译器提出要求,编译器会根据具体情况决定是否把函数代码嵌入到调用的地方
枚举中也不应该有函数~~
inline 只是对编译器提出要求,编译器会根据具体情况决定是否把函数代码嵌入到调用的地方
枚举中也不应该有函数~~
#6
书上说的是展开。。。
#7
inline f(int a){return sizeof(a);}
f(5);
我觉得这里就是你所说的"某些情况下,一些inline被优化成常量。"
既然优化为常量了,f(5)就不算调用函数,而算常量表达式
从而enum{ A=f(5) };也就不算调用函数了是不是?
#8
我觉得
inline f(int a){return sizeof(a);}
这样的inline请求应该会被编译器接受,而且我用release模式编译的.
#9
语法和优化是两码事。
函数始终是函数,无论它有没有被内联(况且还是个“建议”内联)。
而函数调用表达式是不包括在常量表达式里面的。
#10
你说的是,如果inline请求没有被编译器接受,那么我的枚举中才算有函数.但是如果inline请求被编译器接受了呢?是不是就不算在enum中调用函数?从而编译可以通过?
#11
说的很到位啊
#12
想楼上各位说的,你这里定义的enum、sizeof、inline没有任何关系。
inline函数不一定返回常量,所以在展开之前enum{A=f(5)}在语法上就无法通过编译,因为f是函数,返回值不确定。
但是这样当然是可以的enum{A=sizeof(int)},因为sizeof总是(被替换)为常量。
inline函数不一定返回常量,所以在展开之前enum{A=f(5)}在语法上就无法通过编译,因为f是函数,返回值不确定。
但是这样当然是可以的enum{A=sizeof(int)},因为sizeof总是(被替换)为常量。
#13
我认为这里的问题不是会不会内联的问题,”内联是一种请求“,大部分人都知道。不管这里的inline会不会被内联,都不能通过编译,这是语法问题!
#14
也就是说,inline首先就是一个函数,函数可以返回任何值,inline也可以返回任何值。inline的展开不是在预处理期(区别于宏),而是在编译器,语法分析之后。enum需要常量,但函数不保证返回常量(当然),所以语法分析就会产生错误。
#15
inline展开确实在编译期,但是应该在编译期的第一步...所以还是在语法分析之前啊
#16
呃……
#17
inline不是在语法分析之前展开的,先语法分析,最后生成汇编的时候才给你展开的。
#18
cattycat这么说有什么权威的根据吗?
#19
常量表达式不包含函数调用表达式,所以这个从语法上就是错的,无论编译器如何分析都不能违背这一点……
#20
我没看到权威的说法,但我根据编译原理课程中学到的,编译器的过程中推断的,你即使不是inline的,在enum中调用函数也不对吧。编译器首先扫描程序,生成各种符号表,在语法分析阶段看到enum里面的函数调用就不对了。有可能在生成符号表的时候就会认为enum中函数调用不对。
当然你可以看 提高c++性能中关于内联的介绍部分。
当然你可以看 提高c++性能中关于内联的介绍部分。
#21
希望楼主接受这种说法,如果你没学过编译原理,那就默默地接受。
这个问题到现在已经很清楚了。
这个问题到现在已经很清楚了。