質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • C

    4382questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4304questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • C++11

    111questions

    C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

  • コーディング規約

    52questions

    コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

C/C++のコーディング規約について

受付中

回答 13

投稿

  • 評価
  • クリップ 5
  • VIEW 6,407

higetarou

score 47

新しいプロジェクトへ配属される度に新しい規約に頭を抱え、
まわりの空気を読んだコーディングを心がける日々を
過ごしているC/C++プログラマです。

この宗教戦争とまで言われているコーディング規約について
プログラマ皆さんの中で、譲れない部分や理由があってこうしている等
マイルールを持っている等ありましたら教えてください。

ちなみに、私はざっと思いだしたもので以下のとおりです。

①if の条件式で定数は右辺?左辺?
    左辺に書く派です。

    void* p = malloc(...)
    if (nullptr == p)
    {
        return;
    }

    理由は、
    極めて稀なケースでしたが、
    if (p == nullptr) が if (p = nullptr) に
    変更されるといったヒューマンエラーに遭遇した経験があるからです。
    この後、コンパイル時に検出できる構文の方が良いと判断し今の形になりました。
    最初は違和感を感じていましたが、今は気になりません。

②if, for, switch, whileの中括弧はifと同じ行?次の行??
    次の行に書く派です。
    理由は、
    ・{}はスコープを表すものでif等とは別の理由でそこに書かれているから。
    ・スコープを表しているので{と}は同じインデントに書かれていた方が対になっていると分かりやすく、
     縦スクロールの際に見落とすことが少ないから。

③インデントはタブ派?スペース派?
    スペース4文字幅のタブ派です。
    理由は、
    ・初めて使ったVisualC++がタブ設定だったから。
    ・タブを使い続けて問題になったことが無い。
    ・スペースのインデントがあわせづらいから。(気づかないうちにスペースが増えたり、減ったりする)
    ・スペースに比べてファイルサイズが小さくなるから。

こんな感じです。
反論や意見、共感。なんでもいいのであなたのスタイルを教えてください。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

回答 13

+6

あまり細かい構文の書き方にこだわってもと、ゆるい縛りにしています。

括弧の位置は1つのソース内で統一が取れてればOK。
ただ、タブの展開は、後々の検索の利便性にかかわってくる可能性があるので、
スペース展開するかタブコードを使うかはプロジェクトで統一しています。
あと、原則コンパイラの警告はすべて消す事とかね。

たとえば、①の、if の条件式で定数は…ですが、いまどきのコンパイラは警告を吐くと思いますので規制していません。 

どちらかといえば、コーディングスタイルよりも、シンボルの命名規則や、適切なコメントを書く規則を決めた方が有益だと思っています。


投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/13 02:00

    ゆるい縛り。大賛成です!!

    回答ありがとうございます。

    宜しければ、
    T.Kannoさんのシンボル・命名規則
    コメントを書く規則についてお教えいただけませんでしょうか。

    キャンセル

  • 2015/11/13 07:01

    変数の命名規則:
    言語やCPUによりいろいろ使い分けています。
    C では基本はキャメル記法のハンガリアンな感じが多いです。
    とはいえ、C++ でハンガリアンはなじみませんしねぇ。
    アセンブラにしても、たとえばオペレーションサイズ明記方か変数タイプ型かで使い分けています。

    コメントの記述は
    ・一般的なプロローグコメントボックスに機能や入出力を書け
    ・不必要なわかりきったコメントを書かずに、コードの意図や理由を説明を書け
    ・コードの説明ではなく機能の説明を書け

    実際には、事細かに文章で定めるんですけども、慣例的な部分で縛りをゆるくする記述も加えます。
    命名規則に従っていなくても、局所的な一文字変数は許容するとか、argc argv とかは許容するとか。

    まぁ、ゆるゆるですな。プロジェクトのメンバで共通認識でやればOKでしょう。

    キャンセル

+4

