C++ コードは C++03 と C++11 の両方で有効ですが、異なる動作をする可能性がありますか? 質問する

C++ コードは C++03 と C++11 の両方で有効ですが、異なる動作をする可能性がありますか? 質問する

C++コードがC++03標準とC++11標準ですが、どの標準に基づいてコンパイルされているかによって異なる処理を実行しますか?

ベストアンサー1

答えは間違いなく「はい」です。プラス面としては、次のようなものがあります。

  • 以前は暗黙的にオブジェクトをコピーしていたコードは、可能な場合は暗黙的にオブジェクトを移動するようになりました。

否定的な側面については、規格の付録 C にいくつかの例が記載されています。肯定的な例よりも否定的な例の方がはるかに多いですが、それぞれが発生する可能性ははるかに低くなります。

文字列リテラル

#define u8 "abc"
const char* s = u8"def"; // Previously "abcdef", now "def"

そして

#define _x "there"
"hello "_x // Previously "hello there", now a user defined string literal

0の型変換

C++11 では、リテラルのみが整数の null ポインター定数です。

void f(void *); // #1
void f(...); // #2
template<int N> void g() {
    f(0*N); // Calls #2; used to call #1
}

整数除算と剰余後の丸め結果

C++03では、コンパイラは0または負の無限大のどちらかに丸めることができましたが、C++11では0に丸めることが必須となっています。

int i = (-1) / 2; // Might have been -1 in C++03, is now ensured to be 0

ネストされたテンプレートの閉じ括弧 >> と > > の間の空白

特殊化またはインスタンス化の内部では、>>C++03では右シフトとして解釈される可能性があります。ただし、これは既存のコードを壊す可能性が高くなります。(http://gustedt.wordpress.com/2013/12/15/a-disimprovement-observed-from-the-outside-right-angle-brackets/

template< unsigned len > unsigned int fun(unsigned int x);
typedef unsigned int (*fun_t)(unsigned int);
template< fun_t f > unsigned int fon(unsigned int x);

void total(void) {
    // fon<fun<9> >(1) >> 2 in both standards
    unsigned int A = fon< fun< 9 > >(1) >>(2);
    // fon<fun<4> >(2) in C++03
    // Compile time error in C++11
    unsigned int B = fon< fun< 9 >>(1) > >(2);
}

オペレータはnew、以下の例外をスローする可能性がある。std::bad_alloc

struct foo { void *operator new(size_t x){ throw std::exception(); } }
try {
    foo *f = new foo();
} catch (std::bad_alloc &) {
    // c++03 code
} catch (std::exception &) {
    // c++11 code
}

ユーザ宣言のデストラクタには暗黙の例外指定例がある。C++11 ではどのような重大な変更が導入されましたか?

struct A {
    ~A() { throw "foo"; } // Calls std::terminate in C++11
};
//...
try { 
    A a; 
} catch(...) { 
    // C++03 will catch the exception
} 

size()コンテナはO(1)で実行する必要がある

std::list<double> list;
// ...
size_t s = list.size(); // Might be an O(n) operation in C++03

std::ios_base::failurestd::exceptionもはや直接的に派生するものではない

直接の基本クラスは新しいですが、std::runtime_errorそうではありません。つまり、

try {
    std::cin >> variable; // exceptions enabled, and error here
} catch(std::runtime_error &) {
    std::cerr << "C++11\n";
} catch(std::ios_base::failure &) {
    std::cerr << "Pre-C++11\n";
}

おすすめ記事