我继续阅读(例如在Closure Compiler和其他编译器中),内联函数不是总是安全。你能否提供一个不应该进行内联功能的例子?
答案 0 :(得分:2)
在许多语言中,内联函数将没有可观察到的语义效果,尽管它可能会影响程序的编译大小和执行时间。但是,在调用堆栈和/或局部变量绑定可见的语言中,情况并非如此。
作为一个简单的例子,在Javscript中,局部变量arguments
总是引用一个包含当前函数调用参数的类数组对象。显然,如果它所发生的函数被内联,它的语义就会改变。内联器必须拒绝内联其主体引用arguments
的函数,或者必须以保留语义的方式修改代码,可能通过创建具有不同名称的另一个局部变量并替换引用。
另一个例子是(非推荐)使用eval
。传递给eval
的字符串中的名称查找是在调用eval
的函数范围内完成的。例如:
inner = function(s) { var x = 4; return eval(s); }
outer = function(s) { var x = 3; return inner(s); }
outer("x+1")
此处outer
返回的值为5
。如果inner
被内联,这需要重命名其局部变量x
以避免名称冲突,则返回的值将为4
。 (如果内联inner
和outer
,则该值可能会再次出现。)
一般来说,内联调用eval
的函数非常困难,因为没有简单的方法可以知道eval
的参数内容。