是否有可能在文件范围之外评估静态功能。 ?
答案 0 :(得分:19)
这取决于“访问”的含义。当然,函数不能在任何其他文件中通过名称调用,因为它在不同的文件中是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
答案 1 :(得分:16)
可以通过函数指针从作用域外部调用它。
例如,如果你有:
static int transform(int x)
{
return x * 2;
}
typedef int (*FUNC_PTR)(int);
FUNC_PTR get_pointer(void)
{
return transform;
}
然后范围外的函数可以调用get_pointer()并使用返回的函数指针来调用transform。
答案 2 :(得分:12)
不,除非编译器中存在错误。通常情况下,静态函数代码没有用于在目标文件中导出函数的名称,因此它不会显示给链接器,也不能链接到它。
这当然仅适用于按名称调用函数。同一文件中的其他代码可以获取函数地址并将其传递到另一个文件中的非静态函数,然后另一个文件中的函数可以调用您的静态函数。
答案 3 :(得分:6)
无法通过文件名在文件外访问它。但是,你也可以将它分配给函数指针并在任何你想要的地方使用它。
答案 4 :(得分:5)
“访问”?这取决于你对这个术语的意思。我假设当你说“静态函数”时,你所说的是独立函数声明static
(即用内部链接声明),而不是C ++中的静态类成员函数,因为后者可以从任何地方轻松地访问。
现在,声明为static
的独立函数具有内部链接。它不能从任何其他翻译单元链接到。或者,换句话说,它不能从任何其他翻译单元引用名称。如果你的意思是“从文件范围之外访问”,那么不,它就无法完成。
然而,如果其他翻译单元以某种方式得到一个指向该函数的指针(即如果你以某种方式允许该指针“泄漏”到ouside世界),那么任何人仍然可以通过进行idirect调用来调用该函数,因此“访问“它。例如,如果您声明
static void foo_static(void) {
}
extern void (*foo_ptr)(void) = foo_static;
然后在任何其他翻译单元中,用户将能够
extern void (*foo_ptr)(void);
foo_ptr();
,通话将转到foo_static
功能。我不知道这种访问是否符合你问题中的“访问权限”。
答案 5 :(得分:4)
遵循标准,无法在文件按名称的范围之外访问静态函数,因为它受内部链接的约束。它的名称未导出,也未提供给链接器。但是,它仍然可以被函数指针访问和调用,就像任何其他函数一样。
答案 6 :(得分:3)
只有诡计。该函数通常对链接器不可见,因此它不允许您这样做。
但是,如果你在同一个编译单元(作为静态函数)中提供一个返回该函数地址的函数:
在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
答案 7 :(得分:1)
不,关键字static的目的是将函数名称的范围限制为文件。