4

I was reading the following post:

and also the isocpp page:

So I became curious, according to the Standard: What changes introduced in C++11 can potentially break a program written in C++98?

malat
  • 12,152
  • 13
  • 89
  • 158
  • Some interesting cases here: https://stackoverflow.com/questions/6399615/what-breaking-changes-are-introduced-in-c11 I thought I had a good example, but it was based on *implicit int* that was never formally carried over to C++. – Bathsheba Oct 09 '17 at 16:08

2 Answers2

3

Big one that stands out -- throwing exceptions from destructors.

In C++98 you can have programs that do this and work fine if you are careful.

In C++11 you will often have to explicitly declare the dtor noexcept(false).

Nice blog post here, on Andrzej's C++ blog.

In short, the following program used to run successfully in C++03 (under some definition of “success”):

struct S
{
  ~S() { throw runtime_error(""); } // bad, but acceptable
}; 

int main()
{
  try { S s; }
  catch (...) {
    cerr << "exception occurred";
  } 
  cout << "success";
}

In C++11, the same program will trigger the call to std::terminate.

Chris Beck
  • 15,614
  • 4
  • 51
  • 87
0

Here is another case related to destructors are noexcept(true) in C++11:

// 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;
}

Original reference:

malat
  • 12,152
  • 13
  • 89
  • 158