如果我的代码如下所示:
void foofunc(const int fooarg)
{
// something here
}
fooarg
是按价值还是按参考传递的?由于fooarg
是const
,它不会被修改,所以如果通过引用传递它就没问题。
如果我的代码如下所示:
void foofunc(int fooarg)
{
// something here, but fooarg is not gonna get modified
}
fooarg
是通过值还是通过引用传递,也是const或不是?情况与上述相同。它不会被修改。
答案 0 :(得分:8)
宣言说它是按价值传递的。所以它是按值传递的。
答案 1 :(得分:4)
它是按值传递的,因为声明表明它是按值传递的。
它不会被修改,所以如果通过引用传递它就没问题。
不是这样,但除此之外。另一个线程可能会修改传递的变量。在这种情况下,通过引用传递将改变语义。
答案 2 :(得分:3)
在函数签名中忽略顶级const
,因此这些声明完全等效:
void foofunc(const int fooarg);
void foofunc(int fooarg);
由此得出两者的语义都是传值。当然,允许编译器遵循“as-if”规则对其进行优化,因此在给定足够信息的情况下,允许使用引用语义。
答案 3 :(得分:2)
在语言级别,如果按值传递,那么当然,它是按值传递的,而不是通过引用传递的。但是传递是如何在物理上实现的,是一个实现细节,它不依赖于const
的参数,因为它可能在第一眼看上去。
在许多编译器实现中,通过值传递的“大”参数(从语言的角度来看)实际上是通过引用传递,然后通过序列代码进行复制。功能本身。函数体使用副本,该副本创建了按值接收的参数的最终效果。
在其他实现中,参数字面上是“按值”传递的,即副本是由调用者预先准备的。
前一种方法的优点是知道函数的内部工作原理,编译器可能会在知道不需要副本时决定不复制(例如,当函数体不会尝试修改参数时)值)。请注意,无论相应的参数是否声明为const
,智能编译器都可以执行此分析并消除不必要的复制。
这是最佳代码生成的问题,不受语言规范的约束。但是,这些问题可能由平台相关的ABI规范指定。