【放置ぬるぽ】assert() 濫用【遠い原因】
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNGが、使い方を誤ると却ってデバッグの邪魔になるという諸刃の剣。
素人にはおすすめできない。
0002放置ぬるぽ
NGNG{
HOGESTRUCT *hoge = malloc(sizeof(HOGESTRUCT));
assert(hoge); /*←これで止めたつもりになっているのが痛い*/
memset(hoge, 0, sizeof(HOGESTRUCT));
return hoge;
}
0003デフォルトの名無しさん
NGNG0004遠い原因
NGNG{
assert(hoge);
assert(fuga); /*←このぬるぽ、発生箇所不明*/
/*中略*/
}
0005鉄則
NGNGつまり、本番では放置しても問題ないけどデバッグ時に検出したい条件が
あるときに使うのが正しい。
そうでなければ通常のエラー処理に移行しろ。
2. assert()で止めるなら早めに止めろ。
極力原因の直後で。
それが無理ならその原因が影響しそうなモジュールの初期化部とか。
原因から遠ければ遠いほどデバッグは困難になる。
3. そもそも、ぬるぽ如きでassert()使うな。
絶対に必要なポインタなら通常のエラー処理へ。
なくても困らないものならアクセスせずにスルーできるようなコーディングを。
0006orz
NGNGこんな糞コードにために何度徹夜したことか…ったく。
しかも、リアルタイム処理に多数のassert()や放置ぬるぽが埋まっててまるで地雷原。
で、そのせいで頻繁にオチるからクライアントが怒り狂ってるし。
もう見てらんない _no
以上、出向先に多数のヘボPGを抱える俺の愚痴ですた。
0007デフォルトの名無しさん
NGNGNDEBUGつけてないバージョンをリリースしてるのか。
0008デフォルトの名無しさん
NGNGつーかCやめ。
0009デフォルトの名無しさん
NGNG0010デフォルトの名無しさん
NGNG逆に例外がない言語では積極的に使わないと危険。
内部エラーをエラーコードで返してもswitch/caseでスルーされるだけ。
0011デフォルトの名無しさん
NGNG例外とassertの使い方の違いを知らないようだな。
変な使い方をされたときに発生するのが例外。
変な使い方をするのを検出するのがassert。
0012デフォルトの名無しさん
NGNGだからassertはエラー処理にならないって言ってるのに。
0013デフォルトの名無しさん
NGNG検出させることもできるが試験と本番では出来ないのがassert。
0014デフォルトの名無しさん
NGNGテストではassert有効にするだろw
0015デフォルトの名無しさん
NGNGたとえば範囲をチェックする関数
bool InRange(int n, int min, int max)
でInRange(x, 10, 1)を実行したとき、
C#ならSystem.ArgumentExceptionを投げるようにするけど
Cならassertで止めるね。あんたらならどうするんだ?
0016デフォルトの名無しさん
NGNGn >= min(min, max) && n <= max(min, max)
0017デフォルトの名無しさん
NGNG変な使い方をされた場合は例外。
変化使い方を検出するときはassert。
だから、関数内でのチェックでは例外。
関数呼び出し元で変な使い方をしないように検出するためにassert。
0018デフォルトの名無しさん
NGNG答えになってないな。
具体的に関数のインターフェース・仕様を書いてくれよ。
0019デフォルトの名無しさん
NGNGこれでわからないのか?
面倒だから擬似言語で書くぞ。
{
int min=10;
int max=1;
assert(min<=max);
InRange(x,min,max);
}
bool InRange(int n, int min, int max)
{
if(min<=max) {
return 範囲判定;
} else {
throw ArgumentExceptoin;
}
}
0020デフォルトの名無しさん
NGNG話がずれてるよ。
あんたのC言語版でInRange(x, 10, 1)を実行した場合
InRange内では何をするのかと聞いてるんだよ。
なにもしないの?未定義動作?
0021デフォルトの名無しさん
NGNGInRangeの中では例外発生に決まっているだろ?
それとも例外が存在しない言語で
例外をどう実装するかを聞いているのか?
0022デフォルトの名無しさん
NGNG>それとも例外が存在しない言語で
>例外をどう実装するかを聞いているのか?
そうだよ。
>>10では
例外が存在しない言語では内部エラーの検出にassertを、
存在する言語では例外を使う。
だから例外のある言語ではほぼassert不要と主張したつもりなんだけど。
C#
bool InRange(int n, int min, int max){
if(min>max) throw new ArgumentException();
return 判定;
}
C
bool InRange(int n, int min, int max){
assert(min<=max);
return 判定;
}
0023デフォルトの名無しさん
NGNGだから例外がある言語でもassertは使うだろ。
assertは関数呼び出し側での引数チェックや、
関数内で引数のチェックが終わったあと
(このチェックに引っかかった場合は例外)で、
正常な引数だから正常に処理されるはず。・・・という状態での
関数の内部の処理のバグ検出で使うもの。
0024デフォルトの名無しさん
NGNGそこまで頑強にC言語版の実装を示さないのにはなんか意味あるの?
あんたの原則はもうわかったから早くコードくれよ。
0025デフォルトの名無しさん
NGNGばか?
0026デフォルトの名無しさん
NGNGなんか、頭の不自由な人が多いよね。
0027デフォルトの名無しさん
NGNG試験を本番コードでしないのか?
試験でバグが出たときのデバッグに使えれば使うこともあるが…
>>24
エラーになる可能性があるなら、エラーを通知するインターフェースが
必要なんだよ。グローバル変数でもlongjmpでも何でもいいからインターフェースを
規定する。assertは本番コードには残らないし、残しても制御不能な状態で
落ちるからエラーが起きる可能性のあるところのエラーチェックには使えな
いんだよ。仕様記述のコメント+デバッグ時にチェックがかかるかもしれない
機能がassertionだ。
0029デフォルトの名無しさん
NGNG0030デフォルトの名無しさん
NGNGContract
いまいち流行ってないけどな。DbC。
0031嫌がらせ
NGNGassert(0 && "( ´,_ゝ`)プッ");
0032怪文書
NGNGassert(hoge &&
"あ〜あ、メモリ足りなくなっちゃったよ。あれほど実装量ケチるなといったのに。"
"偉い人の気紛れでできた追加仕様詰め込んだら案の定これだ。"
"俺はこんな奴の尻拭いなんて御免だからもう逃げる。"
"御意見・御要望は090-xxxx-xxxxの偉い人まで。"
);
0033デフォルトの名無しさん
NGNGassert(0 && "(゚Д゚)ハァ?");
0034デフォルトの名無しさん
NGNG似たようなの見たことあるぞw
0035デフォルトの名無しさん
NGNGassert(p && "( ^^) <NullPo");
#endif
0036デフォルトの名無しさん
NGNG0037デフォルトの名無しさん
NGNG動作の違いに基づいて使い分けろ。
0038デフォルトの名無しさん
NGNGい場合はチェックのコードを明示的に書く必要がある。
自分一人で全部作っているなら引数チェックをassertでやっても構わないんじゃ
ないかと思う。
0039デフォルトの名無しさん
NGNG同意。
要は、他人に迷惑をかけるなってこった。
0040デフォルトの名無しさん
NGNGvectorの[]演算子のような、実行時チェック入れると速度半減するから
入れたくないような奴にはassert()が最適な気がするけど
まあでも、それとは別の話で、ヌルポインタだけをチェックすることに
何か意味があるのだろうかと俺は疑問に思ってたな
ヌルポインタは、不正なポインタ(いくらでもありえる)の例の中の
ほんの一つに過ぎない
0041デフォルトの名無しさん
NGNG実行時に起こり得るエラーとバグによるプログラムエラーでは
まるで違う話だ
後者があるものは本来納めちゃいかんだろ
それをなるべく早期に(テスト中に)検出するのがassert()やabort()
の目的なんだから
バグがあっても何となく動くように作りそのようなゴマカシを
残したまま納めるのは正しい姿勢か?
確かにassert()はDEBUG版コンパイルでは機能しない
ならば潔くabort()をつかえ
"バグです"
と言ってしぬのだ
0042デフォルトの名無しさん
NGNG0043デフォルトの名無しさん
NGNG0044デフォルトの名無しさん
NGNGUNIXではabort()で死んでコア吐かせたほうが便利
Windowsのabort()はコアを吐いてくれないような気がするが
わざとGPEを発生させればデバッガが何かしてくれる
DrWatsonしかなくてもダンプファイルは取れる
もともとGPEが発生するようなコードなら、わざわざ手を加えると
かえって原因が分かりにくくなるだけだ
assert()は半端。assert()は用済み。assert()はしつこい。
0045デフォルトの名無しさん
NGNG0046デフォルトの名無しさん
NGNG0047デフォルトの名無しさん
NGNG>>15の例は「範囲をチェックする関数」なのであれば、assert使うのは
間違い
それじゃ、範囲をチェックできないだろ?
isascii()はascii以外の文字を食わせたら落ちるのが正しい仕様か?
「正しい範囲の引数でなければ動作しない。正しい範囲の引数を
渡すのは呼び出し側の責任であり、そうなってないならば
呼び出し側のバグである」というような関数であれば
(例えばポインタを扱う全ての関数はそうだ)
assert()してもいいけど、結局は無駄で余計なおせっかいなだけだ。
0048デフォルトの名無しさん
NGNGなんか勘違いしてない ?
bool InRange(int n, int min, int max) で InRange(100, 1, 10) の時の話なら、あんたの言う通りだけど、InRange(x, 10, 1) だよ ?
InRange() の作成者次第だけど、「min < max で引数を渡すのは呼び出し側の責任であり、そうなってないならば呼び出し側のバグである」と考える奴がいても不思議はないと思うが。
0049デフォルトの名無しさん
NGNGint result;
if(!p)return ERROR_VALUE_FOR_HOGEFUNC;
/*中略*/
return result;
}
int hogefunc_dbg(HOGESTRUCT *p){
if(!p){
fputs("ぬるぽにガッ!!\n",stderr);
abort();
}
return hogefunc_rel(p);
}
で、必要に応じて関数を切り替え。これ最強。
0050デフォルトの名無しさん
NGNG単に、
int hogefunc_rel(HOGESTRUCT *p){
int result;
#if defined(DEBUG)
if(!p){
fputs("ぬるぽにガッ!!\n",stderr);
abort();
}
#endif
if(!p)return ERROR_VALUE_FOR_HOGEFUNC;
/*中略*/
return result;
}
とすりゃすむ話じゃないのか ?
0051デフォルトの名無しさん
NGNGそれだと全体でしか切り替えられないやん。
モジュール書いた本人が使うだけならいいけど、複数人でコード書いてるときは
他のメンバーからしてみれば自分の作業範囲と関係ない強制 abort は邪魔なだけだからね。
呼ぶ側が使いたいところだけ
#define hogefunc hogefunc_dbg
にして使うですよ。
(このケースでは自分でチェックした方が早いけど、実際にはエラー条件が
複雑だったり可変だったりすることもあるんで、そのあたりのツッコミは却下)
…と書いたところで、_rel は付けない方が使い易いと思った。
元に戻すときは #undef だけで済むし。
0052デフォルトの名無しさん
NGNGnullpointerを渡したときの動作は
両方落ちるのは同じで
メッセージを吐くかどうかの違い「だけ」
どのみちコアが吐かれるかデバッガが起動するので
メッセージなんぞ見なくても原因は分かるし
「ぬるぽにガッ!!」などというくだらないメッセージでは
スタックトレースや呼び出し引数等の情報は分からないから
コアやデバッガが提供する情報には叶うべくも無い
最強どころか無駄極まりないコードだな
0053デフォルトの名無しさん
NGNG一応状態のチェックあるいは明示をしておきたい、でもエラー処理は冗長ってときに
適当に入れとく一行ってことでええのん?
だいたい、なぜリリースモードでコンパイルすると削除されるようになってるのか。
残しておけばええやんって気もするんですが。
0054デフォルトの名無しさん
NGNGその使い方でええよ。
削除されるのが嫌なら NDEBUG を定義しなければいい。
0055デフォルトの名無しさん
NGNGこの辺に結論は集約されてる。
>>40
>vectorの[]演算子のような、実行時チェック入れると速度半減するから
>入れたくないような奴にはassert()が最適な気がするけど
>>41
>実行時に起こり得るエラーとバグによるプログラムエラーでは
>まるで違う話だ
>後者があるものは本来納めちゃいかんだろ
>それをなるべく早期に(テスト中に)検出するのがassert()やabort()
>の目的なんだから
0056デフォルトの名無しさん
NGNGそれらのレスはちょっと結論とは言えないくらいに主観の入ったものだと思う。
0057デフォルトの名無しさん
NGNGUnitテストのほうに集中的に使え
0058デフォルトの名無しさん
NGNG例外使え
0059デフォルトの名無しさん
NGNGリリースビルドでは言明した内容を仮定して最適化に役立ててくれればいいのに
とときどき思う。
0060デフォルトの名無しさん
NGNGD言語のassertは言語仕様の一部だから、そういうこともできるかも。
0061デフォルトの名無しさん
NGNG0062デフォルトの名無しさん
NGNG"assert() is a built-in expression primitive. Giving the compiler such knowledge of assert() also enables the optimizer to know about things like the _assert() function never returns."
0063デフォルトの名無しさん
NGNGGCC用語でいうとassertがnoreturnだから、
(eがただの式ならば) _assertもnoreturnになるはずという、
一種のtype inferenceでしょう。
>>59はCommon Lispだと処理系によってはしてる気がする。
0064デフォルトの名無しさん
NGNGそれだけの話ならoptimizerについて言及しないだろう。
>>62の引用元は
「D言語のassertは最適化の対象となり得る(C言語ではそうはならない)」
というのが言いたいんじゃないかな。
0065デフォルトの名無しさん
NGNG>>59のようなのだとするとeを仮定することから"the _assert() function never returns."を導くことになるけど、無理じゃね?
0066デフォルトの名無しさん
NGNGこれを
bool f(int x) { return true; }
こうできるってことかな?
0067デフォルトの名無しさん
NGNG0068デフォルトの名無しさん
NGNGbool InRange(int n, int r1, int r2){
return min(r1, r2) <= n && n <= max(r1, r2);
}
0069デフォルトの名無しさん
NGNGそういうオーバーヘッドを支払いたくないから
InRange(int min, int max)ってインターフェースで話を進めてるんだろ。
0070デフォルトの名無しさん
NGNGこの本にassertの使い方のってます。けっこういい本です。
0071デフォルトの名無しさん
NGNG今年の流行語で、あなたが一番印象に残ったのは?
●現在の集計結果です
http://cgi.news.fs.biglobe.ne.jp/vote/no384/vote_result.cgi
0072デフォルトの名無しさん
NGNG> たくさんのテストプログラムがあるのはなぜ?
>
> テストが好きだからです。testsディレクトリにテストスイートを揃えています。
> make check でテストできます。リファクタリング で述べられているソフトウェア
> 開発手法に従っています。 Suffix Arrayの操作にはたくさんのきわどい境界条件
> を要するため、厳格なテストは不可欠です。また、やっかいなバグを防ぐために
> g_assert を多用しています。
0073デフォルトの名無しさん
NGNG外部要因で起き得る例外なら例外じゃないの?
0074デフォルトの名無しさん
NGNGだよね。
0075デフォルトの名無しさん
NGNG0076デフォルトの名無しさん
NGNGassertの後についでに例外もはさむべきだと思う。
人間がやっている以上コードもテストも100%というわけには行かない。
assertだとたいていスタックトレースは残らないから
デバッグしたくても情報が足りないことが多い。
0077デフォルトの名無しさん
NGNGそれはパフォーマンスに対する要求も考慮して決めないといけないだろう。
0078デフォルトの名無しさん
NGNGイミネー
だったら例外投げるだけで十分。
0079デフォルトの名無しさん
NGNG俺も自分で書いてから思った。
まったく意味ねぇ。
なんかどうしてもassert使いたそうな人が居たもんで。
0080デフォルトの名無しさん
NGNG0081デフォルトの名無しさん
NGNGデバッグ用途には例外とloggerがメイン。
0082デフォルトの名無しさん
NGNG0083デフォルトの名無しさん
NGNGassert( p->Release() );
0084デフォルトの名無しさん
NGNGUNIXならasertがabort呼ぶだろ.
0085デフォルトの名無しさん
05/02/12 00:08:21UnitTestでブラックボックステストを行い、さらにテストターゲット中のassertに引っかからない
ことを確認することでホワイトボックステストを行うとさらに品質Up。
0086デフォルトの名無しさん
05/03/11 05:06:21早い話がassertのススメ。
0087デフォルトの名無しさん
05/03/11 23:20:41ソースきぼん
0088デフォルトの名無しさん
05/03/12 10:16:020089デフォルトの名無しさん
2005/05/16(月) 20:27:25(.*´ー`)、 148乙。俺はまだ当たっ (_ *%゚O(゙) でも俺は148が当たって心から喜べる。
/`ヽ,)/| おまいは月たんの婿にふさわしい。俺が認める。
(_/ i,_ノ これから月たんを慈しみ守り通してくれよな。おめでとう148。
0090デフォルトの名無しさん
2005/05/16(月) 20:27:47(.*´ー`)、 148乙。俺はまだ当たってない。
(_ *%゚O(゙) でも俺は148が当たって心から喜べる。
/`ヽ,)/| おまいは月たんの婿にふさわしい。俺が認める。
(_/ i,_ノ これから月たんを慈しみ守り通してくれよな。おめでとう148。
■ このスレッドは過去ログ倉庫に格納されています