サポートできないコード(パート2)

このトピックの続きは、エッセイ「メンテナンス不能なコード」の2番目と3番目の章です。 最初のものと共通するものがありますが、説明されている方法はそれほど明白ではありません(そしていくつかは真に悪魔的な創意と劣悪な悪意で異なります)。 そうそう、宣言されたJavaプロローグから、著者は静かにC / C ++に切り替えました。



カモフラージュ





カモフラージュの技術-物を隠したり、他人に見せかけたりすること-は、サポートされていないコードを書く技術の重要な部分です。 このセクションの手法のほとんどは、コンパイラがテキストエディターや人とは異なる方法でコードを認識および処理するという事実に基づいています。 以下は、選択された迷彩のトリックです。



1.「効果的な」コードを書く


愚かさを含む他のいかなる理由よりも、効率の名の下により多くの罪が犯されています。



コードの難読化アクションを非表示にする最も安全な方法は、プログラムの効率を高めることが主な目標であることを装うことです。 高尚な目標のために、あなたのトリックはすべて出てきても許されます。



2.コードを装ったコメント


コードスニペットをコメントアウトして、一見関連性があるようにします。

 for ( j=0; j<array_len; j+ =5 ) { total += array[j+0]; total += array[j+1]; /*       total += array[j+2]; */ total += array[j+3]; total += array[j+4]; }
      
      





コードを強調表示せずに、中央の行がコメント化されていることに気付くでしょうか?

(このメソッドがどの開発環境のために設計されているか想像できません-Farにもコード強調プラグインがあります。どうやら、/ * * /がコメントとして認識されない不適切なファイル拡張子と組み合わせることになっているようです)



3.名前空間


Cでは、struct / unionとtypedef struct / unionは異なる名前空間に属します。 したがって、同じ名前を両方で使用できます(また使用する必要があります)。 ほとんど互換性を持たせることをお勧めします。



typedef struct { char* pTr; int lEn; } snafu;



struct snafu { unsigned cNt; char* pTr; int lEn; } A;








4.非表示のマクロ


意味のないコメントの中でマクロ定義を非表示にします。 メンテナーはすべてのコメントを一度にスキップし、マクロを検出しません。 このようなマクロを使用して、正当な言語表現を非常に奇妙なものに置き換えます。



#define a=ba=0-b







(著者が何を考えていたかわからない。C/ C ++コードのこのマクロは、変数がコードに表示されるとエラーを生成し、そのような変数がない場合は無視されます。C/ C ++も愚か者を書いていません:-) -約



5.忙しいふりをする


マクロを使用して、まったく何もしない架空の「関数」を作成します。



#define fastcopy(x,y,z) /*xyz*/

:

fastcopy(array1, array2, size);








6.関数をオーバーライドする


