web-dev-qa-db-ja.com

グローバル変数の前に静的キーワードを使用する場合

ヘッダーファイルで定義されたグローバル変数または定数の前に静的キーワードを使用することになっている場合、誰かが説明できますか?

たとえば、次の行を含むヘッダーファイルがあるとします。

const float kGameSpriteWidth = 12.0f;

staticの前にconstがあるかどうかstaticを使用するためのベストプラクティスは何ですか?

62
Matt Rajca

staticは、変数をファイルに対してローカルにレンダリングします。これは一般に良いことです。たとえば、 このWikipediaエントリ を参照してください。

49

defineヘッダーファイル内のグローバル変数は使用しないでください。それらを.cソースファイルで定義する必要があります。

  • グローバル変数を1つの.cファイル内でのみ表示する場合、静的変数として宣言する必要があります。

  • グローバル変数を複数の.cファイルで使用する場合は、静的変数として宣言しないでください。代わりに、必要なすべての.cファイルに含まれるヘッダーファイルでexternを宣言する必要があります。

例:

  • example.h

    extern int global_foo;
    
  • foo.c

    #include "example.h"
    
    int global_foo = 0;
    static int local_foo = 0;
    
    int foo_function()
    {
       /* sees: global_foo and local_foo
          cannot see: local_bar  */
       return 0;
    }
    
  • bar.c

    #include "example.h"
    
    static int local_bar = 0;
    static int local_foo = 0;
    
    int bar_function()
    {
        /* sees: global_foo, local_bar */
        /* sees also local_foo, but it's not the same local_foo as in foo.c
           it's another variable which happen to have the same name.
           this function cannot access local_foo defined in foo.c
        */
        return 0;
    }
    
90

はい、静的を使用します

別の.cモジュールからオブジェクトを参照する必要がない限り、.cファイルでは常に静的を​​使用します。

含まれるたびに異なるオブジェクトを作成するため、.hファイルでstaticを使用しないでください。

21
DigitalRoss

ヘッダーファイルの経験則:

  • 変数をextern int foo;として宣言し、対応する初期化を単一のソースファイルに入れて、翻訳単位間で共有される変更可能な値を取得します。
  • static const int foo = 42;を使用して、インライン化できる定数を取得します
8
Christoph

グローバル変数の前のstaticは、この変数が定義されているコンパイルモジュールの外部からアクセスできないことを意味します。

例えば。別のモジュールの変数にアクセスしたいと想像してください:

foo.c

int var; // a global variable that can be accessed from another module
// static int var; means that var is local to the module only.
...

bar.c

extern int var; // use the variable in foo.c
...

varを静的であると宣言すると、foo.cがコンパイルされているモジュール以外からはアクセスできません。

モジュールは現在のソースファイルであることに注意してください。plusすべてのインクルードファイル。つまり、これらのファイルを個別にコンパイルし、それらを一緒にリンクする必要があります。

4
AraK

Cでは、staticキーワードを使用して、関数の可視性をrestrictにしますまたは変数からその翻訳単位へ。変換単位は、オブジェクトファイルが生成されるCコンパイラへの最終的な入力です。

これを確認してください: Linkage | 翻訳単位

3
p.j

匿名名前空間でのC++の正しいメカニズム。ファイルに対してローカルなものが必要な場合は、静的修飾子ではなく匿名名前空間を使用する必要があります。

0
rmn