0

出力する次のコードを書きました45

#include <iostream>

int main() 
{
    int *p;
    {
        int n = 45;
        p = &n;
    }
    std::cout << *p;
}

の有効期間はnスコープで終了するため、このコードがエラーまたは警告を発すると予想していました。GCC 6.1.0 と Clang 3.8.0 と libubsan サニタイザーを使用しても、問題は発生しません。

g++ -Wall -Wextra -pedantic -fsanitize=undefined
clang++ -Weverything -fsanitize=undefined

ヴァルグリンドも文句を言わない。アセンブリを見ると、GCC はスタックから同じ値を再利用しているだけです。

  400789:   48 89 45 f8             mov    QWORD PTR [rbp-0x8],rax
        std::cout << *p;
  40078d:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  400791:   8b 00                   mov    eax,DWORD PTR [rax]
  400793:   89 c6                   mov    esi,eax
  400795:   bf 60 10 60 00          mov    edi,0x601060
  40079a:   e8 81 fe ff ff          call   400620 <std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@plt>
    }
    std::cout << *p;
  40079f:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  4007a3:   8b 00                   mov    eax,DWORD PTR [rax]
  4007a5:   89 c6                   mov    esi,eax
  4007a7:   bf 60 10 60 00          mov    edi,0x601060

NULL ポインターを参照するのは未定義の動作であることはわかっていますが、ダングリング ポインターはどうでしょうか。(未定義の動作である場合は、標準から引用してください。)


証拠がないと言うだけでなく、未定義の動作であることを誰かに証明してもらいたいです。複製には、引用されていない主張をする多くの回答があります。Cでは、「有効期間外にオブジェクトを使用する」ことは未定義の動作であると明示的に述べています。C++ では、これは当てはまりません。実際、§3.8 はそれほど直接的なことは何も言っていないようです。

質問を再開して、カーゴカルトではなく実際の証拠を入手できるようにしてください。

4

1 に答える 1