C++98 和 C++11 之间的变化显示了行为上的差异



我正在阅读以下帖子:

  • C++14 中引入的哪些更改可能会破坏用 C++11 编写的程序?

以及ISOCPP页面:

  • https://isocpp.org/files/papers/p0636r0.html

所以我很好奇,根据标准:C++11 中引入的哪些更改可能会破坏用 C++98 编写的程序?

突出

的大问题 - 从析构函数中抛出异常。

在 C++98 中,如果您小心的话,您可以拥有执行此操作并正常工作的程序。

在 C++11 中,您通常必须显式声明 dtor noexcept(false)

不错的博客文章在这里,在Andrzej的C++博客上。

简而言之,以下程序曾经在 C++03 中成功运行(在"成功"的某种定义下):

struct S
{
  ~S() { throw runtime_error(""); } // bad, but acceptable
}; 
int main()
{
  try { S s; }
  catch (...) {
    cerr << "exception occurred";
  } 
  cout << "success";
}

在 C++11 中,同一程序将触发对std::terminate的调用。

这是与析构函数相关的另一种情况,在 C++11 中是 noexcept(true):

// A simple program that demonstrates how C++11 and pthread_cancel don't play
// nicely together.
//
// If you build without C++11 support (g++ threadkill.cpp -lpthread), the
// application will work as expected. After 5 seconds, main() will cancel the
// thread it created and the program will successfully exit.
//
// If you build with C++11 support(g++ -std=c++11 threadkill.cpp -lpthread),
// the program will crash because the abi::__forced_unwind exception will
// escape the destructor, which is implicitly marked as noexcept(true) in
// C++11. If you mark the destructor as noexcept(false), the program does 
// not crash.
#include <iostream>
#include <unistd.h>
#include <string.h>
class sleepyDestructorObject
{
public:
    ~sleepyDestructorObject() //noexcept(false)
    {
        std::cout << "sleepy destructor invoked" << std::endl;
        while(true)
        {
            std::cout << "." << std::flush;
            sleep(1);
        }
    }
};
void* threadFunc( void* lpParam )
{
    sleepyDestructorObject sleepy;
    return NULL;
}
int main(int argc, char** argv)
{
    pthread_t tThreadID;
    pthread_create(&tThreadID, NULL, threadFunc, NULL);
    sleep(5);
    pthread_cancel(tThreadID);
    pthread_join(tThreadID, NULL);
    return 0;
}

原始参考资料:

  • https://gcc.gnu.org/ml/gcc-help/2015-08/msg00036.html

最新更新