モジュールの外では見えないようにするので、静的として宣言するのがベストプラクティスだと思います。
これについてどう思いますか。
C++ の場合、静的よりも良いのは、名前のない (匿名の) 名前空間に配置することです。これは、グローバル名前空間の汚染を防ぐための推奨される方法です。
namespace {
void myLocalFunction() {
// stuff
}
}
本当にその .c ファイルにのみ内部的な関数である場合は、はい。グローバル名前空間の汚染を避けるのに役立つはずです。また、関数が静的である場合、他のソースファイルがそれを呼び出す方法を知る必要がないことがわかっているため、コンパイラは呼び出し規約でいくつかの最適化を行うことができると思います。他の人が指摘しているように、c++にはこの問題に対処するための名前空間があるため、これは実際にはcにのみ適用されます。
C++ では、次のように匿名の名前空間を使用する必要があります。
// foo.cpp
namespace
{
class Core { ... };
void InternalFandango(Core *);
}
void SomeGloballyVisibleFunction()
{
InternalFandango(&core);
}
利点: これは struct / class 宣言にも適用できます。
C では、関数を「静的」とマークするだけです。C++ でも "静的" を使用することに反対するものは何もありませんが、名前空間はすべての宣言で機能する単一の概念であるため、名前空間を好むことを学びました。
実装の詳細について多くのことがあり、コンセプトについてはあまりありませんでした。
変数/関数などのスコープを制限することは、実際には良い習慣です。これは、オブジェクト指向設計の基本概念です。つまり、プライベートをプライベートに保つ必要があります。こうすることで、インターフェイスがすっきりし、コードのメンテナンスが容易になります。また、プロジェクトの別の部分の誰かがあなたの関数を気に入って、それを使用することにしたために、プライベートと見なされたものを変更したためにコンパイルが壊れたということはありません。
同意した。結果として、静的関数のプロトタイプは、.h ファイルではなく、.c ファイルの先頭に配置する必要があります。
C では、すべて (関数と変数) をファイル スコープで静的にし、それらがファイルの外部で必要であることを実証できるようにします。その関数だけがそれらを使用し、それらが大きすぎない場合は、関数内で静的にします。基本的に、宣言が関数の残りの部分よりも大きい場合は、宣言を関数の外に置くことができます。もちろん、ソース ファイルによって提供されるパブリック サービスのヘッダーもあります。
C と C++ には異なる制約があると思いますstatic
: C では名前空間がなく、.c ファイルがモジュールであるため、エラーを防ぐためにすべての非パブリック関数を静的にすることが非常に重要です!
匿名名前空間が提供しない、C++ での「静的」のこの使用について私が考えることができる唯一の潜在的に有用なプロパティについては、未使用の静的関数 (デッド コードの形式) に対してオンにできる GCC の警告があることです。 . 匿名の名前空間で使用されていない関数ではそれが得られないため、関数の使用を停止したときにコンパイラに通知してもらいたい場合は、そのようにしてください。
C コードでは、デフォルトで関数を静的にします。非静的関数と、他のモジュールで必要になる関数の .h 宣言のみを作成します。
C++ コードでは、ファイルに対してローカルな関数を無名名前空間に配置し、それらを静的にします。少なくとも GNU コンパイラでは、すべての使用がインライン化されていると関数が書き込まれないため、これにより最適で最小のコードが得られます。インライン化する場合は、もちろん、インライン化する方が静的よりも優れています。
g++ が匿名名前空間にある呼び出されていない関数本体を出力に書き込む理由はまったくわかりませんが、そうです。可視性が隠されている関数も表示されるようです。非表示のシンボルとしてマークされていますが、オブジェクト ファイルに未使用のコード ブロックが生成されています。GCC は、そのような場合にコードが不要であることをおそらく理解していません。または、何かが欠けています。いつでも可能です。
GCC を使用している場合は、可視性フラグを確認する必要があります (完全な説明については、http: //gcc.gnu.org/wiki/Visibilityを参照してください)。
到達不能とマークするのではなく、シンボルを完全に非表示にします。これにより、シンボル テーブルが削減され、リンク時間の短縮に役立ちます。
それだけでなく、それがあなたの求めているものであれば、より多くのインライン化への扉を開きます。
「モジュール」が単に CPP ファイルを意味する場合は、宣言と定義を CPP ファイルに直接配置できます。
C++ では、次のように関数 private を宣言します。
class MyClass
{
public:
void publiclyAccessibleFunction();
private:
void onlyAccesibleFromWithinTheClass();
int some_member_parameter;
};
関数に注意してくださいonlyAccesibleFromWithinTheClass()
。