статическая функция в с - PullRequest
       0

статическая функция в с

2 голосов
/ 09 сентября 2011

Я думал, что функция в C, которая объявлена ​​статической, видна только в файле, где я ее определил. В следующем примере статическая переменная видна в другом файле. я не совсем уверен, если это из-за включения:

main.c:

#include "test.c"

int main() {
    test();
}

test.c:

static void test() {
    // do something here
}

void foo() {
   // do something different here
}

если он работает только с заголовочным файлом, разве это не совершенно бесполезно? Если я хочу скрыть функцию, я не упоминаю ее в заголовочном файле?!

Ответы [ 3 ]

7 голосов
/ 09 сентября 2011

#include является директивой препроцессора.Когда препроцессор (запускаемый перед компиляцией) увидит его, он скопирует туда содержимое включенного файла.Таким образом, вы получите его в том же файле.

, если он работает только с заголовочным файлом, разве он не бесполезен?если я хочу скрыть функцию, то я не упоминаю ее в заголовочном файле?!

Конечно, но если не упомянуть ее в заголовочном файле, она не будет "скрыта".Заголовочный файл не скомпилирован, если вы разместите там свои прототипы, он станет подсказкой для компилятора.

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

5 голосов
/ 09 сентября 2011

Функция в C, объявленная как статическая, видна только в той единице перевода, в которую она включена, это означает, что символ не экспортируется. Это не имеет ничего общего с файлами, но с единицами перевода. В вашем случае есть один модуль перевода - main.c, который включает в себя содержимое другого файла, определяющего main, test и foo; main и foo будут экспортированы, а test - нет.

1 голос
/ 09 сентября 2011

Если бы main.c и test.c были отдельными единицами перевода , вы были бы правы.Однако, включив текст test.c непосредственно в main.c, вы создали одну единицу перевода, так что статическая функция видна main.Он ведет себя , как если бы вы записали все как один файл.

Вы не хотите #include файлы, содержащие переменную или функцию определения ;Это хороший способ столкнуться с несколькими ошибками определения во время компиляции или компоновки.Вместо этого содержимое файлов #include должно быть ограничено определениями типов, объявлениями неопределенных переменных и объявлениями функций.

Вы можете создать файл test.h следующим образом:

#ifndef TEST_H  // include guard; prevents this file from being processed
#define TEST_H  // more than once per translation unit

void foo();     // declaration for foo; this is the only function we're exposing

#endif

, затем переписать main.c как

#include "test.h"

int main(void)
{
  test();
  return 0;
}

Затем вы скомпилируете main.c и test.c отдельно, а затем связать получившиеся объектные файлы для создания вашего исполняемого файла:

gcc -c main.c
gcc -c test.c
gcc -o test main.o test.o

На этом этапе вы получите ошибку компоновщика в порядке «неопределенной ссылки», поскольку символ для test hasnне был экспортирован.

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