2013年4月7日日曜日

コーディング規約 その1 (code conventions 1)

弊社にはプログラミングを行う際のコーディング規約があり、Sofitiesを含めた自社プロジェクトは勿論、請負業務などで先方から指定された規約が無い限り常にこれが適用されている。

業界で一般的に推奨されているものとは異なるものや時代錯誤的なものがあり、また多少流動的でもあるが、全く合理性を欠くものではない。
幾つか紹介してみよう。

字下げは、タブ文字を使用(use tab character for indentation)

XMLには空白文字(半角スペース) 4字以下の字下げを使用することがあるが、そのほかの言語ではほぼ例外なくタブを使用する。
Digital Reserch社の CP/M 2.2時代の名残である。
当時は主記憶、外部記憶の容量が小さかったため空白文字を沢山並べるのは不経済であった。
タブ文字を使用すると多くの場合ファイルサイズが半分以下になる。
欠点としては、タブ文字と空白文字を混在させてしまうと、醜くみにくくなること。

8タブを使用(8 characters tab stop)

弊社の規約の多くが Kernighan and Ritchieの "THE C PROGRAMMING LANGUAGE"に由来しているが、これは例外の一つ。
同書では原点、共立出版による邦訳版ともに 5文字タブを使用している。
多くのテキストエディタが 4または 8文字がデフォルトであることを考えると、5文字は半端である。
4タブを使用する会社が多い中、8タブを使用する理由はつぎの通り。
8タブを使用すると、ネストを深くしたときに内容がどんどん右にいってしまう。すると4タブを使用したい誘惑に駆られるが、そうしてしまうと 1個の関数、サブルーチンが複雑になってしまう。
8タブを守らせることによって、ネストが深くなりそうなときに関数を分割する習慣が付くようになる。

1行は 80文字以下(line length limit at 80 characters)

文字端末は 80文字までしか表示できないものが多かった。
ビットマップが主流となった現在ではハード的な理由は無くなった。しかし、画面が広くなったからと言って際限なく長い行はいただけない。
目で追うときに画面の右端まで行って、つぎの行の先頭に戻るときに見失ってしまう。 況してや左右方向にスクロールさせるなどは持っての外である。
画面を左右に並べてマージ作業するときなどを考えると 80文字くらいが丁度良い。

空白のとり方(spacing)

つぎのいづれかの文字の後には原則として空白類が必要、前には置かない。 ',', '.', ';', ':', '!', '?', ')', '}', ']'
例)
    a[i] = 0;           RIGHT
    a [ i ]= 0;         WRONG


単項演算子のうち次のものの後には空白類は置かない。 '*'(C, C++), '&'(C, C++), '-', '!', '~', キャスト, 前置の '++', '--'
例)
    void *p;            RIGHT
    void * p;           WRONG

    --index             RIGHT
    -- index            WRONG

    (int)longValue      RIGHT
    (int) longValue     WRONG


後置の "++", "--"の前後には空白類は置かない。
例)
    pointer++;          RIGHT
    pointer ++ ;        WRONG


乗法演算子、加法演算子、シフト演算子、関係演算子、等値演算子、ビットごとの演算子、論理的演算子、条件演算子、代入演算子の前後には空白類が必要。
例)
    a = b + c;          RIGHT
    a=b+c;              WRONG


次の演算子の前後には空白文字は置かない。 '.', "->"(C, C++), "::"(C++) ただし、行を折り返す場合は可。
例)
    record->field1 = 0;         RIGHT
    record -> field1 = 0;       WRONG


関数の宣言、定義、呼び出し時の小括弧の前には空白は置かない。
例)
    printf("Hello.\n");         RIGHT
    printf ("Hello.\n");        WRONG


関数の宣言、定義、呼び出しの小括弧の内側には引数、パラメタをコマで区切る箇所を除いて空白は置かない。
例)
    Math.max(a, b)      RIGHT
    Math.max( a, b )    WRONG


関数呼び出しの跡の乗法演算子、加法演算子、シフト演算子、関係演算子、等値演算子、ビットごとの演算子、論理的演算子、条件演算子、代入演算子との間には空白類が必要。それ以外には置かない。
例)
    fabs(v) < 1.0               RIGHT
    fabs(v)< 1.0                WRONG

    fp = fopen("text", "r");    RIGHT
    fp = fopen("text", "r") ;   WRONG
キーワードと小括弧の間には空白文字が必要。ただし、sizeof演算子の場合は置かない。
例)
    if (true)           RIGHT
    if(true)            WRONG

    sizeof(int)         RIGHT
    sizeof (int)        WRONG
sizeof演算子は括弧つきで使用する。
例)
    sizeof(int)         RIGHT
    sizeof int          WRONG
ブロックの中括弧の前には空白が必要。
例)
    if (true) {         RIGHT
    if (true){          WRONG

中括弧の取り扱い (braces)

条件分岐や繰り返しの制御構文の中が単一の文の場合はブロックを使用しない。
例)
    if (end)            RIGHT
            exit(0);

    if (end) {          WRONG
            exit(0);
    }
業界では括弧の対応が不一致になるのを恐れて {を強制する規約が多いと思う。 しかしそれは記述が複雑だったり、ネストが深くなるからであり、シンプルに書くことを心がければ、反って不要な括弧などは付けないほうが良い。 行の折り返しが必要な場合を除いて、{の前で改行しない。
例)
    if (true) {         RIGHT

    if (ture)           WRONG
    {

    int atoi(int i) {   RIGHT

    int atoi(int i)     WRONG
    {
ブロックを使用しない制御構文であっても、条件式の行と制御される行の間は改行する。
例
    while (!end)                RIGHT
            call();

    while (!end) call(); WRONG
} と elseの間は改行しない。
例)
    if (ready) {        RIGHT
      ...
    } else {

    if (ready) {        WRONG
      ...
    }
    else {

文字コードは UTF-8 (using UTF-8)

2000年ころまでは EUC-JPを使用していたが、中国語などの日本語以外の文字を混在させようとしたときを考慮して、UTF-8に切り替えられた。
お尻かゆい虫~

0 件のコメント:

コメントを投稿