10

假设我只想通过传递一个指向该函数的函数指针来从我的一个文件中公开一个函数。将该函数声明为 是否安全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的近似值),从另一个文件访问是否非法?

4

5 回答 5

11

这样做是完全安全的,而且通常很有用。static变量和数据指针也是如此。如果编译器想要进行任何可能干扰通过来自不同翻译单元的函数指针调用函数的能力的花哨优化(如非标准调用约定、内联、重构等),则编译器有责任确定永远不会使用函数的地址,也不会生成多个版本的代码,其中一个版本可以通过标准调用约定从外部安全地调用。

于 2011-02-28T04:59:30.173 回答
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 的函数的指针。

于 2011-02-28T04:56:33.690 回答
1

唯一可能会咬你的是如果函数是内联的——并且将它的地址作为指针应该可以防止这种情况发生。

这样做有点让调用者不知道完整的签名,所以你在玩火,但希望事情排成一行。

它是“extern void”和“static void”——存储类,然后是返回类型。

于 2011-02-28T04:58:39.387 回答
1

指向静态函数的指针没有什么不同。

但是,传递指针可能比直接调用它的效率略低。我并不完全清楚你为什么要这样做,但这对我来说没有多大意义。

于 2011-02-28T04:59:29.440 回答
1

绝对允许,可能完全合理


该语言允许您将指针传递给模块外部的静态函数。

因此,编译器在编译模块内调用时可能做的任何技巧都必须以某种方式与您正在做的事情兼容。

一般来说,相对于使函数全局化,我会说它实际上是一种很好的代码模式,因为您还封装了函数,尽管对于没有外部引用的简单静态函数可以提出相反的论点。

总而言之,我认为重要的是对象和应用程序的设计,而不是全局引用静态函数。

于 2011-02-28T05:01:38.827 回答