簡體   English   中英

const& args 存儲在哪里?

[英]Where is the const& args stored?

這是 function 定義

const int& test_const_ref(const int& a) {
  return a;
}

並從main調用它

int main() {
  auto& x = test_const_ref(1);
  printf("%d, %p\n", x, &x);
}

output 如下

 ./debug/main
>>> 1, 0x7ffee237285c

這是test_const_ref的反匯編代碼

test_const_ref(int const&):
    pushq  %rbp
    movq   %rsp, %rbp
    movq   %rdi, -0x8(%rbp)
    movq   -0x8(%rbp), %rax
    popq   %rbp
    retq

問題是:變量x別名或我傳遞給 function test_const_ref的數字1存儲在哪里?

該代碼表現出未定義的行為- function test_const_ref返回一個對臨時的引用,該引用一直存在到完整表達式( ; )的末尾,之后對其的任何取消引用都會訪問一個懸空引用。

出現工作是UB的常見表現。 程序仍然是錯誤的。 例如,通過優化Clang 12 -O2打印: 0

注意 - function test_const_ref本身沒有錯誤(除了設計錯誤)。 UB 在main中,在調用printf期間,懸空int&的取消引用發生。

臨時int准確存儲的位置是實現細節 - 但在許多情況下(在調試版本中,當 function 未內聯時),它將存儲在堆棧中:

main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     dword ptr [rbp - 12], 1      # Here the 1 is stored in the stack frame
        lea     rdi, [rbp - 12]
        call    test_const_ref(int const&)
        mov     qword ptr [rbp - 8], rax
        mov     rax, qword ptr [rbp - 8]
        mov     esi, dword ptr [rax]
        mov     rdx, qword ptr [rbp - 8]
        movabs  rdi, offset .L.str
        mov     al, 0
        call    printf

因此,任何后續使用返回的引用都將訪問[rbp - 12]處的 memory ,這可能已經被重新用於其他目的。


另請注意,編譯器實際上並未從 C++ 代碼生成程序集; 它僅使用 C++ 代碼來理解意圖,並生成另一個程序來生成預期的 output。 這被稱為假設規則 在存在未定義行為的情況下,編譯器不受此限制,可能會生成任何output,從而使程序變得毫無意義。

已經給出了很好的答案,但是wrapperm 在這里很好地解釋了這個主題。 在我知道的大多數實現中,它將存儲在堆棧中。

1. function

該語言沒有定義 arguments 到函數的存儲位置。 針對不同平台的不同 ABI 對此進行了定義。

通常,在進行任何優化之前,function 參數存儲在堆棧中。 參考在這方面沒有什么不同。 實際存儲的是指向 object 的指針。 這樣想:

const int* test_const_ref(const int* a) {
  return a;
}

2.臨時

如果你要聲明一個變量int foo; 並調用test_const_ref(foo) ,您知道結果將引用foo 由於您使用臨時調用它,因此所有賭注都已關閉:正如@fabian 在評論中指出的那樣,該語言僅保證該值存在直到賦值語句結束。 然后

在實踐中,在您的情況下:為臨時 integer 1分配堆棧空間的編譯器將x引用該位置,並且在定義x之前不會將其用於其他用途。 但是,如果您的編譯器優化了該堆棧分配 - 例如通過寄存器傳遞1 - 那么x沒有可引用的內容並且可能包含垃圾。 它甚至可能是未定義的行為(對此不太確定)。 如果你幸運的話,你會得到一個關於它的編譯器警告(GodBolt.org)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM