今までみた絶望的なソースコード [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
今井氏:ソースコード公開は、社長のティム(*2)の意向です。彼はバリバリのプログラマーで、初期の「Unreal Engine 1」を
1人で書いた人ですが、若い時に雑誌に載っていたコードを書き写して勉強したそうです。それで今の若い人にも、プロのソー
コードとはこういうものだというのを見せたいという願いがあって、ソースコードを公開しています。本当に今のゲーム業界の
事情を憂いてる1人だと思います。(*2)Epic Gamesの創業者兼CEOであるTim Sweeney氏
出村氏:読みやすいコードですよ。「C++」というのは、黒魔術(高度な計算)が多くなりがちな言語ですが、
そういうこともなく、すっきりしていて目的の機能も探しやすい。解読しやすいコードなので、確かにお手本になると思います。
僕は初代のゲームボーイからプレイステーション 2の頃くらいまでゲームプログラマーだったのですが、ゲームプログラミングでは
必ず数学が出てきます。行列とか三角関数とか。もちろん今でもまったく不要になったわけではありませんが、そういう知識の
重要性は薄れてきていると思います。「Unreal Engine」では特にそうです。
http://game.watch.impress.co.jp/docs/interview/20150417_698349.html
初級者から中級者へ昇格する時期は、ほぼどのようなソースコードでも読める程度にプログラミング言語に精通し、
また偉いプログラマーの提唱したデザインパターンも一通り理解したくらいの時期である。
すると、プログラミング言語の持つあらゆる機能と、偉いプログラマーの提唱するあらゆる技術を使わねばならない
という思い込みが発生する。そしてHello Worldにまで崇高なオブジェクト指向や壮大なデザインパターンを
適用しようとしだすのである。
その結果、
* 大量のクラス
* 迷路のような変数渡し
* 底なしに深いネスト
などといった凄いものが生まれる。また、条件分岐に三項演算子を乱用するなどの症状も多く見受けられる。
最終的には第三者にとって読みにくい保守性の悪いスパゲッティコードが生成されることになる。
http://monobook.org/wiki/%E4%B8%AD%E7%B4%9A%E8%80%85%E7%97%85 >>384
例えば時間のかかるデータ取得が100個あるとする
速度重視の場合早い時点でスレッド作って先行処理しておく
実際値使う箇所では中でスレッド待ちしていてなんでわけわからないことやってるんだと言われる
データなんてGet回すだけだろと
アルゴリズム難解といえば自前のHashMapは最初わからんかった
文字列足しこんでへんなビット演算やって
コメントもなかったからあれはなかなか理解されない >>388
スレッド使えるなんて羨ましい
こっちは標準Cライブラリどころかcrtすら使わせて貰えないから
RAMをクリアしてmain関数を自分で起こすところから書かなきゃいけない絶望的な状況 >>389
組み込み系?
クラスも使えずレジスタがどうだとかリソース最小限に留めるとか無理だわ
基本は作りやすさ重視で必要に応じてチューニングが1番仕事しやすい >>388
だからそれ、アルゴリズム変わってるじゃん。
馬鹿なの? クソソース書いといてその言い訳に速度重視とかザコ過ぎない?
お前が速度なんて語るの百年早いのはそのクソソースに丸出しなわけで
よくあんなクソソース書いててそんな態度取れるなっていう不思議な子知ってる >>386
おまえは一生ソートに可読性の高いバブルソートでも使ってろよ >>391
アルゴリズム同一でと言った覚えないんだが?
むしろアルゴリズム同一で速度が飛躍的に上げれるならマジで教えて欲しいが 16進数やビット演算とか使ってるコードは見にくいからクソソースでいいですか? >>395
何進数だろうが関数内にマジックナンバーは入れちゃダメだろうね
定数かマクロにして実行部とは分けて宣言・定義するようにしてるよ じゃあ何進数だったらマジックナンバー使っていいんだよ! 「定数は定義して使え」に対して
#define value_1 (1)
#define value_2 (2)
とかいう馬鹿もいるんだよな #define value_one (1)
#define value_two (2)
これなら大丈夫(キリッ #define ZERO 1
はGNUで見たことある。 マジックナンバーは基本だが定数を使った判定をあちこちに書かないことも重要
例えばファイルの存在チェックでファイルのビットフラグ立ってないことで判定
しかしフォルダも除外したい等仕様変更が予想される
その度多数の修正を入れるのは危険
isExist()などでラップして判定処理は1箇所にすると変更に強くテストも楽 マジックナンバーは必要悪でしょ。
周知されてて、全体で統一されてたら何も文句無いけどな。
日時未定を29991231で持ってるシステムに関わってたけど。
特定のビットが立ってないことと、ファイルの有無と、ディレクトリであるか否かはまた別問題ではないのだろうか。
isExistなのに、ディレクトリ除外しちゃうの?ライブラリなのに外から見た挙動変えちゃうの?って不安のほうが大きい。
そんなもんで判定せずに、判定箇所で切り分けるか、旧関数自体をassertで殺す方がマシ。
その度に多数の修正は躊躇なく入れるべき。
挙動を変えるのに、変えた意識が無い方が、
あり得ないくらい誰も原因に気づかない、どハマりする障害を起こす元。 >>404
例が悪かったからマイナンバー導入を例にする
従来は同一判定をequal()で中身は住所と指名で判定してたとしよう
この場合マイナンバー対応は中身をID比較にすればそれだけで対応完了
これが比較箇所に直接住所と氏名の比較を行っていた場合修正は時間がかかる
修正ソース毎にドキュメント書かないといけないプロジェクトでは発狂もの
言いたいのはやりたいことを外に出して実現手段は中に閉じ込めろってこと
要はカプセル化だが簡単なものだと忘れられることがよくある >>405
ダメ。
名前と住所で比較するロジックと、
マイナンバーで比較するロジックは別物。
それだけで対応完了にならないよ。
それでは、既存の比較するロジック全部洗って、それ呼んでる所を全部テストせなならん。
普通は、呼び出し側ソース修正と同じかそれ以上になるんだよ、ライブラリの挙動変更に対するドキュメントとテストって。
やりたい事をカプセル化するライブラリの、内部挙動が変わったらそれは最早カプセル化されてないとしか言いようが無い。
名前と住所ってのは、ユニークになるとは限らない情報だし、逆に歴なんか持ってたら2つ以上のレコードが一つを指すかもしれないレコードになるでしょ。
今まで同じだったけど今回からは違う人(田中一郎さんが昔住んでて、引っ越した後、今は別の田中一郎さんが住んでる)、や
今まで違う人だったけど、今回からは同じ人(同じ住所だけど、結婚して姓が変わってる)が出る改修はカプセル化失敗としか言えない。
まさにそういうシステム作ってたけど、「同一人物っぽい人」としか言えないから、警告しか出してない。
内部発番のシリアルのIDを比較していた所を、マイナンバーでひっかけるようにする、位の変更くらいじゃないの?その変更が通用するのは。
それでもパターンテストは必要。
呼び出し側を修正して、きちんと新しい関数が呼ばれている所からがテストのスタート地点。
修正ソース毎にドキュメントなんか普通作るよね。
波及コードだけどローレベルで担保されてるから大丈夫。は通用しない。
現実手段を閉じ込めるのは、同じ動きをする事が大前提。 >>406
理想はそうだけど現実解じゃないよそれ。 いつのまに絶望的なコーディング論を紹介するスレになったのか >>404
#define DATE_UNDEFINED 29991231
みたいな感じにマクロ化してあればいいだけじゃん?
マジックナンバーで許されるのは0と1くらいだと思う UNREFFERENCE_PARAM(hCurInst)とかいう無意味マクロまーじ >>406
また言葉足らずだったが話の前提として住所と氏名でユニークキーになる場合の話
勿論結果が修正前と異なるようなら別のメソッドにしたり置き換えたりが必要
あとソース修正毎にドキュメント作るのは金融くらいしか聞かない
テスト自動化してればシナリオ流して終わり
必要以上に金かけるよりほぼ間違いないでコスト削減が今の主流だと思う
スマホゲームでメンテ後に即メンテとかよくあるだろw >>413
医療だけど、特殊例だったのか。
だとすると、医療でそういう運用してても出る障害考えたら、世の中のプログラマは一体どんな気持ちでプログラムしてるかわからんな。
必要以上に金かけずにコスト削減して、障害出したら、それは必要な金だったんじゃねーかなぁ。 >>414
なるほど医療か
医療は周りにいなかったからわからなかった
医療だと慎重にならざるを得ないがバグ出ても修正すれば問題ない分野はそんなにテストに時間をかけない
毎回手動テストしてリリースするより自動テストでバグ出たら修正のほうがトータルコストはかからない
リリース優先か品質優先かは分野で全く異なる
ゲームで慎重なテストで時間使ってたら首飛ぶし逆もまた然り あと金の話だけどリリース時期は作る前から決まってる
そこがずらせないとなればバグのリスクとってもリリースを優先しないといけない
もしくは機能のそぎ落とし
3末リリースが遅れると決算への影響が大きいとかいろいろ事情がある
バグは出るものだからリリース後に改修すればいい
なかなか思ったとおりに仕事できないのは世の中の常w 自動車とか産業機械とか医療は厳しいよね。
バグ流出したら普通に人が死ぬからなあ。 絶望的なソースコードか〜
俺のソースコードは、いつでもスパゲッティになってるな〜 FXのツールとかで時限で誤動作爆発させたら大量に電車に飛び込みそう 糞みたいなコードにはもれなく言い訳がついて来る
もし本気を出せば綺麗なコードが書けるかのような 最近JavaScriptのswitch(true)イディオムを知ったが
do { ... } while(false)と同じような邪悪さを感じた >>423
>do { ... } while(false)
これ最適化でdoの中に入ってこないイカしたコンパイラに昔遭遇して
発狂したことがある マイナンバークラスから氏名クラスへの変換関数が存在した場合の問題点。 期間持つのと、変換日時を任意に設定出来ることが最低条件かな。
変換ではなく、取得クラスになるだろうけど。 >>409
0すら定数定義させられた事があったわー >>431
これは正しいんだよなw
マジックナンバーはだめ
じゃあ数字に対して全部defineすればいいってわけじゃない。
何が数値そのまま書いて良くて、何がダメなのかもう少し良い説明ない? たとえばVBAの話になるが、VBAからシートの特定のカラムのセルを参照するには
Cells(行, カラム)やRange("行:カラム")のように指定する
これはカラムの配置を変えただけでプログラムが破綻することを意味する
さてExcelにおいてカラムの配置を変えたいことは良く思うことである
そこで1行目のヘッダとなる名前とカラム番号を連想配列に登録しておき
名前でカラム位置を特定するという方法がある
こういった対策をしとかないとVBAはマジックナンバーだらけのコードになる
対策したコードは処理の最初に名前から番号への変換のコストが発生するが
それは些細なコストである
・・・わかったかね その値が何を意味してるのかを定義して同じ意味のものをまとめるだけ
もともと可読性と変更に強くするためにしてるのだから
あとdefineはundefで消すこともできるため難解コードは解析しづらい
定数もしくはenumを使うのがいい 上のRangeの場合は"カラム行"だけどまあどうでもいいわな
さてCOMインターフェースの1つIDispatchはこれの逆をやっている
IDispatchは全て名前ベースでプロパティやメソッドを呼び出せるようになっている
が実はそれらには一意のIDが割り振られており、事前に名前からIDを特定しておくこともでき
うまく書けば名前からIDへの変換は1度のコストで済む連想配列を内蔵した形だ
ちなみにここで登場した連想配列に名前を格納する仕組みは
主に文字列リテラルとして実装されるが、これはマジックナンバーではない
これをマジックナンバーとみなしてさらに別名定義するアホはいないだろう GUIDという概念がある
コイツハマサニマジックナンバーデコノアイデーハセカイニヒトツシカナイコトガホショウサレルアイデーナノデアル
デモニンゲンハコンナモノイチイチオボエテラレナイカラマサニマジカルナウンヨウガナサレテイル マイナンバー制度という概念がある
主に国内でやりとりされることを想定した奴隷番号である
公開すると害があるらしく最後には官憲が動くかもしれない危険な番号として最近認知された 国民総背番号制という古来からの論争の種だったのだが,最近は抵抗運動はなかったのか? そもそも既に番号振られてるよね、事実上、って気づいたからじゃない? マイナンバーの本体そのものは民主時代に通ってるがな
今騒いでるのは改正と称して悪用するための変更 そういやテストデータの人名に政治家やら備考欄に真実()入れてきた外注があったわ >>432
function pi() の中で3.14。
function month() の中で12。
function hour() の中で24。
こんなん、常数にする?俺はしない。 >>445
お前誰だよw お前ごときがしないからってどうでもいいわ。
一般的にそれらは定数に良くなっている。 >>446
#define マクロのない言語は哀れだね いや、マクロが欲しければm4みたいな汎用のマクロプロセッサを使えばいいし、
単なる文字列置換であるマクロは、コードの静的解析能力を下げ
(例えばプリプロセッサを通さないと構文エラーかどうかわからない)
エラー時の情報をわかりにくくしたり、分かりにくいバグの元になったりするので
排除する方向にあるんだけど。
C言語でもdefineよりもconstやinlineを使うのが常識だしさ。 #define ABC 5 + 10
void func(void)
{
int abc = ABC * 10;
print("%d", abc);
}
このパソコンは算数が苦手になったみたいです。
150と表示されません。
………………死ね! コンパイラさんがどういうことやってるかわかってない人が コンパイラじゃなくて、余計なことをやってる
プリプロセッサが原因だけどねw プリプロ 何ですか それ
な方たちがやってるんでは >>450
extern constにしておけば実体持ってるライブラリを入れ替えるだけで
piの中身が3.14なのか3.1416なのか3.1415927なのかを切り替えてリンクできる
組み込みなんかではここのセクションに特別な絶対アドレスを振っておいて
Sフォーマットのファイル作ってから後で値を書き換えたりする >>451
いいこと言うね
使う側からは便利に使える反面複雑な使い方してると解析不可
defineはundefで消せるからコンパイル順通りに解析していかないとそのdefineは別の定義かもしれない >>458
プリプロセッサだけ通せばいいだけだろ
解析不可とかアホか >>459
小さい規模ならまだしも業務用のでかいのに毎回やるのは非効率
後続の言語が切り捨てたとおり現状マクロは負の遺産
今の時代はフレームワーク使って読みやすいそこそこのものを短期で作ることが求められてるからね >>459
プリプロセッサを通した結果に対して、
コンパイラがエラーを出したとき、
プリプロセッサを通す前のコードみても意味がわからんし、
通した後のコードは自分が書いたコードじゃないし。
プリプロセッサを通した結果に対するエラーから、
プリプロセッサを通す前のコードをどこをどう直せばいいのか
そのつながりを人間が判断するしかなく意味不明になるんだよ。
人間が頭の中で逆プリプロセッサをしなくちゃいけなくなる >>463
IDEはまだましよ。
そういう変則的なものであっても頑張って対応してるから。
問題はテキストエディタを使ってる場合。
そういう細かいところの対応までできてないからなぁ。 C ( or C++ ) のソースで
#if 0
#endif
でコメントにするのはやめて欲しい。 SublimeTextなどを使って範囲選択して
一気に行頭に//を入れたほうがいい。 >>465
理由を述べよ。
単に嫌うのは、食わず嫌いと一緒。 >>468
自分で考えろ。
考える前に聞くのはバカ。 >>470
バカのうえに早合点のトンチンカンで三冠王だな。 俺の考えが正しいことが証明されたな。
俺の考えはググった程度じゃわからんよ。 >>465
この方式はテキスト直編集や文字列検索の側面から懸念される
しかしメリットもあってコードの切り替えがしやすい
ifdefなら複数箇所修正も一気に元に戻すことも可能
誰かの修正でも消した人間がやってくれていれば修正当時の状態に戻せる
また修正が重なると//はインデントずれるがifの方はズレの発生もないメリットもある
俺はそのコードを検証等で使用する可能性があるかどうかで使い分けてる デメリットもブロックコメントと同等かそれ以下だと思うがな。
まぁ、ネストが重なるとわかりにくくなるから1レベルに限定されたコメントの方が
いいという意見もあるだろうけど。 うちは//も複数行にわたるブロックコメントも禁止だし
コードのコメントアウトは#if 0 〜 #endifが推奨になってる
Eclipse使ってればこっちの方が楽 >>475
その規約をどうにかしたほうがいいんじゃないか #if 0じゃ意味が判らんから定数使えや、とエスパーしてみた またそれかw
定型句は意味がわかるから問題ないんだよ。 #define NOUSE 0
#ifdef NOUSE
:
:
#endif #if 1 // どっちにしようかな
//速いけど詠み難いコード
#else
//遅いけど判り易いコード
#endif バージョン管理システムのチケット番号でifdefしてるのは見たことあるわ。
果たして本当に、それでそのチケット番号の状態に戻るのかは誰もやってないと言う。 >>482
同じ個所弄ったらネストしていくのか…? >>482
戻るかどうかは二の次
一番重要なのはどんな修正をしたかということ
自分はいなくなってもコードは10年20年先の人間も目にすることがあるのだから
バージョン管理でやればいいという声もあるが果たしてそれ20年後に見れるか疑わしい
国際標準でなければ廃れると見たほうがいい
やっておいて損はない > バージョン管理でやればいいという声もあるが果たしてそれ20年後に見れるか疑わしい
絶対確実に見れる。 見れるというのは読めるということ。
無駄な情報ばかりで、重要な事がわからなければ、
それは「見れない」という。 見れるというのは探し出せるということでもある。
ある事柄に関する修正は、一箇所で終わるとは限らない。
複数ファイルを同時に修正することがある。
複数のファイルに分散された、ある事柄に修正をもれなくすべて確実に
把握できる保証がなければ、それはどんな修正をしたかがわからないということ。
これはファイルのコメントなんかじゃ絶対にわかりっこない。
それはバージョン管理ツールでなければ不可能である。 20年後の人「なんだこの糞コードは・・・当時でもバージョン管理くらいあっただろ!?」 ■ このスレッドは過去ログ倉庫に格納されています