1

最近、コード内でリテラルを使用すべきではないとプログラマーが信じている場合があると聞いたことがあります。場合によっては、特定の番号に変数名を割り当てることが役立つ場合があることを理解しています (特に、その番号が他の場所で使用されている場合のメンテナンスの観点から)。ただし、次のケース スタディを検討してください。

ケース スタディ 1: 「特別な」バイト コードに対するリテラルの使用。

(引数のために) a に格納されている特定の値をチェックする if ステートメントがあるとしますuint16_t。2 つのコード サンプルを次に示します。

バージョン 1:

// Descriptive comment as to why I'm using 0xBEEF goes here
if (my_var == 0xBEEF) {
  //do something
}

バージョン 2:

const uint16_t kSuperDescriptiveVarName = 0xBEEF;
if (my_var  == kSuperDescriptiveVarName) {
  // do something
}

適切なコーディングの実践という点で「推奨される」方法はどれですか? kSuperDescriptiveVarNameが複数回使用されている場合にバージョン 2 を好む理由は十分に理解できます。また、コンパイラは、両方のバージョンを実質的に同じ実行可能コードにするために最適化を行いますか? つまり、パフォーマンスへの影響はありますか?

ケーススタディ 2: の使用sizeof

移植性と読みやすさの観点から、生のリテラルではなく sizeof を使用することが望ましいことを十分に理解しています。2 つのコード例を考慮してください。シナリオは、パケットuint8_tの最初の部分が として格納されているパケット バッファ ( の配列)へのオフセットを計算しているmy_packet_headerことですuint32_t

バージョン 1:

const int offset = sizeof(my_packet_header);

バージョン 2:

const int offset = 4;  // good comment telling reader where 4 came from

明らかにバージョン 1 が優先されますが、スキップするデータ フィールドが複数ある場合はどうでしょうか。代わりに次のような場合:

バージョン 1:

const int offset = sizeof(my_packet_header) + sizeof(data_field1) + sizeof(data_field2) + ... + sizeof(data_fieldn);

バージョン 2:

const int offset = 47;

この場合、どちらが優先されますか? オフセットの計算に関連するすべてのステップを示すことはまだ意味がありますか、それともここで文字通りの使用法は意味がありますか?

コードの実践を改善しようとしているので、事前に助けてくれてありがとう。

4

4 に答える 4

2

あなたがリストするすべての例で、私は名前を使います。

最初の例では、その特別な 0xBEEF 番号を少なくとも 2 回使用したことはほぼ確実です。1 回は書き込みに、もう 1 回は比較に使用しました。あなたがそれを書いていない場合、その番号はまだ他の誰かとの契約の一部です (おそらくファイル形式の定義)。

最後の例では、値を生成した計算を示すと特に便利です。そうすれば、後で問題が発生した場合でも、その番号が信頼できるものであるか、見逃しているかを簡単に確認して修正できます。

ただし、名前付き定数よりもリテラルを好む場合があります。これらは常に、名前が番号よりも意味がない場合です。たとえば、サイコロ ゲーム (おそらく Yahtzee) をプレイするゲーム プログラムがあり、特定のサイコロを振るための特定のルールがあるとします。One = 1、Two = 2 などの定数を定義できます。

于 2013-06-14T05:02:23.720 に答える