2013-11-21 18 views
1

假设功能f1调用f2f2电话f3,最后调用f5,他们每个人传递一个参数“ARG”到被叫方,如下所示:C/C++,使用全局或通过argurment之间选择

f1(arg, ...) -> f2(arg, ...) -> f3(arg, ...) -> f4(arg, ...) -> f5(arg, ...) 

的另一种方法,使用全局 “ARG”,没有必要通过论证 “ARG”,如:

int arg = 5; 
f1(...) -> f2(...) -> f3(...) -> f4(...) -> f5(...) 

哪一个更好?或者有什么方法更有用?

+8

在网上搜索“全局变量是邪恶的”。 –

+1

如果函数2-5仅在被前一个函数调用时使用,并且所有函数都不在'f1'之外使用,那么只需要第一个函数接受参数并在'f1'内创建其他4个函数作为匿名函数,这将能够看到范围为'f1()'的变量。但是,如果'f2'到'f5'被用在从'f1'的这个链中调用的上下文之外,那么他们似乎必须接受一个参数,对吧......? – nhgrif

回答

2

添加参数'arg'可能会使您的函数独立并且可以重新进入,例如在多线程应用程序中。 如果在队列中两个函数中的任何一个之间改变全局变量值,并且您将得到意外的和无效的结果,那么对很多函数使用一个全局变量可能会导致错误。

+0

你说得对。只是觉得太多的重复看起来不太好。 –

0

在某些体系结构上,包括x86-64full spec in pdf),前几个参数会传递到寄存器中。因此,如果您始终在参数列表中的相同位置使用arg,并且您在所有函数中始终使用arg,那么编译器可能会利用它将它保留在适当的寄存器中。

几乎所有的ABI都使用一个寄存器作为函数的返回值;在一些ABI中(例如ARM),这与第一个参数使用的是相同的寄存器。但不在x86-64上:eax用于返回值,rdircx(取决于平台)用于第一个参数。无论如何,杂耍寄存器并不像操纵堆栈那么昂贵,操纵堆栈也不是那么昂贵。

所以,我个人不会担心这个开销。而全局变量会让你陷入困境。

0

我会提请注意几个参数传递的情况。情况变得更糟糕:

f1(arg1, arg2, ...) -> f2(arg1, arg2, ...) -> f3(arg1, arg2, ...) -> f4(arg1, arg2, ...)

在这种情况下,它将使意义定义一个结构,并通过其参考:

struct MyParams 
{ 
    int arg1, arg2; 
}; 

void f() 
{ 
    MyParams prms = { ... }; 
    f1(prms, ...) -> f2(prms, ...) -> f3(prms, ...) -> f4(prms, ...) 
} 

我会recommennd您避免使用任何全局变量。收益(如果有的话)不值得下跌。