Just to repeat some of the stuff everyone's been saying, lets look at some compiler output:
#include <stdio.h>
#include <stdlib.h>
int byref(int & foo)
{
printf("%d
", foo);
}
int byptr(int * foo)
{
printf("%d
", *foo);
}
int main(int argc, char **argv) {
int aFoo = 5;
byref(aFoo);
byptr(&aFoo);
}
We can compile this with LLVM (with optimizations turned off) and we get the following:
define i32 @_Z5byrefRi(i32* %foo) {
entry:
%foo_addr = alloca i32* ; <i32**> [#uses=2]
%retval = alloca i32 ; <i32*> [#uses=1]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i32* %foo, i32** %foo_addr
%0 = load i32** %foo_addr, align 8 ; <i32*> [#uses=1]
%1 = load i32* %0, align 4 ; <i32> [#uses=1]
%2 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %1) ; <i32> [#uses=0]
br label %return
return: ; preds = %entry
%retval1 = load i32* %retval ; <i32> [#uses=1]
ret i32 %retval1
}
define i32 @_Z5byptrPi(i32* %foo) {
entry:
%foo_addr = alloca i32* ; <i32**> [#uses=2]
%retval = alloca i32 ; <i32*> [#uses=1]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i32* %foo, i32** %foo_addr
%0 = load i32** %foo_addr, align 8 ; <i32*> [#uses=1]
%1 = load i32* %0, align 4 ; <i32> [#uses=1]
%2 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %1) ; <i32> [#uses=0]
br label %return
return: ; preds = %entry
%retval1 = load i32* %retval ; <i32> [#uses=1]
ret i32 %retval1
}
The bodies of both functions are identical
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…