Статическая функция доступа в другие файлы - PullRequest
13 голосов
/ 02 февраля 2010

Есть ли вероятность, что статическая функция может быть оценена вне области файла.

Ответы [ 8 ]

19 голосов
/ 02 февраля 2010

Это зависит от того, что вы подразумеваете под «доступом». Конечно, функция не может быть вызвана по имени в любом другом файле, так как она static в другом файле, но у вас есть указатель на нее.

$ cat f1.c
/* static */
static int number(void)
{
    return 42;
}

/* "global" pointer */
int (*pf)(void);

void initialize(void)
{
    pf = number;
}
$ cat f2.c
#include <stdio.h>

extern int (*pf)(void);
extern void initialize(void);

int main(void)
{
    initialize();
    printf("%d\n", pf());
    return 0;
}
$ gcc -ansi -pedantic -W -Wall f1.c f2.c
$ ./a.out
42
16 голосов
/ 02 февраля 2010

Он может быть вызван из области видимости через указатель функции.

Например, если у вас было:

static int transform(int x)
{
    return x * 2;
}

typedef int (*FUNC_PTR)(int);

FUNC_PTR get_pointer(void)
{
    return transform;
}

, то функция вне области действия может вызвать get_pointer () и использоватьвозвращенный указатель на функцию для вызова преобразования.

12 голосов
/ 02 февраля 2010

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

Это, конечно, относится только к вызову функции по имени. Другой код в том же файле может получить адрес функции и передать его в нестатическую функцию в другом файле, а затем функция из другого файла может вызвать вашу статическую функцию.

6 голосов
/ 02 февраля 2010

Он не доступен вне файла по его имени. Но вы также можете назначить его указателю на функцию и использовать его где угодно.

5 голосов
/ 02 февраля 2010

"Accessed"? Это зависит от того, что вы подразумеваете под этим термином. Я предполагаю, что когда вы говорите «статическая функция», вы имеете в виду автономную функцию, объявленную static (то есть объявленную с внутренней связью), в отличие от статических функций-членов класса в C ++, поскольку последние очевидны и легко доступны из любого места.

Теперь объявленная автономная функция static имеет внутреннюю связь. Он не может быть связан с из любой другой единицы перевода. Или, говоря иначе, к ней нельзя обращаться по имени из любой другой единицы перевода. Если это то, что вы имели в виду под «доступом извне области действия файла», то нет, это невозможно сделать.

Однако, если другие блоки перевода каким-то образом получают указатель на эту функцию (т. Е. Если вы каким-то образом позволяете этому указателю «просочиться» в чужой мир), тогда любой может по-прежнему вызывать эту функцию, сделав косвенный вызов и, таким образом, доступ "это. Например, если вы объявите

static void foo_static(void) {
}

extern void (*foo_ptr)(void) = foo_static;

тогда в любом другом переводе пользователь сможет сделать

extern void (*foo_ptr)(void);
foo_ptr();

и вызов перейдет к вашей функции foo_static. Я не знаю, квалифицируется ли такой доступ как «доступ» в вашем вопросе.

4 голосов
/ 02 февраля 2010

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

3 голосов
/ 02 февраля 2010

Только с обманом. Эта функция обычно не видна компоновщику, поэтому она не позволяет вам это делать.

Но, если вы предоставляете функцию внутри того же модуля компиляции (что и статическая функция), которая возвращает адрес этой функции:

В main.c:

#inclde <stdio.h>
int (*getGet7(void))(void);
int main (void) {
        int (*fn)(void) = getGet7();
        printf ("Result is: %d\n", fn());
        return 0;
}

В hidden.c:

static int get7 (void) {
        return 7;
}
int (*getGet7(void)) (void) {
        return get7;
}

Это приведет к вызову статической функции get7.

pax> gcc -o demo main.c hidden.c ; ./demo
Result is: 7
1 голос
/ 02 февраля 2010

Нет, цель ключевого слова static - ограничить область действия имени функции файлом.

...