【问题标题】:static and inline静态和内联
【发布时间】:2012-05-09 20:14:22
【问题描述】:

我正在用 C 编程。我想要一些关于静态和内联函数的描述。我知道,如果我们将一个函数设为静态,那么它向编译器表明它仅在一个翻译单元的内部链接下。 我对静态和内联有以下疑问:

  1. 如果我们将函数设为 static ,我们可以在其他翻译单元中使用它...即其他 .c 文件吗?如果是..如何?
  2. 如果我们将函数设为静态内联,那么有什么区别?编译器将如何处理它?
  3. 将函数设为静态会产生与宏相同的效果吗?
  4. 将函数处理为内联函数取决于编译器,具体取决于大小。那么有什么方法可以强行使其被视为内联?
  5. 我们如何使用内联和静态函数进行优化?

请对上述内联内容有所了解。 平台是Linux,gcc编译器,C语言。

【问题讨论】:

  • 在翻译单元中声明为静态的函数在其他翻译单元中不可见。不过,可以在多个翻译单元中重新定义它。

标签: c linux optimization gcc inline


【解决方案1】:

如今,编译器将确定内联函数是否实际上是内联的,因为并非所有函数都适合它。如果是这样,那么在引用相应函数的地方简单地注入/内联函数体。

这样的函数应该保留给函数体通常很短的频繁函数调用,尽管我认为不一定是这样。

【讨论】:

    【解决方案2】:
    1. static 函数不能在其他翻译单元中使用。这就是他们存在的理由。

    2. inline 向编译器提示该函数应该被内联而不是被调用。

    3. 将函数设为静态与使用宏不同。宏本质上会否决编译器。无论它是否认为内联是否明智,宏都会被内联;宏是文本替换。您还可以将static 函数传递给需要函数指针的对象。不能用宏来做到这一点。

    4. 宏将强制内联任何内容。即使指定inline 也可以被否决。

    5. 创建不想导出的函数static。如果一个函数真的很小,并且你真的认为它应该被内联,你可以用inline 告诉编译器。宏实际上仅用于元编程。编译器比你更清楚。

    【讨论】:

    • 但是,您始终可以将static 函数的地址作为函数指针传递到其他地方。
    • 好的,对于你的第 5 点,但是 static 的这种使用应该仅限于未在头文件中声明的函数,否则你可能会有它们的副本。
    • 有趣的是,“内联提示编译器应该内联一个函数”在技术上根本不正确,尽管这可能也是我所说的。标准确实说 “[...] 建议尽可能快地调用函数”。诚然,这是一种愚蠢的措辞(尽管由于 L1 压力,确实没有内联 can 更快)。
    • @Damon 我认为它的措辞是为了更明显地表明编译器可以 - 实际上经常会 - 忽略该关键字。
    【解决方案3】:

    staticinline 有两种截然不同的用途。

    正如您所说的正确static 意味着函数的符号不会从定义它的编译单元中导出。因此不同的编译单元可以有这样的同名符号而不会发生冲突。这是否对应于相同的函数声明和定义取决于您。但是像所有静态分配的对象这样的函数,可以通过静态或动态导出指向它的指针,在不同的编译单元中使用

    inline 不同。它的目的是使编译器可以内联你的函数,因此它的名字,但它的主要直接影响是函数符号通常根本不发出。这样做的目的是您可以将函数的 定义 放在头文件中,并将该文件包含在多个编译单元中,而无需在每个编译单元中创建多个符号。对于已定义的函数,它还具有不允许在 inline 函数内声明 static 变量的效果,因为根本不清楚该对象必须在哪个编译单元中实现。

    总而言之,static 会生成大量函数副本,inline 不会生成; static 主要用于".c" 文件和inline".h"

    第一个的效果是你可能在某些地方没有检测到两个函数指针指向“相同”的函数,第二个可能有这样的效果,如果你需要一个指向函数的函数指针,没有函数对象可以指向它会参考。这样一个 通过在 .c 文件中放置一种“实例化”,可以强制发出函数(仅在一个编译单元中!):

    // .h definition
    inline void toto(void) { }
    
    // .c instantiation
    void toto(void);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 2016-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多