Поймать висячий указатель

Я написал следующий код, который выводит 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 sanitizer, я не получаю сообщения.

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

Я знаю, что это неопределенное поведение, чтобы задерживать нулевой указатель, но как насчет висячего указателя? (Если это неопределенное поведение, пожалуйста, предоставьте цитаты из стандарта.)


Я бы хотел, чтобы кто-то доказал это неопределенное поведение, а не просто сказал, что оно без доказательств. Дубликат имеет много ответов, которые делают невостребованные претензии. В Си это явно говорит, что "использование объекта вне его времени жизни" - неопределенное поведение. В C++ это не так. Фактически, §3.8, кажется, не говорит ничего отдаленно прямого.

Пожалуйста, снова откройте мой вопрос, чтобы я мог получить некоторые фактические доказательства, а не сбор груза.

1 ответ

Это также неопределенное поведение.

Компилятор C++ не обязан выяснять и выдавать диагностику обо всех возможных видах неопределенного поведения. Конечно, лучше, чтобы компилятор ловил как можно больше, и со временем компиляторам становилось все лучше и лучше звучать все больше и больше вещей, которые не проходят тест на запах.

Но, разумеется, тот факт, что компилятор C++ не жалуется, не означает, что код верен.

Другие вопросы по тегам