PEP 7 -- Style Guide for C Code

| **PEP:**  | 7                                                                          |
| --------- | -------------------------------------------------------------------------- |
| **タイトル:** | Style Guide for C Code                                                     |
| **著者:**   | Guido van Rossum <guido at python.org>, Barry Warsaw <barry at python.org> |
| **ステータス** | Active                                                                     |
| **タイプ:**  | Process                                                                    |
| **作成日:**  | 2001年07月05日                                                                |
| **投稿履歴:** |                                                                            |

----------

目次

- イントロダクション
- C言語の方言
- コードレイアウト
- 命名規則
- ドキュメンテーション文字列
- 参照
- 著作権

# イントロダクション

このドキュメントはPythonの実装を網羅しているC言語のコーディングスタイルについて記述されている。PythonのスタイルガイドについてはPEP 8 [1] を見てほしい。

注意: ルールは破るためにある。二つの良い理由で特定のルールを破る。

1. ルールに従ったコードを読みなれている人でも、ルールを適用することでコードが読みづらくなる時
2. 周囲のコードと一貫性を持たせるとき(恐らく歴史的理由で) — これは(本当のExtream Programmingで)他の誰かの混乱を取り除く良い機会ではあるのだが

# C言語の方言
- バージョン3.6以前のPythonはANSI/ISO標準のC言語(標準の1989年版)を使っている。

これは、全ての宣言はブロックの先頭でなければならないことを意味している(関数の先頭でなくても構わない)。

- バージョン3.6以降のPythonはC99の特徴をいくつか取り入れたC89を使っている。
  - `<stdint.h>`と`<inttypes.h>`の標準整数型。固定長の整数型を必要としているため。
  - `static inline`関数
  - 指示付きの初期化子
  - intermingled declarations(訳注: 変数宣言をブロックの最初にしなくても良いものらしい)
  - ブール型
  - C++スタイルの行コメント

コンパイラのサポートによって、将来のC99の特徴もこのリストに加わることになるだろう。(ほとんど有意的にMSVC)

- GCC拡張は使わない(例えば、末尾のバックスラッシュなしに複数行の文字列を書くなど)
- 全ての関数宣言と定義は完全なプロトタイプを使う(言い換えれば、全ての引数の型を指定する)。
- Python 3.6以降ではC++スタイルの `//` 行コメントのみを使用する。
- メジャーなコンパイラ(gcc, VC++, その他)で警告されない。


# コードレイアウト
- 4つのスペースを使用し、タブは絶対に使用しない。
- どの行も79文字を超えてはいけない。もしこのルールと前のルールがあなたに十分なコードのスペースを与えないなら、あなたのコードは複雑すぎる。 — サブルーチンを使うのを考慮してほしい。
- どの行も空白文字で終わってはいけない。もし、意味ある末尾の空白文字がほしいと思うなら、考え直す — 誰かのエディタがそれをルーチンの問題として削除するかもしれない。
- 関数定義のスタイル: インデント1つ目に関数の名前、インデント1つ目にもっとも外側の波括弧、ローカル変数宣言の後に空白行。

```c
    static int
    extra_ivars(PyTypeObject *type, PyTypeObject *base)
    {
        int t_size = PyType_BASICSIZE(type);
        int b_size = PyType_BASICSIZE(base);
    
        assert(t_size >= b_size); /* type smaller than base! */
        ...
        return 1;
    }
```

- コードの構造: `if`や`for`などのキーワードのあとに1スペースあけ次の左丸括弧; 丸括弧の内部にはスペースなし。波括弧は例えC言語が省略可能としていても常に必要だが、あなたが修正していないコードには加えてはいけない。全ての追加されるC言語のコードは波括弧が必要だ。波括弧は以下のようにフォーマットされる。

```c
    if (mro != NULL) {
        ...
    }
    else {
        ...
    }
```

- `return`文では余計な丸括弧を**つけ*****ない***。

```c
    return albatross; /* correct */
    return(albatross); /* incorrect */
```

