Как заставить этот код компилироваться? - PullRequest
1 голос
/ 25 марта 2010

// Файл: foo.c

static int var;

void foo()
{
var++;
}

// конец файла foo.c

// Файл bar.c:

static int var;

void bar()
{
var++;
}

// конец файла bar.c

// файл main.c

static int var;
void main()
{
foo();
bar();
printf("%d", var);
}

// конец файла main.c

Вопрос: скомпилируется ли вышеуказанная программа? Если так, что будет результатом?

Я протестировал код и обнаружил, что он не может быть скомпилирован. Я пытаюсь использовать extern в main.c, чтобы использовать функции foo () и bar (), но он все еще не может быть скомпилирован.

Ответы [ 4 ]

6 голосов
/ 25 марта 2010

main.c имеет несколько мелких проблем - должно быть что-то вроде этого:

#include <stdio.h>

static int var;

extern void foo();
extern void bar();

int main(void)
{
    foo();
    bar();
    printf("%d\n", var);
    return 0;
}

Должно получиться нормально:

$ gcc -Wall main.c foo.c bar.c -o main

и результат должен быть:

$ ./main
0
4 голосов
/ 26 марта 2010

Я ожидаю, что он скомпилирует и выведет 0 (хотя, если вы хотите скомпилировать его как C ++, вам придется добавить объявления для foo() и bar(), а в C или C ++ вы можете получить предупреждение о том, что main() действительно должно возвращать int).

Поскольку var определено как статическое в каждом из трех файлов, у вас действительно есть три отдельные переменные, которые случайно имеют одно и то же имя. Возможно, проще всего думать о каждом файле как об определении структуры, содержащей его статические переменные. То, что вы сделали, называется foo(), что увеличивает foo.var. Затем вы позвонили bar(), что увеличивает bar.var. Затем вы распечатали main.var, который был инициализирован нулем и никогда не изменялся.

0 голосов
/ 26 марта 2010

Код (как он есть) будет скомпилирован, и результат будет 0 (как объясняет Джерри), потому что переменная static будет иметь область видимости файла.

Но если вы включите foo.c и bar.c в main.c и скомпилируете как

gcc main.c

тогда результат будет 2, потому что будет только одна глобальная переменная var.

0 голосов
/ 26 марта 2010

Это компилируется для меня (хотя с предупреждением о типе возврата от main()).

Результат с точки зрения того, что main() будет печатать, не определен, поскольку вы не инициализировали значение var в main.c. Наиболее вероятный результат, когда компилятор вызывается без оптимизации, равен нулю, поскольку ОС обнулит физическую память, предоставленную процессу для хранения данных (ОС делает это, чтобы избежать утечки конфиденциальных данных между процессами).

Статический спецификатор для определения переменной var означает, что переменная не видна за пределами исходного файла, в котором она определена. Это также означает, что каждая из трех var переменных получает свое собственное место хранения.

Если мы добавим printf("[module name] *var=%p\n", &var) к foo(), bar() и main() соответственно, чтобы напечатать адрес ячейки памяти, в которой хранятся эти три переменные, вы должны получить что-то вроде этого: -

foo() *var=0x8049620
bar() *var=0x8049624
main() *var=0x8049628

Обратите внимание, что каждая переменная получает свое собственное место хранения. Код в каждом исходном файле будет иметь доступ к версии var, определенной для этого исходного файла. Использование static подобным образом в файлах .c обычно используется для реализации концепции сокрытия информации в C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...