Поймать висячий указатель
Я написал следующий код, который выводит 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++ не жалуется, не означает, что код верен.