我想知道静态变量或函数如何被保护以仅用于它所定义的文件。我知道这些变量和函数是在数据部分中声明的(堆区域是精确的),但是它是用文件名标记?假设我通过将这样一个静态函数(在foo.c中定义)分配给全局函数指针来愚弄编译器,并在其他文件(bar.c)中调用该函数指针。显然我的代码不会给出任何编译警告,但顺便提一下,它会给出分段错误。显然,这是一个保护错误,但我很想知道它是如何在系统内部实现的。
感谢。 MS
答案 0 :(得分:5)
链接器负责限制将函数名映射到函数的范围。
对函数指针调用的静态函数没有任何保护 - 这不是一个不常见的习语。例如,推荐的实现GObject方法的方法是公开指向静态函数的指针(参见本GObject how-to中的虚拟公共方法部分)
答案 1 :(得分:3)
仅仅通过链接器不知道其符号/位置就可以“保护”它。因此,您无法在另一个通过其符号名称显式引用静态对象的模块中编写代码,因为链接器没有此类符号。没有运行时保护。
如果在运行时将地址传递给静态对象到某个其他模块,那么您将能够通过这样的指针访问它。那不是“愚弄编译器”(或实际上是链接器),这种行为可能完全合法。
您遇到seg-fault的事实可能是出于完全不同的原因(例如,无效指针)。编译器可以选择内联代码,在这种情况下,指向它的指针是不可能的,但是如果你明确地获取对象的地址,编译器应该实例化它,所以这似乎不太可能。
答案 2 :(得分:2)
静态的目的不是“保护”变量/函数,而是保护命名空间并保护程序的其余部分不会被具有冲突名称的符号弄乱。它还允许更好的优化,因为编译器知道它不必方便外部模块访问符号名称。
答案 3 :(得分:0)
如果将foo.c和bar.c编译到不同的动态加载库中,你可能会遇到问题。