Scintilla icon Scintilla

コーディングスタイル Code Style

はじめに Introduction

Scintilla と SciTE のソースコードは私のスタイルに従って書かれています。いくつかの規定は任意のもので、私の好みに基づいたものです。とはいえ、それが誰もが満足するような形ではなかったとしても、全てのコードが同じような形で書かれていることはよいことです。

The source code of Scintilla and SciTE follow my preferences. Some of these decisions are arbitrary and based on my sense of aesthetics but its good to have all the code look the same even if its not exactly how everyone would prefer.

この規定に沿わないコードがあっても構いませんが、時間の経過とともに規定に従うように書き換えられるでしょう。Scintilla のコードは SciTE よりも厳しめに規定に従っています。ただし SciTE のなかでも解析器(lexer)は、相対的に独立したモジュールなので例外です。警告に対する修正する以外は、他の人々に保守されている解析器はそのままにしています。この結果プロジェクト全体としてはエラーを起こさずにコンパイルができます。

Code that does not follow these conventions will be accepted, but will be modified as time goes by to fit the conventions. Scintilla code follows the conventions more closely than SciTE except for lexers which are relatively independent modules. Lexers that are maintained by others are left as they are submitted except that warnings will be fixed so the whole project can compile cleanly.

'-tapO' 引数を指定した Astyle 書式準拠プログラムは、Astyle にいくつか瑕疵があるもののおおよそのところで正しく動作します。 scite/scripts/Fixer.py にあるスクリプトは Astyle を C++ ソースファイルに適用し、それらの瑕疵を修正します。

The AStyle formatting program with a '-tapO' argument formats code in much the right way although there are a few bugs in AStyle. The scite/scripts/Fixer.py script will run AStyle over a C++ source file and fix up some of those bugs.

言語の機能 Language features

Scintilla と SciTE の目標の一つに、いろいろな環境上の現在利用可能な C++ コンパイラが利用可能で、高い性能と低いリソース消費を保つことがあります。Scintilla は SciTE より厳しい可搬性要求があります。Windows CE や PalmOS のような条件の厳しい環境にも移植されているからです。SciTE はこれよりも多少条件がゆるやかになります。

Design goals for Scintilla and SciTE include portability to currently available C++ compilers on diverse platforms with high performance and low resource usage. Scintilla has stricter portability requirements to SciTE as it may be ported to low capability platforms such as Windows CE or PalmOS but it is less likely SciTE will be.

移植性を高めるため、C++ の一部の機能だけを使います。環境によっては例外処理ができません(Windows CE など)。これに伴い標準 C++ ライブラリは使えないことになります。コンパイラによってはテンプレートの挙動が違うため、Scintilla では使えません。ただし、SciTE では単純なテンプレートは使えるようにしています。実行時型情報はメモリを消費するため使えないことにします。名前空間は使いません。

To achieve portability, only a subset of C++ features are used. Exceptions are not available on some platforms such as Windows CE so exceptions are not used and thus the standard C++ library can not be used. Template support differs between compilers so is not used in Scintilla but there are some simple uses in SciTE. Run-time type information adds to memory use so is turned off. Name spaces are not used.

私の初めての仕事であった FORTRAN プログラムの保守はひどい思い出でしたので goto 文は使いません。共用体は型安全性が崩れる元となるため使いません。

The goto statement is not used because of bad memories from my first job maintaining FORTRAN programs. The union feature is not used as it can lead to non-type-safe value access.

キャストについて Casting

(char *)s のような、C 言語で使われていた方式の古いキャストは使用禁止です。const_cast<char *>(s) というように C++ で新設されたキャストうちの最も厳しい条件のものを使ってください。可能な限り reinterpret_cast よりも static_cast と const_cast を使います。実行時型情報を使用不可にしてコンパイルしますので、dynamic_cast は動作しないでしょう。

Do not use old C style casts like (char *)s. Instead use the most strict form of C++ cast possible like const_cast<char *>(s). Use static_cast and const_cast where possible rather than reinterpret_cast. Because the code is compiled with run-time type information turned off, dynamic_cast will not work.

新しい形のキャストを使うことで、どのようなよくないことが起きているかの詳細がはっきりし、潜在的には危険なことが行われていることの印として役に立ちます。

The benefit to using the new style casts is that they explicitly detail what evil is occurring and act as signals that something potentially unsafe is being done.

const を丁寧に扱うコードは人間にとってもコンパイラに対しても大きな説明の力を持ちます。ですから const_cast を避けて const 変数を用いてください。

Code that treats const seriously is easier to reason about both for humans and compilers, so use const parameters and avoid const_cast.

警告について Warnings

しっかり書かれた可搬性のあるコードであることを保証するために、ほぼ全ての警告機能を有効にしてコンパイルします。この結果、全く問題のないコードに対して警告が出ることがありますが、警告が出ないように修正するほうが一般的には高速化になり、可読性もほとんど落ちません。

