みなさん、こんにちは。
今回はC++17(2017年12月に改訂され、ISO/IEC 14882:2017で標準規格化されたC++バージョンの通称)
で追加された機能について見ていきたいと思います。
全部は書けないので今回は一部のみですが今後残りを書いていく予定..にしています。
参考
cpprefjp – C++日本語リファレンス C++17
江添亮の詳説C++17
上記のページを見れば十分なんですが自分の学習も兼ねて見ていきたいと思います。
ちなみにC++17はC++03からC++11に変わったときのような大きな変更ではない、とは言われていますが
それでもいろいろと変わっていますね。
まずは小手調べに
機能の削除
C++17において以下の機能が削除されています。
- 非推奨だったbool型に対するインクリメント演算子を削除
- トライグラフの削除
- 非推奨だったregisterキーワードを削除
- 非推奨だった古い例外仕様を削除
まず
・非推奨だったbool型に対するインクリメント演算子を削除
ですがoperator++がboolに関しては禁止となったと。
1 2 3 4 5 6 7 8 |
#include <iostream> int main() { bool a = false; std::cout << std::boolalpha << a << std::endl; ++a; std::cout << std::boolalpha << a << std::endl; } |
上記をC++14で実行すると警告はでるもののfalse,trueと表示されます。
しかしこれがC++17だと、
1 |
error: use of an operand of type 'bool' in 'operator++' is forbidden in C++17 |
エラーになります。まあこれは削除しても問題ない、というよりなくていいでしょう。
そもそもC++98の時点で非推奨なのでようやくといったところでしょうか。
しかしこれ、
非推奨だった bool 型に対するインクリメント演算子を削除
これによく似たバグで少なくとも6つの過度の放射線被曝事故を引き起こし、3人が死亡した例がある。
Therac-25はカナダ原子力公社(AECL)とフランスCGR-MeV社によって開発・製造された放射線療法機器である。
この装置のソフトウェアのバグの一つに、条件変数を非0にする(=trueにする)ために、インクリメントを使っていたというものがあった。
条件変数はC++でいえばstd::uint8_t型で、つまり256回に1度オーバーフローを起こして値が0になるために、falseとして扱われた。
この結果ほかの条件変数の状態によっては25MeVという通常の100倍のβ線が射出されることがあった。
怖すぎる..
次は
・トライグラフの削除
トライグラフ?正直何のことだとわからなかったのですがwikipediaによるとトライグラフとは
ISO 646 に共通して含まれる文字だけでソースコードを書くための表記法であるとのこと。
トライグラフ
#や[といった文字が全部で9つがトライグラフであると。
1 2 3 4 5 6 |
#include <iostream> int main() { std::cout << '??=' << '\n'; std::cout << '??<' << '\n'; } |
こんな感じだとそれぞれ#、{と表示されていたがこれがC++17だと4144957,4144956と表示されます。
(警告はC++14でも出ますが)
まあ今まで使ったことがないし今後トライグラフにお目にかかることもない..だろう。
registerキーワード削除はC++11で非推奨となっていたがこのたび削除になりました。
registerキーワードはC言語から引き継いだものだが将来の為に予約されたままになる、とのこと。
最後は非推奨だった古い例外仕様を削除。
C++11でnoexcept機能が入ったことで非推奨となっていたがこのたび削除の運びとなった。
昔のプロジェクトでthrowを書きまくったコードでいっぱいだったがあれはC++17にするんだろうか、いやその前にC++11にするのかもわからないが..
今回結局機能削除しただけで終わったがまた機会があれば残りもぼちぼち見ていきたいと思います。
#今回のコード実行はwandboxでやりました。違うバージョンを手軽に試せるのがいいですね。
おまけ こちらの本がC++17対応になっているとのこと