VC++2013で非推奨属性を扱うdeprecated宣言を使う
C++14 には名前やエンティティに非推奨属性を付加するdeprecated attributeと呼ばれる規格が存在する。
[[deprecated]] attribute
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3760.html
が、残念ながら例によって例の如くMicrosoft Visual C++ 2013ではまだ使えない。
その代わり、VC++2013ではdeprecated pragmaと呼ばれるプリプロセッサディレクティブと、deprecated宣言が存在する。
deprecated (C/C++)
http://msdn.microsoft.com/library/c8xdzzhh.aspx
deprecated (C++)
http://msdn.microsoft.com/library/044swk7y.aspx
上記の機能を用いると、C4996ビルドエラーが生成される*1。
コンパイラの警告 (レベル 3) C4996 http://msdn.microsoft.com/library/ttcz0bys.aspx
ここで問題になるのは、VC++2013ではC4996は警告ではなくエラー扱いであることである*2。MSDNでは、あくまで「警告」としか書かれていない。罠だろうか。
このエラーを警告として扱うためにプリプロセッサディレクティブ#pragma warning
を用いる必要がある。
__declspec(deprecated("This is deprecated function.")) void DeprecatedFunction(){} int main() { __pragma(warning(push)); __pragma(warning(3:4996)); DeprecatedFunction(); __pragma(warning(pop)); return 0; }
__pragma
は#pragma
を置き換えるマクロである。__pragma(warning(push))
で全ての警告の設定をスタックに格納し、その後C4996の警告レベルを3にセットし、非推奨関数の呼び出し後に__pragma(warning(pop))
を用いてスタックしておいた警告の設定をポップしている。
マクロの末尾にセミコロンを置いているのは、VSのスマートインデントでインデントがずれないようにするためである。
警告レベルには1から4が存在し、大きいほど重要でない警告となる。あまり低くすると警告が表示されなくなってしまうので、今回は3にした。規定値では、Debugビルドでは警告レベル4は抑制され表示されない。
/w、/Wn、/WX、/Wall、/wln、/wdn、/wen、/won (警告レベル)
http://msdn.microsoft.com/library/thxezb7y.aspx
関数呼び出しそのものをマクロ化してしまえば、固定の警告レベルで警告を出すように出来るが、可能な限り自前でのプリプロセッサを用いたプログラミングは避けたいので上記の様なコードになっている。
MSがdeprecated attributeを実装してくれれば、この様な面倒な記述をしなくて済むのだが……