(訳注: 原文の false positives も考慮に入れると「ぱっと見には理不尽だけれども実は意味があって正しい」というようなインテリすぎるコードはやめとけ、という趣旨と思われます。この節に限りませんが、C よりも C++ の理念に近いものと言えるでしょう。)

To help ensure code is well written and portable, it is compiled with almost all warnings turned on. This sometimes results in warnings about code that is completely good (false positives) but changing the code to avoid the warnings is generally fast and has little impact on readability.

全ての変数は明示的に初期化し、変数の有効範囲は可能な限り小さくしてください。利用する直前に変数を定義しておけばそれより前のコードで誤ってその変数を使うことはなくなります。C++ 標準と現在利用できるコンパイラで同じ動作をする繰り返し構文を用いましょう。

Initialise all variables and minimise the scope of variables. If a variable is defined just before its use then it can't be misused by code before that point. Use loop declarations that are compatible with both the C++ standard and currently available compilers.

メモリ割り当てについて Allocation

例外処理は使いませんので、メモリリソースの枯渇が起こりえます。これは検査され制御されるべきですが Scintilla と SciTE の実に大量のコードはこれを行っていません。

As exceptions are not used, memory exhaustion can occur. This should be checked for and handled but there is quite a lot of Scintilla and SciTE code that doesn't yet. Fixed length buffers are often used as these are simple and avoid the need to worry about memory exhaustion but then require that buffer lengths are respected.

型安全性という理由から、C++ の new と delete 演算子が C の malloc と free より好まれます。

The C++ new and delete operators are preferred over C's malloc and free as new and delete are type safe.

(波)括弧の書き方について Bracketing

開き波括弧 '{' は制御構造が始まる行に置かれるべきです。また閉じ波括弧 '}' は開始行と同じ字下げ位置に書かれるべきです。else 節がある場合は '}' と同じ行に置きます。この形を取ることで、他の習慣よりも行数を減らし一画面内にたくさんのコードを表示させることができます。完全な波括弧による制御構造が好まれます。変更が正しく行われ、Scintilla の折りたたみが動作するからです。

return 文は括弧なしで、つまり関数としてではなくキーワードとして使います。

Start brackets, '{', should be located on the line of the control structure they start and end brackets, '}', should be at the indented start of a line. When there is an else clause, this occurs on the same line as the '}'. This format uses less lines than alternatives, allowing more code to be seen on screen. Fully bracketed control structures are preferred because this makes it more likely that modifications will be correct and it allows Scintilla's folder to work. No braces on returned expressions as return is a keyword, not a function call.

bool fn(int a) {
        
if (a) {
                
s();
                
t();
        
} else {
                
u();
        
}
        
return !a;
}

空白について Spacing

'=' の両側と比較演算子の両側に置きます。'=' を並べることはしません(訳注:代入文の連続などで縦に並べる場合の話か)。
呼び出しに使う '(' の前後には置きません。',' の後には置きます。
短いトークンどうしの間には置きませんが、長いトークンがある場合は置くこともあります。
'{' の前には置きます。':' の前には置きません。
ポインタの '*' の後には置きません。'[' と ']' の後には置きません。
予約語と '(' の間には置きます。

Spaces on both sides of '=' and comparison operators and no attempt to line up '='. No space before or after '(', when used in calls, but a space after every ','. No spaces between tokens in short expressions but may be present in longer expressions. Space before '{'. No space before ';'. No space after '*' when used to mean pointer and no space after '[' or ']'. One space between keywords and '('.

void StoreConditionally(int c, const char *s) {
        
if (c && (baseSegment == trustSegment["html"])) {
                
baseSegment = s+1;
                
Store(s, baseSegment, "html");
        
}
}

名前について Names

識別子は大文字小文字を混ぜて使い、下線文字は使いません。クラス・関数・メソッドの名前は大文字で始まり、その後は単語の先頭毎に大文字を使います。変数は小文字で始まり、それ以後はやはり単語の先頭毎に大文字にします。反復カウンタや同種の変数は 'i' といった単純な名前を使うことができます。メソッド呼び出しとそうでない広域関数呼び出しを区別できるようにすべきです。'::' から始まる表現で広域スコープ関数であることを示してください。

Identifiers use mixed case and no underscores. Class, function and method names start with an uppercase letter and use further upper case letters to distinguish words. Variables start with a lower case letter and use upper case letters to distinguish words. Loop counters and similar variables can have simple names like 'i'. Function calls should be differentiated from method calls with an initial '::' global scope modifier.

class StorageZone {
public:
        
void Store(const char *s) {
                
Media *mediaStore = ::GetBaseMedia(zoneDefault);
                
for (int i=mediaStore->cursor; mediaStore[i], i++) {
                        
mediaStore->Persist(s[i]);
                
}
        
}
};