- 関数とマクロの呼び出しスタイル: `foo(a, b, c)` — 開き丸括弧の前にスペースなし、丸括弧の内部にスペースなし、カンマの前にスペースなし、それぞれのカンマの後に1スペース。
- 代入文、ブール演算子、比較演算子の周囲には常にスペースを置く。多くの演算子を使用する式では、もっとも外側の演算子の周囲にスペースを置く(優先度低め)。
- 長い行は改行する: 可能ならば、もっとも外側のカンマの後に改行する。常に続く行は適切にインデントする。例えば、

```c
    PyErr_Format(PyExc_TypeError,
                 "cannot create '%.100s' instances",
                 type->tp_name);
```

- バイナリ演算子で長い式を改行する時、その演算子は前の行の最後に置き、波括弧は以下のようにフォーマットする。

```c
    if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
        type->tp_dictoffset == b_size &&
        (size_t)t_size == b_size + sizeof(PyObject *))
    {
        return 0; /* "Forgive" adding a __dict__ only */
    }
```

- 空白行を関数定義、構造体定義、関数の大きなセクションの周囲に置く。
- コメントは記述するコードの前に置く。
- 公開されたインターフェースの一部でない限り、全ての関数とグローバル変数はstaticで宣言する。
- `PyAPI_FUNC()`マクロを使用するexternal関数とexternal変数は、「Include」ディレクトリに然るべきヘッダファイルに宣言がある。例えばこのように:

```c
    PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
```

# 命名規則
- プレフィックスとしてPyをつける; static関数には決してつけない。`Py_`プレフィックスは`Py_FatalError`のようにグローバルなサービスのルーチンとして予約されている; 特定のルーチンのグループ(例えば、特定のオブジェクトのAPI)には長いプレフィックスがついている。文字列関数には`PyString_`がついているように。
- Publicな関数と変数は下線によるミックスケースが使われる。例えば、`PyObject_GetAttr`, `Py_BuildValue`, `PyExc_TypeError`。
- 時折、内部関数がローダーに対して見えている必要がある。その場合は、`_PyObject_Dump`のように`_Py`プレフィックスをつけている。
- マクロはミックスケースのプレフィックスでUPPERケースを使われる。例えば、`PyString_AS_STRING`, `Py_PRINT_RAW`。


# ドキュメンテーション文字列
- ドキュメンテーション文字列を使わず(`./configure` `--``without-doc-strings`)にPythonをビルドするには、`PyDoc_STR`か`PyDoc_STRVAR()`マクロをドキュメンテーション文字列に使う。


  Python 2.3より古いバージョンのサポートが必要なC言語のコードのために、`Python.h`をインクルードした後にこれをインクルードすることができる。

```c
    #ifndef PyDoc_STR
    #define PyDoc_VAR(name)         static char name[]
    #define PyDoc_STR(str)          (str)
    #define PyDoc_STRVAR(name, str) PyDoc_VAR(name) = PyDoc_STR(str)
    #endif
```


- それぞれの関数のドキュメンテーション文字列の最初の行は引数と戻り値について記述したシグネチャ行であるべきだ。例えば、

```c
    PyDoc_STRVAR(myfunction__doc__,
    "myfunction(name, value) -> bool\n\n\
    Determine whether name and value make a valid pair.");
```

  シグネチャ行と説明の間には常に1行入れる。


  もし関数の戻り値が常にNone(戻り値に意味がない)なら、戻り値については記述してはいけない。


- 複数行のドキュメンテーション文字列を書く場合は、続く行の前にバックスラッシュが入っていることを確認する。上記の例のように、または文字列リテラルの連結で、

```c
    PyDoc_STRVAR(myfunction__doc__,
    "myfunction(name, value) -> bool\n\n"
    "Determine whether name and value make a valid pair.");
```

  いくつかのC言語のコンパイラは上記のどちらでもない文字列リテラルを受け入れる。

```c
    /* BAD -- don't do this! */
    PyDoc_STRVAR(myfunction__doc__,
    "myfunction(name, value) -> bool\n\n
    Determine whether name and value make a valid pair.");
```

  すべてではないが、MSVCはこれについて文句を言うことで知られている。
# 参照

[1] PEP 8, "Style Guide for Python Code", van Rossum, Warsaw (http://www.python.org/dev/peps/pep-0008)

# 著作権

このドキュメントはパブリックドメインで公開されている。
ソース: https://github.com/python/peps/blob/master/pep-0007.txt