【问题标题】:How is the static function/variable protected静态函数/变量如何保护
【发布时间】:2010-07-08 10:13:38
【问题描述】:

我想知道如何保护静态变量或函数仅用于定义它的文件。我知道这些变量和函数是在数据部分(准确地说是堆区域)中声明的,但它是用文件名标记?假设我通过将这样的静态函数(在 foo.c 中定义)分配给全局函数指针,并在其他文件(bar.c)中调用该函数指针来愚弄编译器。显然我的代码不会给出任何编译警告,但顺便说一下,它给出了分段错误。显然,这是一个保护故障,但我有兴趣知道它是如何在系统内部实现的。

谢谢。女士

【问题讨论】:

  • 通过函数指针调用另一个编译单元中的静态函数不应产生保护错误。发布您的代码。
  • 当编译器实际上是为程序员提供的一种功能时,为什么还要欺骗编译器?

标签: c static


【解决方案1】:

链接器负责限制将函数名映射到函数的范围。

对于由函数指针调用的静态函数没有保护 - 这并不是一个常见的习语。例如,实现 GObject 方法的推荐方式是公开指向静态函数的指针(请参阅此GObject how-to 中的虚拟公共方法部分)

【讨论】:

    【解决方案2】:

    它只是通过不让链接器知道其符号/位置而受到“保护”。因此,您不能在另一个模块中编写通过符号名称显式引用静态对象的代码,因为链接器没有这样的符号。没有运行时保护。

    如果您在运行时将静态对象的地址传递给其他模块,那么您将能够通过这样的指针访问它。这不是“愚弄编译器”(实际上是链接器),这样的行为可能是完全合法的。

    你得到一个段错误的事实可能是完全不同的原因(例如一个无效的指针)。编译器可能会选择内联代码,在这种情况下,指向它的指针是不可能的,但是如果你明确地获取一个对象的地址,编译器应该实例化它,所以这似乎不太可能。

    【讨论】:

      【解决方案3】:

      静态的目的不是“保护”变量/函数,而是保护命名空间并保护程序的其余部分免受名称冲突的符号的影响。它还允许更多的优化,因为编译器知道它不必方便外部模块访问符号名称。

      【讨论】:

        【解决方案4】:

        如果 foo.c 和 bar.c 被编译到不同的动态加载库中,您“可能”会遇到问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-15
          • 2016-03-08
          • 1970-01-01
          • 1970-01-01
          • 2014-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多