完全に予期しないことを行う標準的な関数(パラメーター付きマクロ)の「関数」複製を作成します。 (したがって、特別なマニアは、修正を行う人が使用する可能性のある多数の関数を再定義できます。たとえば、マクロ#define abs(a)(-2 * a)とペアで、かさばるモジュール計算関数を記述して使用できます。パートナーの通常のモジュールに置き換えようとする試みを悪魔のように笑っています-約)



7.変数名での転送


Cプリプロセッサは、行末の\文字を改行として扱い、次の行に接着することを覚えていますか? いいね! 単純な検索でこれらの変数へのすべての呼び出しを見つけることをより困難にするために、長い変数名を文字列に分割することで創造的です。



8.任意の例の予約語を選択します。


ドキュメントでファイル名の任意の例が必要な場合は、「charlie.dat」のような明らかに任意の名前ではなく、「file」を使用します。 一般に、予約語にできるだけ近い任意の例を選択するか、これらの語自体を選択します(コンパイラーがそれを受け入れない場合、さらに良いことに、これは単なるドキュメントです)。 正しく使用すると、読者は、例のどの部分を他の単語に置き換えることができ、どの部分を置き換えることができないかについて絶望的に混乱します。 捕まったら、読者が各変数の目的を理解するのを助けようとしているだけであることを無実に証明できます。



9.コード内の名前とインターフェース内の名前


変数名がドキュメントとインターフェイスの名前とは無関係であることを確認してください。 たとえば、郵便番号フィールドはzip変数に格納できます。



10.名前を変更しないと言う


2つのコードを同期するには、変数の名前を変更しないでください。 #defineでそれらを再定義します。 テキスト検索を防止するために、異なるファイルで同じ変数の同義語をさらに作成します。



11.グローバル変数の禁止を回避


これを行うには、必要なすべての変数を含む静的なグローバル構造を定義し、EverythingYoullEverNeedという名前を付けます。 この構造体を関数(または、ハンドルと呼ばれるポインタ)に渡して、グローバル変数が存在しないという錯覚を作成します。



12.オーバーロード演算子


演算子のオーバーロードの注目すべき特性により、算術とはまったく関係のない独自の演算子+、-、/、*を作成できます。 結局のところ、StraustrupがI / Oのストリーミングにシフト演算子(>>および<<)を使用している場合、何が悪いのでしょうか?



13. #defineおよび#ifdef


前の段落からわかるように、プリプロセッサディレクティブは感謝の偽装の別の歌に値します。 他にほとんど何もコードに多くの混乱をもたらすことはできません。 #Define式は関数と変数として完全にマスクされます。 #ifdefを創造的に使用すると、ヘッダーファイルが含まれる順序と数量に応じて、異なるバージョンの関数を使用できます。 次のコードが何をするのかを理解してください。



#ifndef DONE

#ifdef TWICE

// put stuff here to declare 3rd time around

void g(char* str);

#define DONE

#else // TWICE

#ifdef ONCE

// put stuff here to declare 2nd time around

void g(void* str);

#define TWICE

#else // ONCE

// put stuff here to declare 1st time around

void g(std::string str);

#define ONCE

#endif // ONCE

#endif // TWICE

#endif // DONE








14.コンパイラ指令


コードの動作を変更するのに便利なもう1つのことは、コードが作成された理由です。



15.気を散らす操作


未使用の変数と呼び出し不可能なメソッドを使用してコードを強化します。不要になったコードは削除しないでください。 これを正当化する理由は、このコードがまだ役に立つかもしれません。 使用されるコードに似た名前のボーナス-メンテナーは間違いなくそれらを混同します。



ドキュメント





愚か者は真実を語ることができますが、賢い人だけがよく嘘をつくことができます



コンパイラーはコメントを無視し、ドキュメントを表示しません。そのため、コンパイラーで何かをすれば、貧しい仲間を混乱させることができます。



1.うそ


直接うそをつくことはできません。コードを更新するときにコメントを更新するのを忘れてください。



2.明白なことを文書化する


/ * increment i * /のようなコメントでコードにシーズニングを行い、疑わしい場所(メソッドの目的または実行されたアクションの意味)へのコメントを避けます。



3.「なぜ」ではなく「なぜ」


プログラムのアクションのみにコメントし、その目的と目的にはコメントしないでください。



4.「明白な」文書化を避ける


コードが特定の方法で変更されると想定する場合は、これを行うために何をする必要があるかについては決して述べないでください。 あなたの後に来る人々は、それを詳細に理解することなくコードを編集するために登ることは何もありません。



5.ドキュメントテンプレートの問題について


機能を文書化するためのプロトタイプの適切な使用について考えてください。機能間でテンプレートを慎重にコピーしますが、テンプレートフィールドには入力しないでください。 それらを記入することを余儀なくされた場合、すべての関数のパラメータが同じと呼ばれ、それらの復号化が関数自体とわずかな関係を持っていないことを確認してください。



6.設計文書の問題について


複雑なアルゴリズムを実装する必要があるとしましょう。 ソフトウェア開発の古典的な原則を使用します。最初に、このアルゴリズムのプロジェクトを作成します。 自動番号付けを使用して、ネストされたアイテムのマルチレベル(最低5レベル)階層の形式で、段階的に説明する非常に詳細な(より詳細な、より良い)ドキュメントを記述します。 最終的に少なくとも500ポイントになるようにしてください。 したがって、1つのポイントの例は



1.2.4.6.3.13 - Display all impacts for activity where selected mitigations can apply (short pseudocode omitted).







その後(はい、ここにフォーカスがあります)コードを記述し、そのようなアイテムごとに個別のメソッドAct1_2_4_6_3_13()を作成します。 いいえ、メソッドコードにコメントを書かないでください-結局のところ、これに関するプロジェクトドキュメントがあります! ドキュメントを編集すると、元のドキュメントの番号が自動的に変更されるため、メソッドの静的な名前を最新に保つことは困難です。 しかし、あなたにとってこれは仕事にはなりません-結局のところ、あなたは文書を最新に保つよう努めません。 実際、ドキュメント自体だけでなく、その存在のあらゆる種類の痕跡も破壊するようあらゆる努力を払う必要があります。 ただし、古いコンピューターの下のパントリーには、1つまたは2つの下書きを慎重に隠すことができます。



7.単位


変数とパラメーターの測定単位を文書化しないでください-これは計算ではそれほど重要ではありませんが、エンジニアリング作業では非常に重要です。 同様に、変換で使用される定数、または値の取得方法についてはコメントしないでください。 原始的で効果的な方法は、誤ったユニットを示すコメントでコードを装飾することです。 特に憂鬱な気分がある場合は、独自のユニットを考案します。自分自身または特別な人にちなんで名前を付け、明示的に定義しないでください。 これに誤りがある場合は、それを使用して小数を混乱させないように整数演算に制限することを使用することを説明してください。



8.バグ


他の人のコードのバグを文書化しないでください。 バグがどこかに隠されていると思われる場合は、自分に任せてください。 コードを再編成するためのアイデアがある場合は、神のために書き留めないでください。 あなたのコメントがコードの作成者、管理者、クライアントに見られたらどうなるかを考えてください。 はい、解雇できます! しかし、匿名のコメント「これは修正する必要があります」は、特にそれが何を指しているのかわからない場合、驚くほどうまくいきます。



9.変数の説明


決して-聞いて、決して! -変数を宣言するときに変数を文書化しないでください。 変数の使用、その境界と許容値、精度、測定単位、出力形式、入力規則などに関する事実 コードから明らかです。 コメントを書く必要がある場合は、それらをプロシージャの本文であふれさせますが、変数の宣言はありません。



10.屈辱的なコメント


他の会社の従業員を引き付ける試みを削減し、名誉と尊厳を損なうコメントでコードをgeneしみなく飾ります。



* Software Services Inc.; , ,

* 50 <math.h>








可能であれば、そのようなコメントを重要なコードに配置し、セマンティックコメントと混合して、無害にしようとする試みができるだけ複雑になるようにします。



11.パンチカード上のCOBOLであるかのようにコメントする


開発環境の機能を破棄し、関数と変数の定義が常に使用からワンクリックで離れているという噂を信じないでください。また、Visual Studio 6.0で記述されたコードにはedlinまたはviツールが付属することを期待してください。 ドラコニックな注釈の要件は、コードを埋めるのに最適な方法です。



12. Monty Pythonスタイルのコメント


makeSnafucatedメソッドのコメントは、/ * make snafucated * /の1行のみで構成する必要があります。 盗まれたものを決して定義しないでください-誰でもそれを知っています。



13.古いコード


古いコードを復元するためにバージョン管理システムに頼らないでください-削除しないでください。 新しいコードが古いコードを置き換えるか、それを補足するか、古いコードが誰かのために機能しなかった理由、それがまったく機能したかどうかなどについてコメントしないでください。 古いコードに各行で//の代わりに/ * * /としてコメントします-これにより、現在のコードをより簡単にサポートに費やすことができます。



All Articles