-5

I've got the following issue where the output in debug appears to completely defy what the code says and it seems like it could be a bug in the compiler unless I'm missing something.

So here's the code, it's supposed to create two filename strings and delete one of the files.

auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);

However, it does not exhibit this behavior in practice, and in reality we get the following in gdb:

auto *real = (base_dir + "/index.txt").c_str();
(gdb) n
auto *bkp = (base_dir + "/index.txt.new").c_str();
(gdb) n
remove(real);
(gdb) p real
$1 = 0x7060e8 "./ss-clientdir/index.txt.new"
(gdb) p bkp
$2 = 0x7060e8 "./ss-clientdir/index.txt.new"

So as you can see, despite the strings being initialized using two different expressions with different string literals, after initialization they end up as the same pointer to the same string.

Is this some compiler optimization gone off the rails or what?

GenTel
  • 1,448
  • 3
  • 13
  • 19
  • 9
    Remember the first rule of programming: [It's always your fault](https://blog.codinghorror.com/the-first-rule-of-programming-its-always-your-fault/) – Yksisarvinen Feb 18 '19 at 21:30
  • 1
    Welcome to C++. Here's some handy reading before you get your head tied in knots: [What is meant by Resource Acquisition is Initialization (RAII)?](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii) – user4581301 Feb 18 '19 at 21:32
  • 1
    *Is this some compiler optimization gone off the rails or what* -- In addition to the comment by @Yksisarvinen, you should realize that the compiler you're using is used by thousands of persons, and maybe hundreds, if not thousands of companies around the world. If there was such a compiler bug in a small toy program as you've demonstrated, then most of the C++ community would have talked about it and informed the compiler writers (and would be embarrassing for the folks who maintain the compiler). Thus it is always unlikely it is a compiler bug. – PaulMcKenzie Feb 18 '19 at 23:00
  • 1
    In proper languages this would be a bug. In C++ it's "your fault". – Boann Feb 19 '19 at 00:05
  • @Boann Let's not talk about Java and proper languages. – Hatted Rooster Feb 19 '19 at 09:29

1 Answers1

10
auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);

You're using real in the function call remove() but real points to an internal buffer inside the std::string that has already been destroyed because it was a temporary, attempting to read from it is undefined behavior and thus the only bug here is your code.


To fix this, save the string and then ask for a c_str() :

auto real = (base_dir + "/index.txt");
auto bkp = (base_dir + "/index.txt.new");
remove(real.c_str());
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122