字符串错误或编译器错误?

Gen*_*Tel -5 c++ string c++11

我有以下问题,其中调试中的输出似乎完全违反代码所说的内容,似乎它可能是编译器中的错误,除非我遗漏了一些东西.

所以这是代码,它应该创建两个文件名字符串并删除其中一个文件.

auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);
Run Code Online (Sandbox Code Playgroud)

但是,它在实践中没有表现出这种行为,实际上我们在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"
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,尽管使用具有不同字符串文字的两个不同表达式初始化字符串,但在初始化之后它们最终会成为指向同一字符串的相同指针.

这有些编译器优化是否已经脱轨或者是什么?

Som*_*ken 10

auto *real = (base_dir + "/index.txt").c_str();
auto *bkp = (base_dir + "/index.txt.new").c_str();
remove(real);
Run Code Online (Sandbox Code Playgroud)

您正在real函数调用中使用remove()real指向std::string已经被销毁的内部缓冲区,因为它是一个临时的,尝试从中读取未定义的行为,因此这里唯一的错误是您的代码.


要解决此问题,请保存字符串,然后要求c_str():

auto real = (base_dir + "/index.txt");
auto bkp = (base_dir + "/index.txt.new");
remove(real.c_str());
Run Code Online (Sandbox Code Playgroud)