C/C++,在使用全局参数或传递参数之间进行选择
C/C++, choose between using global or passing argurment
假设函数f1
调用f2
,f2
调用f3
,最后调用f5
,它们各自向被调用者传递一个参数"arg",如下所示:
f1(arg, ...) -> f2(arg, ...) -> f3(arg, ...) -> f4(arg, ...) -> f5(arg, ...)
另一种方式,使用全局"arg",无需传递参数"arg),如:
int arg = 5;
f1(...) -> f2(...) -> f3(...) -> f4(...) -> f5(...)
哪一个更好?或者还有什么方法更有用?
添加参数"arg"可以使函数独立且可重新输入,这可能很好,例如在多线程应用程序中。当队列中任意两个函数之间的全局变量值发生变化时,为多个函数使用一个全局变量可能会导致错误,并且会得到意外的无效结果。
在一些体系结构上,包括x86-64(pdf中的完整规范),前几个参数在寄存器中传递。因此,如果您总是在参数列表的同一位置使用arg
,并且在所有函数中都一致使用它,那么编译器可能会利用这一点,将其保留在适当的寄存器中。
几乎所有ABI都使用寄存器作为函数的返回值;在一些ABI(例如ARM)中,这与用于第一个参数的寄存器相同。但不是在x86-64上:eax
用于返回值,rdi
或rcx
(取决于平台)用于第一个参数。无论如何,处理寄存器远没有处理堆栈那么昂贵,而且处理堆栈也没有那么昂贵。
所以,就我个人而言,我不会担心开销。全球化会给你带来麻烦。
当传递几个参数时,我会提请注意这种情况。情况变得更糟:
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, ...)
}
我建议您避免使用任何全局变量。收益(如果有的话)不值得亏本。
相关文章:
- 如何使用默认参数等选择模板专业化
- 对可变参数使用声明.如何选择正确的功能
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 使模板函数按函数参数选择类型
- 根据模板参数选择宏定义
- 使用 std::条件根据模板参数选择成员类型
- 根据 C++11 中的模板参数选择数组大小
- 为什么 lambda 自动和参数选择常量重载?
- 如何使用模板参数选择方法调用
- 如何根据参数选择变量
- 根据函数参数选择派生类
- 如何根据模板参数选择替代成员函数实现
- 使用mpl::if_和integer模板参数选择类型
- 根据模板参数选择合适的复制构造函数
- 参数选择的问题
- 通过模板参数选择子类与实例化成员变量的区别
- 根据模板整数参数选择一个整数类型
- 根据模板参数选择枚举类型
- 根据模板参数选择函数名称
- 根据模板参数选择联合成员