1 名前:仕様書無しさん mailto:sage [2007/04/02(月) 12:45:06 ] この会社辞めようと思ったソースコード。 プログラマとして幻滅するソースコード。 プログラマを悩ませるソースコード。 をつらつらと綴っていって頂戴。 ちなみにここは質問スレじゃないので 技術的な質問がしたいならム板 pc11.2ch.net/tech/ に逝って。 前スレ この会社辞めようと思ったソースコード#15 pc11.2ch.net/test/read.cgi/prog/1167117526/
251 名前:仕様書無しさん mailto:sage [2007/05/16(水) 20:44:09 ] じゃあ、Cで短絡評価は使わないってこと?
252 名前:仕様書無しさん mailto:sage [2007/05/16(水) 20:50:09 ] >>251 C・C++は別格
253 名前:仕様書無しさん mailto:sage [2007/05/16(水) 20:51:54 ] >>251 短絡的な発想だな
254 名前:仕様書無しさん mailto:sage [2007/05/16(水) 20:57:30 ] >>253 だれがうまいこと言えとwww
255 名前:仕様書無しさん mailto:sage [2007/05/17(木) 11:43:10 ] >>250 言語が変わったら、同じ書き方は出来ないと思うんだが。
256 名前:仕様書無しさん mailto:sage [2007/05/17(木) 12:56:49 ] >>255 なにその柔軟すぎる発想 お前PGとかこの業界やめたほうがいいよ それとも釣りですか?
257 名前:仕様書無しさん mailto:sage [2007/05/17(木) 14:00:51 ] >>256 「同じ言語で、同じ書き方をして、違う動作をするような書き方」 であれば、しないのが当たり前。素人じゃあるまいし。
258 名前:仕様書無しさん [2007/05/17(木) 14:17:15 ] >>257 日本語嫁よwwwwww
259 名前:仕様書無しさん mailto:sage [2007/05/17(木) 14:53:11 ] おいおい COBOLでかちゅーしゃ作れねーだろ
260 名前:仕様書無しさん mailto:sage [2007/05/17(木) 15:32:20 ] .netコボルならできるんじゃね?
261 名前:仕様書無しさん [2007/05/17(木) 15:42:57 ] COBOLでJavaのVM作ればOK。
262 名前:仕様書無しさん [2007/05/17(木) 16:12:45 ] Valiantをブリリアントと読んでいた。 そんな時期もありました。
263 名前:仕様書無しさん mailto:sage [2007/05/17(木) 17:02:51 ] ━━ a. 勇敢な. ひょっとして: variant valiantly Valerian
264 名前:仕様書無しさん mailto:sage [2007/05/17(木) 17:58:31 ] 今年入社した会社のコード if(《BOOL型変数》!= TRUE) { }else { 処理; } もっと簡潔に書いてくれ・・・
265 名前:仕様書無しさん mailto:sage [2007/05/17(木) 18:14:47 ] BOOLというのが実は独自定義の真偽値型で、 TRUE==0でそれ以外がFALSEだとか?
266 名前:仕様書無しさん mailto:sage [2007/05/17(木) 18:15:54 ] >>264 既出のものかと思いきや応用編か……。
267 名前:仕様書無しさん mailto:sage [2007/05/17(木) 18:48:13 ] >>265 それにしたってブロックからっぽにするんだったら 条件ひっくりかえしてelse削除でしょう。
268 名前:仕様書無しさん mailto:sage [2007/05/17(木) 18:52:06 ] >>267 ご指摘の通りだけど。else部分は省略禁止という規約も実在するしw
269 名前:仕様書無しさん mailto:sage [2007/05/17(木) 19:07:26 ] いや、条件に一致した場合の処理も後で書き加える可能性があるとか。 コメント残せよって話だけど。
270 名前:仕様書無しさん mailto:sage [2007/05/17(木) 19:39:21 ] Dim bFlag As Boolean = False If bHoge Then bFlag = True If bMoge Then bFlag = True If bNuge Then bFlag = True If bHage Then bFlag = True : : If bFlag = False Then CB.Checked = True なんつーか、下っ手くそなコードだなあ…
271 名前:仕様書無しさん mailto:sage [2007/05/17(木) 22:03:48 ] 真偽定数と比較する奴ウザイ。
272 名前:仕様書無しさん mailto:sage [2007/05/17(木) 22:30:17 ] おれ明示的に描くようにしてるわ
273 名前:仕様書無しさん mailto:sage [2007/05/17(木) 22:50:57 ] 真偽値と比較するのならなぜその結果をさらに真偽値と比較しないのか。 そしてその結果をさらに……
274 名前:仕様書無しさん mailto:sage [2007/05/18(金) 00:13:13 ] >>270 こういう、似たような処理をひたすら羅列して、ウォーリーを探せみたいな ソース書いてる人って、どんな気持ちで書いてるんだろう?
275 名前:仕様書無しさん mailto:sage [2007/05/18(金) 00:14:06 ] あーめんどくせー
276 名前:仕様書無しさん mailto:sage [2007/05/18(金) 01:57:47 ] >275 きっと本気でそう思ってるんだろうなぁ…… 恐らく「コピペでガンガンコードが書けて俺様ってば超Cool!!」とは思ってない気がする
277 名前:仕様書無しさん mailto:sage [2007/05/18(金) 07:36:40 ] コピペでコード書くのは全くCoolでない件
278 名前:仕様書無しさん mailto:sage [2007/05/18(金) 08:12:42 ] >>277 おまけにバグまでコピッてるのを見ると殴り殺したくなる。 こういう時はgrepするとワラワラと湧いてくるんだよな。orz
279 名前:仕様書無しさん mailto:sage [2007/05/18(金) 09:16:43 ] >>276 しかしどこぞの馬鹿に言わせると 馬鹿でも理解できるため良質なコードということになる。 良質なコードを生み出すことが超Coolでないわけなかろう。
280 名前:仕様書無しさん mailto:sage [2007/05/18(金) 09:26:30 ] 正しくは「馬鹿だけ」が最小コストで理解できるコードだろ
281 名前:仕様書無しさん mailto:sage [2007/05/18(金) 09:31:22 ] >280 何か問題でも?
282 名前:仕様書無しさん mailto:sage [2007/05/18(金) 09:41:40 ] >>281 一般人には理解できないコードなのだが。
283 名前:仕様書無しさん mailto:sage [2007/05/18(金) 09:46:16 ] 自分が一般人に含まれると勘違いしているのはイタさ倍増
284 名前:仕様書無しさん mailto:sage [2007/05/18(金) 10:26:37 ] 多分、板住民同士でレビューしたら自称一般人だらけだろうなw 自分の知識が普通とか一般だと思うのは非常に危険だぞ。
285 名前:仕様書無しさん [2007/05/18(金) 11:19:51 ] >>274 ステップ単価だったりして。 ステップ単価の文化に浸った人はコピペ多いよなぁ。
286 名前:仕様書無しさん mailto:sage [2007/05/18(金) 17:23:52 ] 人月の狼
287 名前:仕様書無しさん [2007/05/18(金) 17:25:39 ] ほら吹き狼
288 名前:仕様書無しさん mailto:sage [2007/05/18(金) 19:41:19 ] >>270 こういうふうに書き換えるのは、上手普通下手で言えばどれですかね? Dim bFlag As Boolean = False If (bHoge Or bMoge Or bNuge Or bHage Or ...) Then bFlag = True End if If Not bFlag Then CB.Checked = True 他の人のコード見て勉強する機会があまりないので。 270は、どれか1つのフラグがいらなくなったら1行削ればいいので、 案外上手なのかもしれんと思いました
289 名前:仕様書無しさん mailto:sage [2007/05/18(金) 19:56:25 ] Dim bFlag As Boolean = False If (False _ Or bHoge _ Or bMoge _ Or bNuge _ Or bHage _ Or ..._ ) Then bFlag = True End if
290 名前:288 mailto:sage [2007/05/18(金) 20:11:38 ] >>289 ナルホド、これなら1行で消せますね。 他のコードで同じ書き方してました。 If 条件式でやるのはためらいますが。
291 名前:仕様書無しさん mailto:sage [2007/05/18(金) 20:52:54 ] hogeとかmageをセットしてるコードのほうが気になる。
292 名前:仕様書無しさん mailto:sage [2007/05/18(金) 23:47:38 ] 自分はVB(でしょ?)知らないんだけど bFlag = bHoge Or bMoge Or bNuge Or bHage Or ... とは書けないの?
293 名前:仕様書無しさん mailto:sage [2007/05/19(土) 00:04:03 ] そこまで分岐するならビット演算とかどうよ?
294 名前:仕様書無しさん mailto:sage [2007/05/19(土) 01:06:41 ] VBScript環境やまして.netはよー知らんが、レガシVBとかVBAでは s = "hogehoge" _ '& "piyopiyo" _ & "fugafuga" は文法エラーということを忘れてる人はおらんか。 いや忘れていいなら忘れてしまいたい貴方♪だが。 >292 書けるお。
295 名前:仕様書無しさん mailto:sage [2007/05/19(土) 02:05:39 ] >>288 cb.checked = cb.checked Or ( Not ( _ bHoge _ Or bHage _ Or bHuge _ : ) )
296 名前:仕様書無しさん mailto:sage [2007/05/19(土) 02:28:24 ] C言語で。 typedef void (*func)(void); ・ ・中略 ・ func pFunc = (func)0x00010000; pFunc(); 辞めよう、とまでは思わないが、組み込みってこえぇ、と思った。 他には void free(struct Data *pstData){ struct Memory *pstMemory; if(pstData==NULL)return; pstMemory = (struct Memory *)(((char *)pstData) - sizeof(struct Header)); pstMemory->stHeader.nUsed = 0; } とか value = array[-2]; とか 自分が今まで覚えてきたことを色々否定された気分になった。
297 名前:仕様書無しさん mailto:sage [2007/05/19(土) 02:49:14 ] >>296 俺も怖い。組み込みは鬼門と考えるようにする。
298 名前:仕様書無しさん mailto:sage [2007/05/19(土) 02:56:53 ] >>296 スマン。 2つ目のやつの問題点を教えてくれ。 これよくあったよ・・・@携帯電話の網の中の人
299 名前:仕様書無しさん mailto:sage [2007/05/19(土) 03:10:34 ] というか普通のfreeも大雑把に見ると>>296 の二つ目みたいなもんだ。
300 名前:仕様書無しさん [2007/05/19(土) 03:15:26 ] せめて (uintptr_t)pstData - (unsigned)(&(((Memory*)0)->データ)); にできないかねぇ。
301 名前:仕様書無しさん mailto:sage [2007/05/19(土) 03:20:18 ] >>298 プログラム全体で見ると整合性が取れてるんだけど、 free関数単体で見ると、引数pstDataからさらに前のアドレスってことは 一見アクセス出来る範囲外のアドレスを叩いてるように見える。 極端な話すると int main(int argc, char *argv[]) { char *str = argv[-1]; printf("%s\n",str); return 0; } みたいなコトをしてるように見えるわけだ。
302 名前:仕様書無しさん mailto:sage [2007/05/19(土) 03:29:37 ] >>300 うは・・・。 構造体のアライメントを運用で気ぃつけるとかはあったけど、 そういう発想は無かったな・・・。 さんきぅ。参考になります。
303 名前:仕様書無しさん mailto:sage [2007/05/19(土) 08:47:17 ] >>296 value = array[-2]; これの動作は未定義なのでは?
304 名前:仕様書無しさん mailto:sage [2007/05/19(土) 08:56:50 ] バグ、それも謎の挙動が多いと評判最悪のシステムのメンテを担当する事になった。 普通に順繰りに実行すればいい処理1〜3をわざわざ for(i=1; i<=3; i++){ switch (i){ case 1 : 処理1 case 2 : 処理2 case 3 : 処理3 } } みたいな謎のロジックで実行していたりしてアタマ痛い…他にも char *hoge(char *s, const char *ct, int n){ if n==0{ strcpy(s, ct); } else { strcat(s, ct); } retuen s; } を遥かに大規模にしたような、標準関数を1つに纏めて、引数で実行する関数を 選択するようなのもあって、作った本人はかなり自慢げに 「これで標準関数を覚える必要が無くなり、ソースの可読性も増した」と 94年当時の日付入りでコメントを残しているんだが、 その問題の関数の前後で情け容赦なく素でstrcpyとか使われていて、 もう何が何だが・・・ リファインして良いか責任者に聞いたら、結構重要な部分だから、 汚いソースでも動いている以上手直し不可だって。
305 名前:仕様書無しさん mailto:sage [2007/05/19(土) 09:11:22 ] >>304 上はよく見る。 下もよく見・・・るわけねえええええ
306 名前:仕様書無しさん mailto:sage [2007/05/19(土) 09:13:56 ] >>304 上は各処理の後にbreak;はあるの? あったらただの馬鹿だな。
307 名前:仕様書無しさん mailto:sage [2007/05/19(土) 09:14:24 ] >>304 Fの仕事の後では全然なんでもないと感じる。 やつら車輪の再発明大好きで、標準関数同等品の再開発はもちろん、 それを作ったのが同じF内でも課が違えば、自分ところで再開発するからな。 一つのシステムに同じ機能が何箇所も独立してコーディングされてて、 成績上位者が軒並み逃げるのも判る気がする、と思った。
308 名前:仕様書無しさん mailto:sage [2007/05/19(土) 09:33:28 ] >306 >上は各処理の後にbreak;はあるの? 実はある…orz 完璧、思いつきで組んでみた的な無駄なロジックいっぱい。 一つの関数内でローカル変数を初めはインデックスカウンタ、 下の方では値の交換のための受け皿に使ってたりもするし。
309 名前:仕様書無しさん mailto:sage [2007/05/19(土) 09:57:15 ] >>308 >一つの関数内でローカル変数を初めはインデックスカウンタ、 >下の方では値の交換のための受け皿に使ってたりもするし。 この誘惑に駆られちゃうことがあるな… 新しい目的のローカル変数が欲しいんだけど、既にいくつものローカル変数があって 新しく宣言するのは気が引ける時とか。 「おやこの変数この処理の後は使ってないや、使っちゃえ」って感じで。 保守を優先するなら、目的が違えば新しく宣言すべき?(規約にもよるだろうけど、一般論として)
310 名前:仕様書無しさん mailto:sage [2007/05/19(土) 10:28:46 ] >>309 > 保守を優先するなら、目的が違えば新しく宣言すべき?(規約にもよるだろうけど、一般論として) 当然だ。 ローカル変数多すぎってのは、リファクタリングの必要がある可能性があるよ。
311 名前:仕様書無しさん mailto:sage [2007/05/19(土) 11:06:29 ] クソみたいなソースをリファインするのは我慢できるが、 クソみたいなソースと付き合うのは苦痛だな。
312 名前:仕様書無しさん mailto:sage [2007/05/19(土) 11:34:09 ] >>309 確認したいが。 その関数内のローカル変数の現在の個数はいくつか? (一般論を知りたいか?w)
313 名前:仕様書無しさん mailto:sage [2007/05/19(土) 11:53:02 ] >>309 ジジイみたいに関数の先頭でどっさり宣言するからだろ。 スコープ絞って宣言すれば、ほとんどそんなことにはならん。
314 名前:仕様書無しさん mailto:sage [2007/05/19(土) 12:23:41 ] >296 freeってそんなもんでしょ。組み込みじゃなくても GNU libcのmalloc/freeはもっとスゴイ、という話を聞くけど。
315 名前:仕様書無しさん mailto:sage [2007/05/19(土) 12:34:29 ] >>312 10個かな。 2次元矩形の現在の開始〜終了座標と更新前の同座標を保持する必要があって、 元データの構造体1個と、それぞれ単独変数に追い出した4個×2で9個。 それに、問題の変数1個。他にもあったかも。 単独変数に追い出した4個×2はなくてもいいと思うんだけど、それないとコード追いにくいって メンバがいるもんで、残してる。 リファクタリングの精神忘れてました。ありがと。見直してみる。
316 名前:仕様書無しさん mailto:sage [2007/05/19(土) 12:45:31 ] >>314 組み込みじゃなければmalloc/freeを使えば良いわけで。
317 名前:仕様書無しさん mailto:sage [2007/05/19(土) 12:55:01 ] そういや昔居た会社での事。 引数の数が8個9個が当たり前で、うち6個はどの関数でもやり取りされてるから、 「構造体にまとめませんか?」って提案したら、「難しくなるから駄目」って却下。 やたら構造体とかポインタだとかに拒絶反応のあるところだった。
318 名前:仕様書無しさん mailto:sage [2007/05/19(土) 13:03:11 ] >>306 >>304 の上の処理はbreakが あるかないかよりもswitchの後に続く処理が あるかないかが重要なんでは?
319 名前:仕様書無しさん mailto:sage [2007/05/19(土) 13:05:28 ] >>296 malloc/free周りは基本はそんなかんじでしょ。 俺も自作したとき、似たようなコード書いた。
320 名前:仕様書無しさん mailto:sage [2007/05/19(土) 13:13:34 ] >>309 俺は、単純なカウンタ変数やインデックスの 受け皿の変数は使いまわしてもいいと思う。 例えば int i, j, k; を意味ごとに int hoge_i; みたいに名前を変えたくないしな。
321 名前:仕様書無しさん [2007/05/19(土) 13:18:12 ] そんな素人コーディングだめだろ 俺等のところ同じようにしろ int int_id_0000001, int_id_0000002, int_id_00000003 こうやって全部定義すれば仕様書みれば全部意味がわかる
322 名前:仕様書無しさん mailto:sage [2007/05/19(土) 13:52:56 ] >320 必要な時にブロックを生成して、なかで int iを幾らでも定義すりゃいいじゃん。
323 名前:仕様書無しさん mailto:sage [2007/05/19(土) 13:58:09 ] >>309 グローバル変数として宣言すれば、宣言は1回で済むぞ。 同じものを幾らでも使いまわせる。 これは便利。覚えておけ。
324 名前:仕様書無しさん mailto:sage [2007/05/19(土) 14:53:47 ] 後輩がそのパターンをやてってくれて頭抱えてるんだが。 学歴あってもセンスないやつはダメだ('A`)
325 名前:仕様書無しさん mailto:sage [2007/05/19(土) 14:57:01 ] >>323 そういう時は、自分で同じパターンの 読みにくいコードを書いてやって、 後輩に読ませれてみればよい。
326 名前:仕様書無しさん mailto:sage [2007/05/19(土) 15:04:14 ] 本人はそれがわかりやすいと思って書いてるんだから 意図が理解できるはずもない
327 名前:仕様書無しさん mailto:sage [2007/05/19(土) 15:09:48 ] 仮に>>324 みたいな事をやって、 そいつがそのソースを即理解できたのなら、 文句ないんじゃねえの? だって本当に分かり易かったんだろ?
328 名前:仕様書無しさん mailto:sage [2007/05/19(土) 15:12:24 ] とりあえずLispとかPrologとかマイナー系言語で書いて 「俺には判りやすいんだからいいだろ」といっとけ
329 名前:仕様書無しさん mailto:sage [2007/05/19(土) 15:29:50 ] >>327 自分が見て分かり易いかどうかより、 他人が見て分かり易いかどうかの方が重要なんじゃないか?
330 名前:仕様書無しさん mailto:sage [2007/05/19(土) 15:32:20 ] 「俺はいつも"他人が見て分かり易いコード"を書くように努めている」 という奴に限って糞コードを書く件について、どう思う?
331 名前:仕様書無しさん mailto:sage [2007/05/19(土) 16:10:17 ] >330 そこの会社のわかりやすいコードのレベル=クソコードなだけ。 書いているうちにそれしかかけなくなる罠
332 名前:仕様書無しさん mailto:sage [2007/05/19(土) 16:31:38 ] みんないろいろなコメントありがとう。一般論もっと聞けるとうれしいけど。 >>320 i, j, k で思い出した。 漏れは i と j がぱっと見た目で区別しづらいことがあるから、 一文字変数は i, k, m, n, x, y, z, a, b みたいに、区別しやすい飛び飛びの アルファベット使ってる。l も大文字の I と混乱すると嫌だから使わない。 i, j, k のように一文字アルファベット連続で使うのは、どんな理由があるのかな?
333 名前:仕様書無しさん mailto:sage [2007/05/19(土) 16:33:59 ] >>323 遠慮しときます。 ウッカリ、ある関数で使った後にもかかわらず別の関数で以前の値を保持しているつもりで 使おうとする実装をやってしまって、デバッグで痛い目にあったことがある。
334 名前:仕様書無しさん mailto:sage [2007/05/19(土) 16:41:27 ] >>332 大昔のFOTRANでI,J,K,L,M,Nで始まる変数は宣言なしで整数型になったから
335 名前:仕様書無しさん mailto:sage [2007/05/19(土) 16:53:02 ] >>334 とてもためになりました、ありがとうございます。 会社に入ってから勉強した文系プログラマなのでこうした基礎教養がないです。
336 名前:仕様書無しさん mailto:sage [2007/05/19(土) 17:13:00 ] N M Σ Σ Aij i=0 j=0 こっちの法の使い方がもとだとおもうけどねー
337 名前:仕様書無しさん mailto:sage [2007/05/19(土) 17:19:11 ] 元来FORTRAN(FORmula TRANslation)ってのは数式の処理目的だから当然だな
338 名前:仕様書無しさん mailto:sage [2007/05/19(土) 17:25:33 ] 飛び飛びって初めて見たな。 それはそれで激しく嫌だ。
339 名前:仕様書無しさん mailto:sage [2007/05/19(土) 17:28:06 ] >>336 そして数式でiから始まる文字を使うのはiがindex(添え字)の頭文字だからだろうか。 iterationのiだと主張してる人もいたが数学に元を辿ると違いそうだなぁ。
340 名前:仕様書無しさん mailto:sage [2007/05/19(土) 17:32:41 ] 元FORTRAN屋なんて自分以外には何人生き残ってるか知らんが、 いまだにi〜nで始まる変数名を見ると「整数型」と思ってしまう。 たぶん、一生治らんなw
341 名前:仕様書無しさん mailto:sage [2007/05/19(土) 17:44:36 ] index j k length m number 一文字変数ならi〜nは整数だと感じる
342 名前:仕様書無しさん mailto:sage [2007/05/19(土) 18:26:05 ] それは普通だろ。 むしろ、「倍精度実数型」や「文字列型」とか定数のiを作るほうがどうかしてる。 何でうちの会社はこういうのがいるんだろう…。難読化か?
343 名前:仕様書無しさん mailto:sage [2007/05/19(土) 18:33:01 ] 逆にaやbが整数だと気持悪い
344 名前:仕様書無しさん mailto:sage [2007/05/19(土) 21:20:44 ] >>338 漏れもすっきりしてるわけでありません。 i と j を打ち間違えてチェックに時間をとられたり、i I と l の区別に一瞬 ためらうことがあるので、そういうところで時間ロスしたくないと思って、 ぱっと見ても視認しやすい文字だけ使うようになりました。 皆さんはそういうことないですか? 漏れが下手なんでしょうね。
345 名前:仕様書無しさん mailto:sage [2007/05/19(土) 21:58:25 ] >>344 そーゆー時はフォントを書き換えると良いよ
346 名前:仕様書無しさん mailto:sage [2007/05/19(土) 21:59:34 ] >>344 うちのコーディング規約では、そもそも1文字の変数名が禁止。 それと意味の無い変数名も禁止。 例えば表を処理する二元配列のループ回すカウンタとかなら、 int nCntRaw,nCntCol; とかになるかな。
347 名前:仕様書無しさん mailto:sage [2007/05/19(土) 22:13:21 ] >>345 そういう意見出ると思ってました。 開発環境が固定されてなくて、設定を持ち歩いたり、いちいちフォントを設定しなおすのが 面倒なんです。 使える開発環境のデフォルトの設定ですぐ読めるコードを優先してます。 >>346 普段は漏れもそうです。一文字変数は、ループカウンタのような限定された状況だけですね。 こんな感じ。 for ( i = nStartRow; i <= nEndRow; i++ ) { for ( k = nStartCol; k <= nEndCol; k++ ) {
348 名前:仕様書無しさん mailto:sage [2007/05/19(土) 22:17:07 ] 寿命の短かったり重要でない、変数名が短いほうがいい。 ソースがうるさくなる。
349 名前:仕様書無しさん mailto:sage [2007/05/19(土) 22:19:17 ] >意味の無い変数名 だったら nXXXXって意味ないからやめろ int CntRaw,CntCol; でおけ
350 名前:仕様書無しさん [2007/05/19(土) 22:21:05 ] int CR, CCでいいじゃん
351 名前:仕様書無しさん mailto:sage [2007/05/19(土) 22:24:06 ] >>349 あー、説明不足で申し訳ナス。 メインC言語なんだが、「決まったプリフィクス」をつけることになってんだ。 癖でつけてしもた。 例えばこんなのが変数の先頭に付く int → n char → c void * → p int * → pn 構造体 → st 列挙型 → e グローバル変数 g_