跨編譯器和配置的引用實現
C 中的引用是一個強大的功能,可以高效地訪問超出變量範圍的內存。但它們實際上是如何實現的呢?
標準建議和實現差異
C 標準沒有強制要求特定的實現以供參考。但是,編譯器通常遵循某些準則:
範例程式和編譯器輸出
為了示範引用的內部實現,請考慮以下程式:
#include <stdio.h> #include <stdlib.h> int byref(int &foo) { printf("%d\n", foo); } int byptr(int *foo) { printf("%d\n", *foo); } int main() { int aFoo = 5; byref(aFoo); byptr(&aFoo); }
在停用LLVM 和最佳化的情況下編譯此程式會產生相同的彙編程式碼byref 和byptr函數:
define i32 @_Z5byrefRi(i32* %foo) { %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) { %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 }
在此組譯程式碼中,兩個函數使用相同的指令來載入和取消引用輸入變數富。這表明編譯器在底層以類似的方式對待引用和指標。
結論
引用和指標是 C 中密切相關的概念。雖然標準沒有規定具體的實現,但編譯器通常將引用實現為指標。這允許高效且可互換地使用引用和指標來存取變數範圍之外的記憶體。
以上是C 中的引用實際上是如何實現的?的詳細內容。更多資訊請關注PHP中文網其他相關文章!