假设我只想通过传递一个函数指向该函数来从我的一个文件中公开一个函数。将该函数声明为static
是否安全?是否允许编译器执行任何会使我的函数指针无效的柔道,或者在该文件的上下文之外使其无意义,因为该函数被声明为特定于该文件?
不是我的代码,而是一个(愚蠢)我的意思的例子:
void static cool_function(void);
void extern (*cool_function_ptr)(void); // Actually, I’m not sure of where the `extern` goes in a function-
// pointer declaration. Damn you, confusing function-pointer syntax!
鉴于代码(或语法正确的近似值),从另一个文件访问cool_function_ptr
会不合法吗?
答案 0 :(得分:11)
这样做是完全安全的,而且通常很有用。 static
变量和数据指针也是如此。如果编译器想要进行任何可能干扰通过来自不同转换单元的函数指针调用函数的能力的奇特优化(如非标准调用约定,内联,重构等),则编译器的责任< / em>要么确定从不采用函数的地址,要么生成代码的多个版本,其中一个版本可以安全地使用标准调用约定从外部调用。
答案 1 :(得分:3)
不确定。函数指针只是一个地址,没有什么神奇之处。
以下是一个例子:
$ cat Makefile
.PHONY: all
all: main
./main
main: main.c other.c
gcc -o main main.c other.c
$ cat main.c
#include <stdio.h>
static void goodnight(){
printf("Goonight, gracie!\n");
return;
}
int
main(char * argv[], int argc){
other(goodnight);
return 0;
}
$ cat other.c
#include <stdio.h>
void other(void(*fp)()){
fp();
return ;
}
$ make
gcc -o main main.c other.c
./main
Goonight, gracie!
$
困难的部分是获取一个函数的声明,该函数将指向函数的函数返回void。
答案 2 :(得分:1)
唯一可能咬你的是如果函数被内联 - 并且将其地址作为指针应该保持这种情况不会发生。
这样做可以让来电者不知道完整的签名,所以你正在玩火,希望事情排成一行。
它是“extern void”和“static void” - 存储类,然后返回类型。
答案 3 :(得分:1)
指向静态函数的指针没有什么不同。
然而,传递指针的效率可能略低于允许直接调用指针。我不清楚为什么你这样做,但这对我没有多大意义。
答案 4 :(得分:1)
该语言允许您将指针传递给模块外部的静态函数。
因此,编译器在编译模块内调用时可能会做的任何技巧都必须与你正在做的事情兼容。
一般来说,我会说它实际上是一个很好的代码模式,相对于使函数全局化,因为你还要封装函数,尽管可以针对一个没有外部引用的简单静态函数做出相反的参数。
总而言之,我认为重要的是对象和应用程序的设计,而不是全局引用静态函数。