K&RとOne True Brace Style(1TBS)スタイルの違いは何ですか?


48

Indent Stylesに関するWikipediaの記事を読みましたが、まだ理解できません。K&Rと1TBSの違いは何ですか?


私はどこかで、K&Rのスタイルはスペースの考慮事項に支配されていたことを読みました。つまり、コードが本で取り上げていた垂直方向のスペースを減らすことです。
ChrisF

@ChrisFは、画面上の垂直方向のスペースも削減します。80カラムx 25ラインのターミナルがあれば、それだけの価値がありました!
マーティンベケット

7
Appleの「GOTO失敗」確かに1TBSを使用することによって防止されていたであろう重大なバグの偉大な例です。imperialviolet.org/2014/02/22/applebug.html

4
Appleのバグは、ステートメントを1行に入力するか、校正するか、デッドコードチェッカーを使用するか、インデントに敏感な言語を使用することで防ぐこともできました。
シーズティマーマン

1
@CeesTimmerman、..またはテスト中...
thoni56

回答:


76

K&Rと一つの真のブレーススタイル(1TBS)との最大の違いは1TBSで、すべてがということでifelsewhile、とfor彼らは必要ない場合であっても、文が開閉括弧を持っています。目的は、新しいステートメントを簡単に挿入し、それらがどのようにグループ化されるかを正確に知ることです。

例として:

K&R:

int i;
for (i = 0; i < 10; i++)
  printf("Hi.");

1TBS:

int i;
for (i = 0; i < 10; i++) {
  printf("Hi");
}

20

K&Rは次のようなものです。

if (x) 
    a();
else {
    b();
    c();
}

つまり、ブレースは必要な場所でのみ使用され、制御ステートメントと同じ行でブレースを開き、独自の行でブレースを閉じます。

「1つの真のブレーススタイル」(1TBSまたはOTBS)は、中括弧で囲むことにより、単一の制御ステートメントを複合ステートメントに変換します。

if (x) {
    a();
} else {
    b();
    c();
}

Allmanスタイルは1TBSよりも少し進んでおり、オープニングブレースを単独で線上に配置することにより、垂直方向の間隔を強制します。

if (x) 
{
    a();
}
else 
{
    b();
    c();
}

編集:

「デニスリッチーは、優れた言語を発明しただけでなく、それに対して非常に優れたブレーススタイルを考え出した非常に賢い人でした」と言うために、それが「ar慢」とみなされる方法を正確に把握しようとしています。

とにかく慢であると主張する人のために、ここに少し挑戦があります:Sourceforge、Github(など)に行き、K&Rブレーススタイルを使用してプロジェクトを選択します。バグとコミットの記録を調べ、使用したブレーススタイルによって引き起こされた単一のバグを見つけようとします。

それほど多くの作業を行いたくない場合は、簡単な統計分析を行ってみてください。さまざまなブレーススタイルを使用してプロジェクトを比較し、ブレーススタイルと相関するバグカウント(重大度など)の統計的に有意な違いである「バイモーダル」を表示できるかどうかを確認します。

数年前にこれらの両方を実行しましたが、ブレーススタイルに起因する単一のバグを見つけることも、2つの間の統計的に有意な相関に近づくものを見つけることもできませんでした。平均して、K&Rブレーシングを使用したものは、わずかに少ないのバグがあったが、違いました多くの統計学的に有意としての資格には小さすぎます。

提起されたので、複数ステートメントマクロの状況についてコメントします。複数のステートメントを含むが、それらを中括弧で囲まないマクロにはバグがあります。私の仕事は、そのバグをカバーするコードを書くことではありません。それどころか、私の仕事はそのバグをできるだけ早く見つけて根絶することです。

バグを隠してバグを診断および修正されないままにすることを期待してコードを書くのは、実に悪です。あなたが望むなら、その慢さを呼びなさい、しかし私はこれを交渉に近いものとさえ見ない。バグを見つけて修正する必要があります。存在する期間が長いほど、修正するのがはるかに困難で費用がかかる可能性が高くなります。


1
彼らが口論とノイズに降りかかったので、すべてのコメントを削除しました。有効なポイントがある場合は、回答として投稿してください。ディスカッションが必要な場合は、チャットに参加してください
ChrisF

8
1tbsは}などを1行に入れませんか?不思議な美しい対称性を維持しながら垂直方向のスペースを節約することがポイントです!
マーティンベケット

4
@ジェリー-まあ、良い聖戦にはいくつかの分裂が必要です;-)
マーティンベケット

6
gotoが失敗します。gotoが失敗します。
ジェイミーパテ14

9
はい、ここ分析されている Apple SSLバグである@JamiePateのコメントをフォローアップしますif文の後にインデントされた文があり、したがって両方が条件付きで実行されているように見えます。しかし、ブレースはありません!2番目のステートメントは実際にはそれを超えてifおり、常に実行されるため、バグです。
コリンDベネット

9

問題は、一般的にKRブレーススタイルにあり、コードのリファクタリングにあります。コードを移動するとき、何かの周りにブレースがないことを簡単に見落とし、それを誤って移動し(または条件付きで実行されていると考えてその下に何かを移動し)、何かが機能しなくなったときに頭を傷つけるか、不幸にしてコード領域は十分にテストされておらず、バグは悪用される方法が見つかるまで気付かれません。デバッガーに簡単にアクセスすると、気づいた場合は簡単に問題を見つけることができますが、気付かない場合は...


2
これは、以前の回答で指摘され説明されたポイントを単に繰り返すようです
-gnat

1
他の回答では、日常のコードで問題がどのように発生するかを正確に説明しているとは思いません。OTBが何であるかを説明しますが、実際に重要である理由ではありません。コメントはそれを扱っているかもしれませんが、答えはありません。
ジャスティンスワンハート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.