C++03とC++11の互換性についての補足

id:melponさんがC++03とC++11の互換性について書かれました。ぜひ読むべきだと思います。

当該記事のコメント欄で指摘されてますが、n3291*1のC.1に書かれている部分が抜けているので補足します。C.1にはC言語からの変更について書かれており、C++03では変更されてないがC++11で変更されたものも含まれています。C.1に書かれているもののうち、C++03で既にC言語から変更されているものについては書きません。知りたい場合は規格か適当な書籍に当たってください。
変更部分は2つあります。文字列リテラルに関することと、autoキーワードの意味の変更です。これらの変更によって互換性の問題が発生したとしても、修正するのは容易です。修正方法も書きました。

文字列リテラル

Cでは、文字列リテラルはconstではありませんでした。

char* s = "abc"; // valid in C

C++03の文字列リテラルはconstになりましたが、constでないポインタで文字列リテラルを指したり、constでないポインタを引数に取る関数に文字列リテラルを渡したりできました(deprecatedですが)。C++11ではこれらが禁止されました。

char* s = "abc"; // deprecated in C++03
                 // invalid in C++11

void f(char*);
f("abc"); // deprecated in C++03
          // invalid in C++11

修正方法は、constを付けることです。

char const* s = "abc";

void f(char const*);
f("abc");

関数を修正できない場合は、char*にキャストするか、文字列をコピーすることによって解決できます。

void f(char*);

// キャストによる解決
f(const_cast<char*>("abc"));

// コピーによる解決
char s[] = "abc";
f(s);

当然ですが、キャストによる解決の場合、関数の中で文字列を書き換えてはいけません。

autoの意味の変更

C言語およびC++03では、自動変数を定義するときにautoというキーワードを付けることができました。単に自動変数であることを明示的に示すだけで、省略しても全く問題ありません。

auto int n = 0; // int n = 0;

C++11では、autoは別の意味を持ちます。初期化子から変数の型を推論するときに使うようになりました。

auto n = 0; // int n = 0;
auto const x = 3.14; // double const x = 3.14;

この変更に伴い、型を明示的に書くときにautoを付けることはできなくなりました。

auto int n = 0; // invalid in C++11

解決法は、単にautoを削除するだけです。

*1:C++11の最新ドラフト。ダウンロードできなくなったが、ほぼ同等のn3242で多くの場合代用できる。