コーディングスタイル
はじめに
ScintillaとSciTEのソースコードは、私の好みになる。
これらの決定のいくつかは、気まぐれと私の美的センスをベースにするが、すべてのコードを同じに見せることは、皆は好まないだろうか。
これらのコンベンションに続かないコードを受け入れるが、時間がコンベンションに合うように過ぎるとき、変更されるだろう。
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.
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.
言語機能
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.
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.
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.
キャスト
(char *)sのような古いCスタイルのキャストは使わない。
代わりにconst_cast<char *>(s)のようなもっとも厳しい形式のC++のキャストを使う。
static_castとconst_castはreinterpret_castよりも可能なところなら使う。
コードはランタイムタイプ情報がオフにされてコンパイルされているので、dynamic_castは動作しない。
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.
Code that treats const seriously is easier to reason about both for humans and compilers, so use const parameters and avoid const_cast.
警告
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.
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.
確保
例外が使われないとき、メモリ消費が発生できる。
これはチェックすべきであるが、ScintillaおよびSciTEコードにはまだある。
これらが簡単であり、メモリ消費を心配するが、バッファ長が尊重されるのが必要である必要性を避けるとき、固定長バッファはしばしば使用される。
newとdeleteとしてのCのmallocとfreeより安全であるので、C++のnewとdelete操作は好まれる。
括弧
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;
}
空白
'='および比較オペレータの両側に空白を置くが'='の整列はしない。
呼び出しの'('の前または後に空白はないが、','の後に空白は入れる。
短い式の間には空白はないが、長い式には入れてもよい。
'{'の前に空白を入れる。
';'の前に空白はない。
ポインタを意味するために使うとき'*'の後に空白はなく、'['または']'の後に空白はない。
キーワードと'('の間に1個の空白を入れる。
void StoreConditionally(int c, const char *s) {
if (c && (baseSegment == trustSegment["html"])) {
baseSegment = s+1;
Store(s, baseSegment, "html");
}
}
名前
識別子は大文字小文字を混ぜるが下線を使わない。
クラス、関数およびメソッド名は英大文字で始まり、単語を区別するためにさらに英大文字を使用する。
変数は英小文字で始まり、単語を区別するためにさらに英大文字を使用する。
ループカウンタおよび同様な変数は、'i'のように簡単な名前にすることができる。
関数呼び出しは、最初に'::'グローバルスコープ修飾子でメソッド呼び出しと区別すべきである。
class StorageZone {
public:
void Store(const char *s) {
Media *mediaStore = ::GetBaseMedia(zoneDefault);
for (int i=mediaStore->cursor; mediaStore[i], i++) {
mediaStore->Persist(s[i]);
}
}
};