おことわり
意識低すぎる初心者の戯言です.
話
他の人の立派なC++の記事 を読んでて,
「そういや,自分, assert ってほとんど使ってないな? なんでかなー?」っていう.
(1)他の方法でデバッグできるし?
assert って「デバッグの手段」だと思っている.
(もうこの時点で圧倒的に間違っているのかもしれないが… assert というのはコード内に残し続ける物ではない,と思っている)
で,デバッグの手段って他にもあって……
- デバッガ使える状況ならコードに手を入れなくて済むし
- 怪しい箇所がある程度分かってるならステップ実行とかで見ればまぁ,うん.みたいな.
-
assertじゃなくて条件付けたブレークポイントとかで見れば良い感.
- printfデバッグ
-
assertって書く代わりに,何か出力を書いても大抵事足りる気が.- (あと,意識低すぎて「
assertって…真偽どっちだっけ?」ってなるので,そしたらさっさとprintf的なのを書いちゃうみたいな)
- (あと,意識低すぎて「
- (後述の(3)にも似たようなこと書いてるけど)デバッグビルドじゃなくてもやれるし.
-
……という感じで, assert の出番が来ない感.
(2)std::logic_errorを投げるし?
「外から入ってきたやつが話と違うんですけど?」みたいな場合には std::logic_error 系のを throw するというスタイル.
(外の世界とは関係の無い完全に内側の話については,前記(1))
/// <summary>なんか処理</summary>
/// <param name="p">何か有効なやつを指すポインタ.nullを渡してはならない!</param>
/// <exception cref="std::invalid_argument">pがnullのときは例外を送出</exception>
void F( XXX *p )
{
//assert( p!=nullptr ); //こうじゃなくて
if( !p )throw std::invalid_argument( "pがnullくね?" ); //こう
//...
}
「俺はコメントで仕様を明記したというのに,お前(:使う側)がそれを破ったのだから,そしたら始末もお前がつけろや!」みたいな姿勢.
(3)「デバッグビルド時にしか効かない」という特性では,到底俺の意識低さに対抗できないし?
(前述のように,そもそも assert ってコード内に残らないのだと思っているのだけども,仮に残していくのだとして)
「リリースビルド時には消えてなくなるよ!」っていうのは,要は,
- まずデバッグビルドで完膚なきまでにデバッグするよね
- そしたらもう,あとはリリースビルドで
っていう流れでちゃんとやれや,ってことなんだろうけど……
以下のような不真面目な理由により,意識低いとこれをどうにも徹底できない場合があると思うの.
- デバッグだと動作がアホみたいに重くてもう見てらんないので…
- 例えば,「シミュレーション」とか「最適化」とか「画像処理」だとかいう要素が入ってるとつらいことが
- ライブラリのデバッグ版バイナリが提供されてないので!
- 自分でライブラリをビルドすることが{単に面倒/すごく難しい/何故かコンパイル通らない…}等々.初心者ゆえの地獄.
- 仮に俺が
assert入りコードを書いたとして……
それを他者が使う場合のことを想像すると(その他者というのも相応に意識低い可能性が濃厚であるから),
「お前のコード,デバッグとリリースとで動きが違(以下略)」とかいう事態を引き起こす地雷に成り得そう. - 「何故かリリースビルドのときだけ動きがおかしい! デバッグビルドだと動くのに!」
- はい…
(4)そこでプログラムを止めたくない場合
これは,ごくごく限られた状況の話でしかないけど……
「明らかに変な動きをしているけど,とりあえず正常に終わらせることはできているし, 正常に終わらせないとまずい」っていうときには, assert 突っ込んで「正常に終わらせる」を阻害しちゃうのではまずいよね.
(後始末処理で物理的に動く何かを安全に止めてる,みたいな)
※static_assert
「定数式のチェック用に static_assert なんてのがあるらしいぞ」ということだけは知ってはいるが,
今のところ自分は使ったことが無いので,これは本稿における「なんでかなー?」の理由には当てはまらない.
まとめ
非常に意識低く過ごしている場合には, assert の出番はほとんど無い(謎の結論!)