今まで一番感銘を覚えたのが、Linux カーネル コーディング規約の「第3章 - 括弧の位置と空白」にある次の一節です。
ただし、関数定義の括弧だけは例外で、開始括弧は次の行の始まりに置きます -
【コード例略】 
ところが世界中の異教徒たちは、この一貫性の無さが、...そうですね...一貫
性が無いと文句を言っています。しかし、正しい思想を持った人々は (a)
K&R は正しく、しかも(b) K&R が正しいのだとわかっています。それに、とに
かく関数定義というのは特別なものなのです(C言語の中で関数定義のネスト
はできません)。
最後の()の中の文、「C言語の中で関数定義のネストはできません」という所はとても納得させられる物でした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/13 02:17

    ご回答ありがとうございます。

    頂いた情報だけですと、
    K&Rは正しいのだから従えば間違いないということでしょうか?
    Last Updateした2007年の規約としては十分だったかもしれませんが、
    現在のC/C++コーディング規約としては不十分な印象をうけます。

    できれば、raccyさんがどういった理由で
    この一節に感銘を覚えたのかが知りたいです。

    キャンセル

  • 2015/11/13 06:03 編集

    すいません、K&Rの背景とカーネルコーディングの背景を知らないと上の話はよくわからないですね。

    まず、「K&Rは正しい」という所は彼らなりのジョークです。K&Rの例文では括弧についてそのように採用しているのですが、一貫性があれば、K&Rの例文に従う必要は無いとK&Rでは書いてあったりもします。この規約を書いた人も、そして、読むであろう人も、このことを知っています。

    それでもカーネルコーディングでは関数の中括弧"{"は改行の後、ifやforなどの中括弧"{"は同じ行という一見一貫性がない規約を採用しました。その理由が最後の()の中の文なのです。Cではifやforはネストできますが、関数はネストできません(GCCだと拡張でCでは関数をネストできるっぽいらしいですけど、標準仕様じゃないので無視します)。記号は同じでもレベルが違うのだから区別して書いた方が良いと考えたのです。

    私はどっちかというとJavaの規約派で、何でも同じ行に中括弧"{"を書いていました。その方が明らかに一貫性があったからです。昔は一貫性がないK&Rの方法は好きじゃなかったのです。しかし、このコーディング規約の一文を見て感動を覚え、ネストできない場合は改行後に書くようにしています。と言っても、C/C++以外に関数をネストして書けないって少ないんですけど…。

    キャンセル

+3

①if の条件式で定数は右辺?左辺? 
右辺派です。
今時のコンパイラなら警告レベルを適切に設定すれば、if文の条件式が代入文になっていると警告を発してくれます。その他見落としがちなミスを指摘してくれたりするので、プロジェクト開始時には必ずコンパイルオプションを確認しましょう。VC++なら警告レベル4に上げましょう。
また、==ならまだしも、不等号でも定数を左辺にするという記述をたまに見かけますが、非常に読みづらいのでコードレビューなどでそのような記述をしているのを見かけたら、私なら訂正させます。

