web-dev-qa-db-ja.com

ヘッダーの静的変数を初期化する

私はCでのプログラミングに不慣れなので、言語に慣れるためにさまざまなことを試みています。

私は次のように書いた:

ファイルq7a.h

static int err_code = 3;
void printErrCode(void);

ファイルq7a.c

#include <stdio.h>
#include "q7a.h"

void printErrCode(void)
{
        printf ("%d\n", err_code);
}

ファイルq7main.c

#include "q7a.h"

int main(void)
{
        err_code = 5;
        printErrCode();

        return 0;
}

次に、メイクファイルで次のコマンドを実行しました(Linux OSを使用しています)

gcc –Wall –c q7a.c –o q7a.o
gcc –Wall –c q7main.c –o q7main.o
gcc q7main.o q7a.o –o q7

出力は3です。

なんでこんなことが起こっているの?

ヘッダーファイルで静的変数(実際には任意の変数)を初期化する場合、2つのファイルに同じヘッダーファイル(この場合はq7.cとq7main.c)が含まれていると、リンカーは2回定義するとエラーが発生します。同じ変数?

そして、なぜ値5が静的変数に挿入されないのですか(結局のところ、静的でグローバルです)?

助けてくれてありがとう。

12
darven

staticは、変数がコンパイルユニット内でのみ使用され、リンカーに公開されないことを意味します。したがって、ヘッダーファイルにstatic intがあり、2つの別々の.cファイルからインクルードする場合、そのintの2つの個別のコピーがありますが、これはほとんどの場合、必要なものではありません。

代わりに、extern intを検討し、それを実際に定義する.cファイルを1つ選択することができます(つまり、int err_code=3だけ)。

39
EboMike

静的変数には外部リンケージがないため、静的変数が定義されている変換単位の外部からアクセスすることはできません。したがって、q7.hが両方の翻訳単位q7a.cとq7main.cに#includeされている場合、対応する.oファイルに2つの異なるコピーが存在します。これが、外部シンボルリンケージを実行しているときに両方のコピーがリンカーに表示されないため、リンカーがエラーを報告しない理由です。

4
Amit

変数を静的として宣言した場合、その変数はファイル内のスコープのみを持ちます。つまり、ファイル内でのみアクセスできます。ヘッダーファイルで静的変数を宣言し、このヘッダーファイルを2つの.cファイルにインクルードすると、2つの異なる「.c」ファイル用に2つの異なるメモリが作成されます。

Main関数でerr_codeを直接出力すると、その値は3ではなく5と表示されますが、err_codeが異なるメモリ位置を持つ別のファイル「q7a.c」で定義されている関数printErrCodeを呼び出しています。はまだ3であり、更新されていないため、値は5ではなく3になります。

2つのメモリが作成され、err_codeは、異なるファイルスコープを持つ異なるメモリを持つ2つの異なる変数と見なされるため、リンクエラーは発生しません。

1
bvprakash

小さな調査をしていると、ヘッダーファイルで変数を宣言できることがわかりましたが、ソースファイルの1つには、その変数の定義が含まれている必要があります。

代わりに、ヘッダーファイルで変数を定義する場合。このヘッダーファイルが含まれているソースファイルでは、複数の定義が発生する定義が作成されます。

静的変数は、使用するファイルで宣言する必要があり、ヘッダーファイルに公開しないでください。

私が正しい情報を提供していることを願っています。私が間違っている場合は、コメントの私の記述を自由に修正してください。

0