0

I wrote the following code which outputs 45:

#include <iostream>

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

Because the lifetime of n ends at the scope I expected this code to emit an error or warning. Using GCC 6.1.0 and Clang 3.8.0 and the libubsan sanitizer I don't get a blip.

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

Valgrind doesn't complain either. If I look at the assembly, GCC just reuses the same value from the stack:

  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

I know it's undefined behavior to deference a NULL pointer, but what about a dangling pointer? (If it's undefined behavior, please provide quotes from the standard.)


I'd like for someone to prove it's undefined behavior, not just say that it is without proof. The duplicate has a lot of answers that make uncited claims. In C, it explicitly says that "using an object outside its lifetime" is undefined behavior. In C++, this is not the case. In fact, §3.8 doesn't seem to say anything remotely that direct.

Please reopen my question so I can get some actual proof and not cargo culting.

  • Have a look at this. http://stackoverflow.com/questions/13888268/what-happens-when-a-variable-goes-out-of-scope It is almost exactly the same question. – Jerry Jeremiah May 23 '16 at 01:55
  • Lifetime of function level variables is function call duration. Visibility is limited to the declaring scope, but lifetime isn't. – Seva Alekseyev May 23 '16 at 01:55
  • Add `-O` to your flags and you should get a warning. – user657267 May 23 '16 at 01:56
  • @JerryJeremiah C and C++ are different languages. – user6369079 May 23 '16 at 01:56
  • 2
    @user6369079 What about http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope ? – Jerry Jeremiah May 23 '16 at 01:58
  • @SevaAlekseyev: Not sure what you mean by "function level variables", but for automatic variables (such as `n` in the OP's code), lifetime is bound to the scope. – Benjamin Lindley May 23 '16 at 02:04
  • @JerryJeremiah I don't see any authoritative references in that question. Also, the code is different: that's trivially diagnosable. – user6369079 May 23 '16 at 02:05
  • I closed this as duplicate even though the very popular answer doesn't reference the standard (AFAICS). The relevant language is about lifetime, at the start. – Cheers and hth. - Alf May 23 '16 at 02:09
  • @Cheersandhth.-Alf The popular answer is clearly implying it's undefined behavior with "In this situation anything can happen." I don't care what happens in this code because I never intend to use it. I'm explicitly asking if it's undefined behavior and that link does not remotely answer that question. – user6369079 May 23 '16 at 02:11
  • Answered with an amazingly excellent analogy here: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – Daniel Goldfarb May 23 '16 at 02:12
  • @user6369079 Huh? Sure it does. Saying "anything can happen" means it's undefined behavior. If it had defined behavior, clearly "anything" couldn't happen! – Barry May 23 '16 at 02:17
  • @Barry "Sure anything can happen, therefore it's undefined behavior." "Yeah, but where in the standard does it say that?" "It's undefined behavior, anything can happen!" – user6369079 May 23 '16 at 02:19
  • 1
    @Barry [Read this](https://stackoverflow.com/questions/28727439/is-it-undefined-behavior-to-dereference-a-dangling-pointer) and get back to me. – user6369079 May 23 '16 at 02:19
  • @user6369079 That's why these are comments. If I had the standard handy it would have been an answer. I was just trying to be helpful - sorry about that. – Jerry Jeremiah May 23 '16 at 02:20
  • @user6369079: I'm sorry - it's non-trivial to find the relevant standardese. I'm reopening the question. It is a duplicate of [at least one other question about it](https://stackoverflow.com/questions/28727439/is-it-undefined-behavior-to-dereference-a-dangling-pointer), but there's no answer yet. – Cheers and hth. - Alf May 23 '16 at 02:34
  • @Cheersandhth.-Alf Too bad [examples](http://eel.is/c++draft/conv.lval#2) are non-normative... – Barry May 23 '16 at 02:37
  • @Barry: There's also explicit language about this for a variable of thread storage duration. And there's the loosely associated statement that "The properties ascribed to objects throughout this International Standard apply for a given object only during its lifetime". It doesn't apply because it's about accessing the storage before or after the object lifetime. It's worth noting I think that there's a similar problem with proving dereference of nullpointer is UB. It's *not* UB in a `typeid` expression. – Cheers and hth. - Alf May 23 '16 at 02:42
  • I posted a new answer on the current duplicate – M.M May 23 '16 at 03:16

1 Answers1

0

This is also undefined behavior.

A C++ compiler is not required to figure out and issue a diagnostic about every possible kind of undefined behavior. It's certainly better to have the compiler catch as much as possible, and, over time, compilers have been getting better at blowing the whistle on more and more stuff that doesn't pass the smell test.

But, of course, just because the C++ compiler doesn't complain doesn't mean that the code is right.

Sam Varshavchik
  • 84,126
  • 5
  • 57
  • 106
  • I'm looking for references to back up that it's "undefined behavior", not just cargo culting and cute analogies. Unlike C, C++ doesn't have a convenient quote that outright says "this is undefined". For all we know, the code is well-defined. – user6369079 May 23 '16 at 02:03
  • I'm fairly certain that somewhere in the C++ standard it is specified that dereferencing a pointer to an object that went out of scope, and whose destructor has been called, is undefined behavior. This is fundamental. – Sam Varshavchik May 23 '16 at 02:30