инициализация статической переменной в заголовке - PullRequest
12 голосов
/ 01 октября 2010

Я новичок в программировании на 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;
}

Затем я запустил в make-файле следующее (я использую ОС Linux)

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) компоновщик должен выдавать ошибку для определения дважды одного и того же var?

И почему значение 5 не вставляется в статический var (ведь он статический и глобальный)?

Спасибо за помощь.

Ответы [ 3 ]

37 голосов
/ 01 октября 2010

static означает, что переменная используется только в вашем модуле компиляции и не будет доступна для компоновщика, поэтому, если у вас есть static int в заголовочном файле и вы включите его из двух отдельных файлов .c, иметь две отдельные копии этого int, что, скорее всего, совсем не то, что вы хотите.

Вместо этого вы можете рассмотреть extern int и выбрать один файл .c, который фактически его определяет (т. Е. Просто int err_code=3).

3 голосов
/ 01 октября 2010

Статические переменные не имеют внешней связи, что означает, что к ним нельзя получить доступ за пределами единицы перевода, в которой они определены.Так что в вашем случае, когда q7.h # include'ed в обоих модулях перевода q7a.c и q7main.c ... в их соответствующих файлах .o существуют две разные копии.Вот почему компоновщик не сообщает об ошибке, поскольку компоновщик не видит обе копии при выполнении внешней символьной связи.

0 голосов
/ 04 июня 2014

При проведении небольших исследований стало известно, что мы можем объявить переменную в заголовочном файле, но в одном из исходных файлов есть определение, которое должно иметь определение для этой переменной.

Вместо этого, если мы определим переменную в заголовочном файле. в исходных файлах, в которые включен этот заголовочный файл, будут созданы определения, что приведет к нескольким определениям.

Статическая переменная должна быть объявлена ​​в файле, где мы ее используем, она не должна быть открыта для заголовочного файла.

Надеюсь, я даю правильную информацию. Если я ошибаюсь, не стесняйтесь исправлять мои высказывания в ваших комментариях.

...