17

私は、Linus Torvalds から正体不明の Elbonian コード スレーブまで、さまざまな品質/能力/正気のさまざまなソースからまとめられた大規模な SDK コードベースを使用しています。

コードにはさまざまなスタイルがあり、明らかに他のスタイルよりも優れているものもあり、別の手段で人類の未来に対する私の知識/絶望を拡大する興味深い機会を証明しています.

少し奇妙な(私にとって)スタイルを繰り返し使用する関数の山に出くわしました。

void do_thing(foo)
{
    do {
        if(this_works(foo) != success)
            break;
        return(yeah_cool);
    } while (0);
    return(failure_shame_death);
}

このコードでは複雑なことは何も行っていません (この投稿のために 10,000 行の魔法を切り出していません)。

if(this_works(foo) == success)
    return(yeah_cool);
else
    return(failure_shame_death);

どういうわけかより良く/きれいに/より直感的/読みやすいように見えます.

だから私は今、それを別の方法で行う(正当な)理由があるのか​​ 、それともエルボニアのコードマインズで常に行われている方法なのか疑問に思っています.

編集:「重複の可能性がある」リンクによると、このコードどのような種類のマクロでも前処理されておらず、通常のコードにあるだけです。この回答 に従って、エラーチェックに関するコーディングスタイルのルールが原因である可能性があると信じています。

4

5 に答える 5

5

うーん、コードは何らかの形で前処理されている可能性があります。これdo { } while(0)は、プリプロセッサ マクロで使用されるトリックです。次のように定義できます。

#define some_macro(a) do { whatever(); } while(0)

上記のコードのように、while(0) の後にセミコロンを置くことが許可されているため、どこでも使用できるという利点があります。

この理由は、次のように書くと

#define some_macro(a) { whatever(); }

if (some_condition)
    some_macro(123);
else
    printf("this can cause problems\n");

else ステートメントの前に余分なセミコロンがあるため、このコードは無効です。はdo { ... } while(0)どこでも機能します。

于 2013-10-17T10:49:32.993 に答える
1

do {...} while(0) を "break" で並べたものは、ある種の "プレーン C の RAII" です。

ここで、「ブレーク」は異常なスコープの終了 (一種の「プレーン C 例外」) として扱われるため、リソースの割り当てを解除する場所が 1 つだけであることを確認できます: 「while(0)」の後です。少し変わったように見えますが、実際にはプレーン C の世界では非常に一般的なイディオムです。

于 2013-10-21T16:31:48.363 に答える
0

gotoこのコードは、もともとエラー処理のために s で書かれたものだと思います。

void do_thing(foo)
{
    if(this_works(foo) != success)
        goto error;
    return(yeah_cool);
error:
    return(failure_shame_death);
}

しかし、ある時点で、「あなたは goto を使用してはならない」という勅令が下されたため、誰かが goto スタイルから loop-break スタイルへの半自動変換を行いました (おそらく単純なスクリプトを使用)。おそらく、コードがあるプロジェクトから別のプロジェクトにマージ/移動されたときです。

于 2013-10-21T16:23:36.533 に答える