②if, for, switch, whileの中括弧はifと同じ行?次の行?? 
自分でコードを書く場合は改行してブロックの開始と終了のインデント位置をそろえますね。左側だけ見ていればプログラムの構造が把握できますから。それと、{を行末にすると、特にfor文でそうなりがちですが、条件式が長くなって改行したときに、条件式なのかブロック内の処理なのか見分けがつきにくくなります。
あとは、行単位にすると編集がしやすいということもありますね。ブロックを丸ごとカット&ペーストするというときなど。
ただし、他人のコードを修正するようなときはそっちに合わせます。

③インデントはタブ派?スペース派? 
基本4文字のハードタブです。これは重要なのでプロジェクト開始時には規約に入れてメンバーに周知させ、エディターの設定などを確認します。

コーディング「スタイル」に関しては、あまり細かく規定して「規約」に盛り込むと、それこそ宗教戦争的な流れになってしまうので、そうしなければ困るということ以外は個人の裁量に任せた方がいいような気がします。有名なところが出しているコーディング規約は、参考にすることはありますが従う気にはなれません。
T.Kannoさんのご指摘のように命名規則やコメントの充実などを決めた方が良いでしょう。あるいはエラーの伝達方法とか。

追記です。
以下自分で実践している主な規約(?)です。
  • 外部公開のクラス・メソッド等にはDoxygen形式でコメントを書く
  • それ以外も処理内容が判るように適度にコメントを書く(数か月後に見直したときに思い出せるように)
  • シンボル名をあまり省略しすぎない
  • 命名規則でいくつかのプリフィックスを決めている(m:メンバ変数、g:グローバル変数、i:入力引数、o:出力引数、等)
  • #defineでなければ実現できない場合を除いて定数定義は列挙子かconst値を使う
  • 1行はだいたい130桁程度まで(昔プリンターに出していたときの名残。今ではこれがエディターでもちょうど良い長さ)
  • 1行が長すぎて途中で改行する場合は行頭が演算子で始まるようにする(前の行の続きだと即座に判るように)
  • 1行に複数の文を記述しない(デバッガーのステップ実行が行単位なので)
  • 一項演算子はくっつけて二項演算子は前後に空白を入れる(ただし読みやすさを考えてくっつけることもある)
  • 演算子の優先順位が誤解を招きそうな場合は括弧で明確にする(*(p++), x = (a << 1) + 1等)
  • ifやforなどと括弧の間に空白は挟まない
  • do~whileのwhileはブロック閉じ括弧と同じ行に書く
  • switch文のcaseはswitchと同じインデント位置
  • ブール値の条件判定では等号・不等号を使わない(if(flag == false)ではなくif(!flag)とする)
  • gotoを使う前に本当に必要なのかをよく考える(少なくとも21世紀に入ってから使った記憶はない)
  • 同じような記述(関数呼び出しとか変数設定とか)が何行も続くときはなんとなく桁位置をそろえる
  • ファイル終端は改行で終わらせる
  • フレームワークなどを使わない場合はエラー処理やデバッグの仕組みを先に決める(業務でも重要ですね)

結構ありますね。ガチガチですね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/13 02:54

    ご回答ありがとうございます。

    私も警告レベルは常に最大で警告はエラー扱いは常識だと思います。
    規約もゆるく設定とりきめ、他人のコードを編集するときは
    編集されたことが気づかないくらい溶け込むコーディングを目指しています。
    ・・・もちろん、本人には伝えますよ(。´・ω・)。

    しかしながら、ゆるく決めるということは、
    個人に判断を委ねるということで
    その人が0からコーディングする際は、
    ガチガチの俺様コーディング規約がある訳ですよね。

    今回、私の質問の意図としましては
    その個人が決めてる規約に何か実用性のある理由があれば、
    今の自分のスタイルを変えるきっかけにしたいというのもあります。

    回答頂いた内容を例に挙げますと私にとって
    ②,③は完全に共感しているのですが、
    ①の今時のコンパイラに関する点だけ
    私の中の「全てのコンパイラで同じ問題を解決したいか?」という2択に対し
    Yesの判断なので左辺のスタイルなのです。

    できれば、catsforepawさんの規約が知りたいです。

    キャンセル

  • 2015/11/13 07:42

    > ガチガチの俺様コーディング規約がある訳ですよね。
    それでも、それなりのプログラマーなら見たこともないような奇抜なコーディングスタイルというのはないでしょうし、慣れていないものを強制すればかえって生産性が落ちますし。
    まぁ、あまり一般的でないようなスタイルをしていたらこういう風にしてねという感じで言ったり、良くない例として規約に盛り込むことはありますが。

    > 私の中の「全てのコンパイラで同じ問題を解決したいか?」という2択に対し
    私の答えはNoですね。ターゲットは明確に定めます。といってもVC++/G++/Clangの3つしか想定していませんけど(仕事ではVC++/G++以外はほとんど使ったことないですし)。

    > Yesの判断なので左辺のスタイルなのです。
    ちゃんと理解した上でそうするのならいいのですが、特に経験の浅い人はおそらく誰かに言われたか真似をして定数を左に書いているのでしょうけど、よく判っていないから不等号でも同じように書いて読む人を混乱させるのですよね。なのでその場合は見かけたら指摘することにしています。

    > できれば、catsforepawさんの規約が知りたいです。
    回答の方に追記します。

    キャンセル

  • 2015/11/13 10:34

    > 外部公開のクラス・メソッド等にはDoxygen形式でコメントを書く
    これトライしてみようとしているところです。まだDoxygenに慣れないのでDoxygen化する時のことを想定してコメントを書いている段階ですが...

    > 命名規則でいくつかのプリフィックスを決めている(m:メンバ変数、g:グローバル変数、i:入力引数、o:出力引数、等)
    おお、iとoいいですね!!
    今まで私は引数のプリフィックスに 'a' を使ってましたが、'i' と 'o' なら出力であることを明記できますね。

    キャンセル

  • 2015/11/13 12:10

    Doxygenはなかなか便利ですね。Graphvizもセットで入れればクラス図っぽい絵を描いてくれて、それっぽいドキュメントになりますから。

    > おお、iとoいいですね!!
    気に入っていただけてなんだかうれしいです。想像は付くとは思いますが、入力がiで出力がoということは、入出力引数にはioが付きます、

    キャンセル

+2

規約について不毛な議論に時間を費やすよりは、
  * すでにある一般的な規約を流用する。
  * 規約に準拠したコード書きやすいようにエディタの設定をする。
  * 規約違反をチェックするツールを用意する。
ことが大事とおもいます。

規約の例:
- プログラム言語 C の推奨されるスタイルとコーディング規範 http://www.gfd-dennou.org/arch/comptech/cstyle/cstyle-ja.htm

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/13 01:59

    ご回答ありがとうございます。

    確かに既存のスタイルに頼るのも一つの選択肢ですね。
    しかし、リンク先の情報は1999年のものですし
    この16年間、コーディング規約が一切進化しないというのも悲しいと思います。

    できれば、katoyさんが今までで
    この規約に沿ってコーディングしていて疑問に思った点
    どちらかというと、こういった書き方の方が良い等
    ありましたらお教え頂けませんでしょうか。

    キャンセル

+1

コーディング規約は誰が担当しても「一定レベルの品質で生産する」および「メンテできる」ことを目的としたものだと思います。c/c++に関しては長い歴史の中である程度固まっているので、既存の規約に従うのが最適かと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/13 02:56

    ご回答ありがとうございます。

    確かに既存のスタイルに頼るのも一つの選択肢ですね。
    よろしければsugimaさんが準拠しているある程度固まった規約について
    教えていただけますと幸いです。

    キャンセル

+1

こんにちは。楽しいテーマをありがとう。

自分自身としては、(発展途上ですが)下記ルールでコーディングしています。(もちろん決められた規約がある時はそれに従ってます。チーム開発時、私が規約を決める時はもう少し異なる視点で緩やかに決めます。)

①if の条件式で定数は右辺?左辺? 
私はコンパイラの警告に頼って右辺です。もちろん、コンパイラの警告は全て消す主義です。

②if, for, switch, whileの中括弧はifと同じ行?次の行?? 
両方やってみたのですが、今は、中括弧の中身が少ない場合は同じ行、多い場合は次の行にすると使い勝手が良いと感じてます。
高々2~3行の時に{で1行消費すると却って見難くなります。数十行ある時に同じ行にしているとブロックの開始位置がパッと見で見つかりにくくなるからです。

③インデントはタブ派?スペース派? 
ソースは他の人へ渡す可能性が高いのでエディタの機能でスペースへ変換してます。
秀丸を使っているのですが、保存して再度開いた時に初めてスペースに変わるので、なかなか使い勝手が良いです。

④論理的な区切りをコメントで目立たせてます
大きな区切りほど目立つコメントとしてます。
論理的な構造を強調して視覚化することで、頭に入って来やすいように心がけてます。

⑤識別子の長さ
なるべく単語の一部を略さないようにしています。でも、似たような処理の微妙に異なる変数名は異様に長くなりやすいです。
長過ぎる識別子の目立たない一部が異なると可読性が極端に落ちるし、タイプミスしやすくなるので、そのような時は諦めて省略しています。
識別子の長さが20文字を超えてくるとつらいです。

⑥行の長さ
Google Styleで80文字を推奨しているので、なるべく80文字を超えないようにしてます。
でも、改行せずに並べた方が見やすいケースがあります。(例えば、switch-caseで各case文が1行でほとんど同じことをしているような時等)
そのような時は、A4縦印刷できる上限を限度に1行に入れた方が良いかもと最近感じているところです。

⑦変数の宣言形式
良く言われるのがポインタの*をどちらに付けるかですね。
char*   p;
char   *p;
意味としては前者の方が理解しやすい(char*型の変数p)ので、前者としています。
最近は、char* p, q;問題ではコンパイラがエラーや警告してくれるので酷いことにはならない筈です。
むしろ、CやC++言語は型の修飾子がどの順序で付くのか非常に分かり難いので、それを少しでも把握しやすいように心がけるよう努力してます。


気にしている人は少ないと思いますが、下記の選択もありますね。
const char* p;
char const* p;
今まで前者で書いていたのですが、どうも意味的には後者の方がすっきりすることに最近気が付きました。
const, volatile, *, &, []は型の修飾子であり、[]を除き、修飾子は型の右側から修飾すると考えるのです。
つまり、より左側にある修飾子の方が元の型と密に結びついてます。

「char型←それはconst←そこへのポインタ」って感じです。
日本語的にはconstなchar型へのポインタなのでconst char*は妥当なのですが、constな「char型へのポインタ」(char* const p;)と混同しやすいです。
「char型←そこへのポインタ←それはconst」の方が分かりやすいように感じてます。

ただ、[]をこのルールに当てはめることができないので残念です。
int[5] data;って書けないし、int data[10][5];は、data[10]が5個あるのではなく、data[5]が10個ですし。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/13 03:27

    ご回答ありがとうございます。

    Chironianさんの規約大変興味ありました。
    ⑤⑥⑦は私も共感できます!

    ④⑤に関しては主観の判断になるので何がベストか判断に迷いますが
    視覚的に見やすく、間違えにくいを意図してそのようにしている点は共感しました。

    ①に関してはcatsforepawさんへの返答と同じです。
    ②に関しては括弧の位置が2通り混在したソースを見た経験があるのですがスコープの範囲を見失うことが多かったのであまり良いとは思えません。

    ③に関しては理解できませんでした(。´・ω・)?
    人に渡すのであればタブインデントの方が編集しやすくサイズも小さいので
    あえて、スペースに変更する理由が見つかりませんでした。
    何か理由があるのならお教えいただけますでしょうか。
    ちなみに、私は秀丸で保存時にスペースをタブ化しています

    キャンセル

  • 2015/11/13 10:09

    > ②に関しては括弧の位置が2通り混在したソースを見た経験があるのですがスコープ
    > の範囲を見失うことが多かったのであまり良いとは思えません。
    私もC++の深いところを使い始めるまではhigetarouさんの方式で書いていました。

    しかし、コンストラクタを真面目に初期化子で初期化するようになって、コンストラクタの大半は中身が空になったことや、SFINAEで型による分岐処理を書くようになって緩めました。
    例えば下記のようなコンストラクタを結構書きます。
      Foo(const Bar& aBar) : mBar(aBar) { }
    こんなのが数個ある時、
      Foo(const Bar& aBar) : mBar(aBar)
      {
      }
    と書くとソースがすごく間延びして見難くなるのですよ。

    SFINAEは可読性が極端に落ちるので多用はしないのですが、これを使って初めてできることがあるので必要な時は使ってます。
    これを使う時、大抵下記のような記述で始まります。
      template<class Bar, class Enable=void>
      struct Foo { };
    この記述でも{ }の中身は全く重要ではないので、改行しない方が却って見やすいのですよ。

    ちなみにSFINAEを使うと「あるメンバーを持っているクラスは特別処理する」とかできちゃいます。リフレクションのないC++でリフレクションっぽいことを実行時のペナルティ無しでできるのです。

    > ③に関しては理解できませんでした(。´・ω・)?
    タブ幅を統一することができれば問題ないのですが、オープン・ソースでそれをやると顰蹙なのですよ。
    linuxは8ですし、Googleをはじめ2が好きなOSS系の人たちも少なくないです。
    でも、私は4が好きです。

    キャンセル

0

この宗教論は昔から白熱しますねw

bool func(
 int a,    // 改行してここに引数のコメントを書く
 double b
)
{
  bool hoge = false;
  for (int i=0; i<100; i++) {
    while ( !hoge ) {
        if ( getsome() == 1 ) {
            hoge = true;
        } else {
            hoge = false;
        }
        // hoge = ( getsome() == 1 ); というツッコミはなしでw
    }
  }
  return hoge;
}

・条件判断式の前後はスペース(日立で覚えた)
・関数最初の{ は改行
・関数内の if () { や while () { と } はそれぞれ1行で対応させる
・} else { もこれで一行
・forの中にスペース入れるかいつも迷うんだけどねー
・return値にはカッコつけない
です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/16 05:15

    そういえば。
    a >= b
    の方が
    a => b
    よりもアセンブラレベルでステップ数少なくなるというのがあったけども。
    最適化バリバリの今では関係ないようですね(^^;

    ちなみに先日 a => b を見かけて、「構造体ポインタの->じゃないよな?右矢印ってナニ?」と本気で理解に苦しみましたw

    キャンセル

0

うん、つい最近も大論争したなぁ・・・、ガチガチのC言語使いVSC++使いの大論争。
https://github.com/yumetodo/2015_C_Textbook/issues/59
https://github.com/Nagarei/DxLibEx/wiki/Coding_Style
https://github.com/Nagarei/DxLibEx/issues/9

そもそもCとC++ではコーディング規約は違ってしかるべきなんですよね。たとえば

int f(void)/* C */
{
    return 0;
}
int f() //C++
{
    return 0;
}

ちなみにCで前者にするべき理由は、voidと書かないと引数を渡せてしまうからで、C++で後者にするべき理由は短く書けというのと、
C++17のドラフト文章である
P0146R0: Regular Void
では、将来的に廃止することを示唆しているからです。

全般には、

にかなり影響を受けています。ただ最近論争した結果
Linux kernel coding style
にも影響を受けるようになりました。これで思い出したけど、一行あたりの文字数の論争もあったな・・・。私は140文字位だけど。

ではでは本題に。

①if の条件式で定数は右辺?左辺?

もうすこし詳細な場合分けが必要です。

  1. operator== or operator !=  
      pvalue、コンパイル時定数、rvalue、実行時定数、const lvalue referenceの順に左側においています
  2. operator <  
      とくにきにしません。というよりoperator=とoperator==が紛らわしいのが問題であって不等号では関係ないと。ちなみに他の不等号演算子ほぼは使いません。理由はSTLのsortで要求するのがoperator<の存在か比較関数の指定なのでこれつかえば間違いないという安心感があります。
  3. operator <= or operator > or operator =<
      これらはそもそもほとんど使いません

②if, for, switch, whileの中括弧はifと同じ行?次の行??

同じ行です。理由は縦に長くなると、16:9なモニターでは見難くてしかたがないので。

ただし質問にはありませんが関数は次の行にするように最近なりました。理由はSFINAEしたりするとtemplateやら関数の戻り値の後置記法やらnoexceptやらで関数宣言部がながくなり、改行しないと定義部の開始がわかりにくいからです

template<typename T1, typename T2, enable_if_t<std::is_arithmetic<T1>::value && std::is_arithmetic<T2>::value, std::nullptr_t> = nullptr>
    DXLE_CONSTEXPR_CLASS auto dot(const point_c<T1>& p1, const point_c<T2>& p2) DXLE_NOEXCEPT_OR_NOTHROW
        ->decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())
    {
        return p1.x * p2.x + p1.y * p2.y;
    }

コンストラクタ書くときも長くなりやすいですしそれとの統一性というのもあります

struct game_c::Impl {
    Impl(const dxle::pointi& bouninngennA_p, const dxle::pointi& bouninngennB_p)
        : m_window_s(static_cast<int>(WINDOW_WIDTH), static_cast<int>(WINDOW_HEIGHT)), m_state(), m_back_img(dxle::Graph2D::MakeScreen(m_window_s.x, m_window_s.y)),
        m_img(make_image_array()), m_sound(make_sound_array()), score(),
        m_bouninngenn{ {
            { bouninngennA_p, &m_img["bouninngennA"], &m_img["bouninngennA_fall"]},//棒人形A
            { bouninngennB_p, &m_img["bouninngennB"], &m_img["bouninngennB_fall"]} //棒人形B
        } }
    {
        this->m_back_img.DrawnOn([this]() {m_img["gake"].DrawExtendGraph({}, m_window_s, false); });
    }
    void state_init() NOEXCEPT;
    bool normal_con_f() const NOEXCEPT;
    void move_x(int limit_l_x, int limit_r_x) NOEXCEPT;
    void fadeout_prelude_masseage();
    void fall_bouninngenn(size_t bouninngenn_no, const std::deque<dxle::pointi>& pos_record);
    const dxle::pointi m_window_s;
    keystate m_state;
    dxle::Graph2D::Screen m_back_img;
    img_arr_t m_img;
    sound_arr_t m_sound;
    uint8_t score;//0-100
    std::array<obj_info, 2>m_bouninngenn;
};

③インデントはタブ派?スペース派?

スペース4文字幅のタブ派です。スペースでもいいんだけど、まともなエディタならタブくらいちゃんと扱えるでしょ(煽り)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

規約というかコメントの書き方は
doxygenのドキュメントを生成できるようにするのがルールとか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Doxygen はよく使っていますね。
もちろんDoxygen コメントを入れるのは結構手間です。
そこでエディタのマクロを駆使して関数のヘッダが一撃で自動生成できるものを使っています。
エディタは 秀丸エディタ。これを社内標準にしていてマクロをサーバー上で管理し、こつこつメンテしています。

あまり良いことではありませんが、仕様変更が多く、詳細設計書が書けない事もあり、最終成果物であるソースコードから Doxygen を使って文書を生成しています。

そのためにDoxygen で理解できるようなコメントを大量に入れて構造体の意味等も分かりやすくしています。

私のところでは、賛否両論あることを分かった上で、こんな記述にすることを強く推奨しています。

#define   IS_EQUAL_TO    ==
#define   IS_NOT_EQUAL_TO   !=
    if ( bEnableFeature IS_EQUAL_TO TRUE )


これに、さらに秀丸エディタの設定を使って IS_EQUAL_TO は緑に、IS_NOT_EQUAL_TO は赤になるようにしています。
これだと絶対に = 単体にしてしまう間違いはありませんし、色が違うので打ち間違い、勘違いも起こりにくくこの部分でバグったのを見たことがありません。

ご参考まで

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/28 18:47

    > そこでエディタのマクロを駆使して関数のヘッダが一撃で自動生成できるものを使っています。
    > エディタは 秀丸エディタ。

    おお! すっごい便利そうですね。この発想はありませんでした。
    探したら、↓が公開されてました。
    http://hide.maruo.co.jp/lib/macro/doxylabel.html

    doxygenでドキュメント作る予定です。また秀丸を主に使ってますので、これを使えばサクサク進めそうです。
    良いアイデア、ありがとうございます。

    キャンセル

  • 2016/01/29 01:30

    doxygen commentつけるのは絶対にsubime textのプラグインのほうが
    /**
    と打ってEnterするだけで雛形ができるからそっちが楽だと思うんだけど、それこそ宗教戦争だからまあいいや

    キャンセル

0

どれも宗教戦争レベルなので気にするだけ時間の無駄と考えています。
①はWarningが出ていれば直す。出ていなかったら静的解析ツールを使用するべきかと思います。
②、③は本当に議論するだけ無駄だと考えています。

他の方の回答にもありましたが、命名規則・コメント・無駄な空白行を気をつて、
可読性を上げたほうが有意義です。

特に命名規則はコーディングの修正が入ると名と機能が合わなくなることがあるので、
その時点で名もコメントも修正するようにするほうが重要と思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

必須なのはインクルードファイルの構成に関する規約ですね。
放っておくと、すぐにall-in-oneヘッダを作ったり、includeの順序が違うと動かなくなったりするものを平気で作る人たちのお陰で、ソースファイルの依存関係がメチャクチャになりますから。

内容は、大体、GoogleのC++スタイルガイドの<ヘッダファイル>の項目と一緒です。
また、それに関して、C++だとnamespaceに関する規約は必ず入れさせますね。
namespaceの使い方を考えずに作られた規約でそのまま作業している現場がまだ多いですから。

括弧や空白の位置、タブなどは、瑣末な話なのであんまり考えてません。担当者の趣味で決めてもらいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ぶっちゃけた話、「IDEやコンパイラのワーニングの設定を揃えてそのまま」がいちばんいいです。
些末な書式の好き嫌いよりも、自動的に整形してくれたり、
違反を見つけてくれる便利さのほうがはるかに勝ります。
自動整形もバリデーションもできないような規約は
よほど切迫した実際的な問題が無い限りスルーですね。
ゆずれない、といったらそういう部分です。

それでも、自分の好みというのは確かにあります。

①if の条件式で定数は右辺?左辺? 

誤記の見つかりやすさの問題もありますが、
私は JUnit 的なニュアンスで、

期待値 == 実際値

のほうがしっくりきますね。

しかし、そのJUnit も大きく変わってきていますし、
英語話者の感覚では、  if ( p == nullptr ) を、
「if p is nullptr」  と読み下せることを優先するような動機もあるみたいですね。
全体の趨勢がそうなってきたらそちらに合わせた良い場合もあるのかな的なことは思っています。

②if, for, switch, whileの中括弧はifと同じ行?次の行?? 
K&R から入っているので同じ行にあるほうがすわりが良いです。

{} がスコープを示すのは事実ですが、
頭に文が無いと、逆に純粋にスコープのためだけに使う {}との見分け方が紛らわしくなりませんか?
・スコープの記号だから行を変える
・単純スコープとの区別のために同じ行に書く
という二つの理由は私にはどちらも同じ程度納得がいくものですです。
ですから、あるいみ「どちらでもいい」気はします。
慣れの上から、同じ行にあったほうがいいと思うだけです。
ただ、else だけは、

} else {

のような形で一行にしてほしいという気もします。
else if で複数の条件が書かれている場合に、
else の記述が複数行にわたっていると、
条件と分岐の記述と、各条件における処理の記述が一目で見分けにくくなる気がします。

{} に関しては、位置よりも省略の方にこだわりがあります。
自分は {} が省略されているコードを見るとどうもムズムズしてしまいます。
一番の問題は、処理を追加する場合により注意が必要になってしまうということです。

if ( ... ) 
   ...
else
   ...
条件分岐には含まれない処理の記述


なんて記述の気色悪さに比べたら、

if ( ... ) 
{
  ...
}
else
{
   ...
}


if ( ... ) {
   ...
} else {
   ...
}


の違いなんて大した問題ではないです。

③インデントはタブ派?スペース派? 
派、というか、設定一つで勝手にエディタがやってくれる事柄なので、
他のツールの都合に設定を合わせるだけで、問題が生じない限り普段は意識していません。
経験から、タブはやめた方がいいとは思います。
ソースコードレビューやろうとして、チームリーダが使ったビュワーで自分のソースだけ
インデントが変になるといった問題を回避するために、
プロジェクト参加時にタブを規約で決まっている桁数の空白にするようにエディタに設定しておしまいです。
当然 Makefile だけはタブはタブのままですが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • C

    4382questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4304questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • C++11

    111questions

    C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

  • コーディング規約

    52questions

    コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。