'pass by reference' 如何在不实际将地址传递给函数的情况下实现?
How is 'pass by reference' implemented without actually passing an address to a function?
我很清楚在 C 和 C++ 中一切都是按值传递的(即使该值是引用 type)。我认为(但我不是那里的专家)Java.
也是如此
所以,这就是为什么我将与语言无关的标签包括在内,我可以用什么语言将 anything 传递给函数而不传递 some值?
如果存在,该机制是什么样的?我苦思冥想,没有想出任何不涉及值传递的机制。
即使编译器以我没有 pointer/reference 作为内存中真正变量的方式进行优化,它仍然必须计算一个地址作为堆栈(帧)指针的偏移量 -并通过它。
有哪位大侠能赐教吗?
按值传递的意思是传递对象自身
在指针传递中,我们将指针的值传递给对象。
在引用传递中,我们以相同的方式传递一个引用(基本上是一个我们知道指向对象的指针) .
所以是的,我们总是传递一个值,但问题是这个值是多少?并不总是对象本身。但是当我们说通过**传递变量时,我们给出的是与我们要传递的对象相关的信息,而不是实际传递的值。
从C角度看:
没有参考作为语言级别的概念。通过用指针指向对象来引用对象。
指针的值是指向对象的地址。指针像任何其他参数一样按值传递。一个指向的对象在概念上是通过引用传递的。
至少从 C++ 的角度来看:
How is 'pass by reference' implemented [...] ?
通常,通过复制对象的地址。
... without actually passing an address to a function?
如果函数调用是内联扩展的,则无需在任何地方复制地址。这同样适用于指针,因为副本可能由于 as-if 规则而被省略。
in what language can I pass anything to a function without passing some value?
这样的语言必须具有与 C 明显不同的函数概念。必须没有堆栈帧推送。
函数式 C 预处理器宏,顾名思义,类似于函数,但它们的参数不会在运行时传递,因为预处理发生在编译之前。
另一方面,您可以拥有全局变量。如果您更改程序的全局状态,并调用一个不带参数的函数,那么您在概念上 "passed the new global state to the function" 没有传递任何值。
'pass by reference' 是如何在不实际将地址传递给函数的情况下实现的?
在 C 语言的上下文中,简短的答案是:
- 在 C 中,它不是。
- 在 C++ 中,后跟符号 (&) 的类型是 reference type。
例如,int& 是对 int 的引用。传递参数时
对于采用引用类型的函数,对象是真正传递的
引用。 (在下面的 学术 link 中有更多相关信息。)
但事实上,大部分的混淆是语义上的。一些混乱可以通过以下方式帮助解决:
- 1) 停止使用 模拟 一词来描述 传递地址 。
- 2) 停止使用 reference 来描述 address
或
- 3) 认识到在 C/C++ 语言的上下文中,在
短语 pass-by-reference,单词
reference
定义为:value of
地址.
除此之外还有很多illusions and concepts created to convey impossible ideas的例子。非模拟的概念 pass-by-reference 可以说是其中之一,无论有多少学术论文或实践讨论。
This one(学术论文类别)是另一个区分 emulated 和 的类别actual 在使用 C 和 C++ 的讨论中按引用传递,但谁的结论与现实密切相关。以下为节选:
...Somehow, it is only a matter of how the concept of “passing by reference” is actually realized by a programming language: C implements this by using pointers and passing them by value to functions whereas C++ provides two implementations. From a side, it reuses the same mechanism derived from C (i.e., pointers + pass by value). On the other hand, C++ also provides a native “pass by reference” solution which makes use of the idea of reference types. Thus, even in C++ if you are passing a pointer à la C, you are not truly passing by reference, you are passing a pointer by value (that is, of course, unless you are passing a reference to a pointer! e.g., int*&).
Because of this potential ambiguity in the term “pass by reference”, perhaps it’s best to only use it in the context of C++ when you are using a reference type.
但是正如您和其他人已经指出的那样,在通过参数传递任何内容的概念中,无论是 value 还是 reference,根据定义,某物 必须具有 值。
在机器代码级别,"pass X by reference" 本质上是 "pass the address of X by value"。
指针是值。价值观是价值观。值具有唯一标识,需要存储。
引用不是值。参考没有身份。如果我们有:
int x=0;
int& y=x;
int& z=x;
y
和z
都是对x
的引用,没有独立的身份。
比较:
int x=0;
int* py=&x;
int* pz=&x;
py
和pz
都是指向x
的指针,具有独立的标识。你可以修改 py
而不是 pz
,你可以获得它们的大小,你可以 memset 它们。
在某些情况下,在机器代码级别,引用的实现方式与指针相同,只是某些操作永远不会对它们执行(例如重新瞄准它们)。
但是C++并不是按照机器码来定义的。它是根据抽象机器的行为定义的。编译器将你的代码编译为这个抽象机器上的操作,它没有固定的调用约定(按照标准),没有引用布局,没有堆栈,没有堆等。然后它会对此进行任意转换,不会改变 as-如果行为(一个常见的行为是单一赋值),重新排列事物,然后在某个时候发出 assembly/machine 代码,在您 运行 使用的实际硬件上生成类似的行为。
现在编译 C++ 的近乎通用的方法是编译 unit/linker 模型,其中函数作为符号导出,并为其他编译单元提供固定的 ABI 调用约定以使用它们。然后在 link 阶段将编译单元连接在一起。
在这些 ABI 中,引用作为指针传递。
我很清楚在 C 和 C++ 中一切都是按值传递的(即使该值是引用 type)。我认为(但我不是那里的专家)Java.
也是如此所以,这就是为什么我将与语言无关的标签包括在内,我可以用什么语言将 anything 传递给函数而不传递 some值?
如果存在,该机制是什么样的?我苦思冥想,没有想出任何不涉及值传递的机制。
即使编译器以我没有 pointer/reference 作为内存中真正变量的方式进行优化,它仍然必须计算一个地址作为堆栈(帧)指针的偏移量 -并通过它。
有哪位大侠能赐教吗?
按值传递的意思是传递对象自身
在指针传递中,我们将指针的值传递给对象。
在引用传递中,我们以相同的方式传递一个引用(基本上是一个我们知道指向对象的指针) .
所以是的,我们总是传递一个值,但问题是这个值是多少?并不总是对象本身。但是当我们说通过**传递变量时,我们给出的是与我们要传递的对象相关的信息,而不是实际传递的值。
从C角度看:
没有参考作为语言级别的概念。通过用指针指向对象来引用对象。
指针的值是指向对象的地址。指针像任何其他参数一样按值传递。一个指向的对象在概念上是通过引用传递的。
至少从 C++ 的角度来看:
How is 'pass by reference' implemented [...] ?
通常,通过复制对象的地址。
... without actually passing an address to a function?
如果函数调用是内联扩展的,则无需在任何地方复制地址。这同样适用于指针,因为副本可能由于 as-if 规则而被省略。
in what language can I pass anything to a function without passing some value?
这样的语言必须具有与 C 明显不同的函数概念。必须没有堆栈帧推送。
函数式 C 预处理器宏,顾名思义,类似于函数,但它们的参数不会在运行时传递,因为预处理发生在编译之前。
另一方面,您可以拥有全局变量。如果您更改程序的全局状态,并调用一个不带参数的函数,那么您在概念上 "passed the new global state to the function" 没有传递任何值。
'pass by reference' 是如何在不实际将地址传递给函数的情况下实现的?
在 C 语言的上下文中,简短的答案是:
- 在 C 中,它不是。
- 在 C++ 中,后跟符号 (&) 的类型是 reference type。 例如,int& 是对 int 的引用。传递参数时 对于采用引用类型的函数,对象是真正传递的 引用。 (在下面的 学术 link 中有更多相关信息。)
但事实上,大部分的混淆是语义上的。一些混乱可以通过以下方式帮助解决:
- 1) 停止使用 模拟 一词来描述 传递地址 。
- 2) 停止使用 reference 来描述 address
或
- 3) 认识到在 C/C++ 语言的上下文中,在
短语 pass-by-reference,单词
reference
定义为:value of 地址.
除此之外还有很多illusions and concepts created to convey impossible ideas的例子。非模拟的概念 pass-by-reference 可以说是其中之一,无论有多少学术论文或实践讨论。
This one(学术论文类别)是另一个区分 emulated 和 的类别actual 在使用 C 和 C++ 的讨论中按引用传递,但谁的结论与现实密切相关。以下为节选:
...Somehow, it is only a matter of how the concept of “passing by reference” is actually realized by a programming language: C implements this by using pointers and passing them by value to functions whereas C++ provides two implementations. From a side, it reuses the same mechanism derived from C (i.e., pointers + pass by value). On the other hand, C++ also provides a native “pass by reference” solution which makes use of the idea of reference types. Thus, even in C++ if you are passing a pointer à la C, you are not truly passing by reference, you are passing a pointer by value (that is, of course, unless you are passing a reference to a pointer! e.g., int*&). Because of this potential ambiguity in the term “pass by reference”, perhaps it’s best to only use it in the context of C++ when you are using a reference type.
但是正如您和其他人已经指出的那样,在通过参数传递任何内容的概念中,无论是 value 还是 reference,根据定义,某物 必须具有 值。
在机器代码级别,"pass X by reference" 本质上是 "pass the address of X by value"。
指针是值。价值观是价值观。值具有唯一标识,需要存储。
引用不是值。参考没有身份。如果我们有:
int x=0;
int& y=x;
int& z=x;
y
和z
都是对x
的引用,没有独立的身份。
比较:
int x=0;
int* py=&x;
int* pz=&x;
py
和pz
都是指向x
的指针,具有独立的标识。你可以修改 py
而不是 pz
,你可以获得它们的大小,你可以 memset 它们。
在某些情况下,在机器代码级别,引用的实现方式与指针相同,只是某些操作永远不会对它们执行(例如重新瞄准它们)。
但是C++并不是按照机器码来定义的。它是根据抽象机器的行为定义的。编译器将你的代码编译为这个抽象机器上的操作,它没有固定的调用约定(按照标准),没有引用布局,没有堆栈,没有堆等。然后它会对此进行任意转换,不会改变 as-如果行为(一个常见的行为是单一赋值),重新排列事物,然后在某个时候发出 assembly/machine 代码,在您 运行 使用的实际硬件上生成类似的行为。
现在编译 C++ 的近乎通用的方法是编译 unit/linker 模型,其中函数作为符号导出,并为其他编译单元提供固定的 ABI 调用约定以使用它们。然后在 link 阶段将编译单元连接在一起。
在这些 ABI 中,引用作为指针传递。