使用-O3编译时出现奇怪的段错误

Strange segfault when compiling with -O3

本文关键字:段错误 错误 编译 -O3 使用      更新时间:2023-10-16

下面的代码可以在Debian 7的g++ 4.7.2-5上正常编译和工作。

#include <iostream>
#include <string.h>
using namespace std;
class mystring {
  char * buf;
  static char * dupbuf(const char * buf) {
    char * result = new char[strlen(buf) + 1];
    strcpy(result, buf);
    return result;
  }
  public:
    mystring(const char * o)
    : buf(dupbuf(o)) {}
    ~mystring() { delete[] buf; }
    mystring(const mystring &) = delete;
    mystring & operator=(const mystring&) = delete;
    void write(ostream & o) const {
      if (!buf) { exit(1); } // remove me
      o << buf;
    }
};
ostream & operator <<(ostream & o, const mystring & ms) {
  ms.write(o);
};
int main() {
    mystring m("hello");
    cout << m << endl;
    return 0;
}

…除非使用-O2或更高版本编译。然后它会出现段错误,valgrind会声明从0x0读取的数据无效。我猜有一些堆栈损坏,但对于我的生命,我找不到它。

有趣的是,删除标记为"remove me"的行会使问题消失。把一个endl加到write上也一样。什么好主意吗?
ostream & operator <<(ostream & o, const mystring & ms) {
  ms.write(o);
};

这会导致未定义的行为,因为它不返回任何东西。此外,名称空间级别的空声明(";")是完全没有必要的(并且在旧的c++标准中是非法的)。