【问题标题】:Should C declarations match definition including keywords and qualifiers such as "static", "inline", etcC 声明是否应与定义匹配,包括关键字和限定符,例如“static”、“inline”等
【发布时间】:2017-03-22 21:23:37
【问题描述】:

考虑这个函数声明和定义的例子(在同一个翻译单元中):

inline static int foo(int x);

...

int foo(int x)
{
  return x+1;
}

我知道类型需要匹配,但是其他关键字和限定符呢? inline static 应该在这两种情况下吗?还是只是声明?

我可以使用 C 标准的哪个部分或哪个编码指南来证明答案的合理性?

【问题讨论】:

    标签: c function keyword


    【解决方案1】:

    不,特别是对于inline,这些不应该相同。

    但是这个例子从一开始就是错误的。对于inline,您需要在.h 文件中使用inline 进行定义(整个函数)。通过 inline,您可以避免符号在包含 .h 标头的多个翻译单元 (.c) 中定义。

    然后,在一个翻译单元中,您只需将不带inline 的声明噘起,以表明该符号应在相应的.o 目标文件中生成。

    【讨论】:

    • 在我的例子中它们在同一个翻译单元中
    • @JasonS,如果它只是在一个 TU 内,inline 根本没有意义。无论如何,编译器可以内联它看到的每个定义。
    • 可以!= 可以。对于我正在使用的这个特定编译器(Microchip XC16),带有-O1 优化的免费版本不会自动内联小函数(但你可以用inline 哄它这样做),而带有-O2 或@ 的高级版本987654330@ 优化确实如此。但我的问题很笼统+我正在寻找涵盖clang / gcc / XC16的建议。
    • @JasonS,我明白了。我的建议是避免仅仅因为您有一个优化不佳的编译器而添加噪音。如果您确信这些函数应该使用 C 模型进行内联,那就是将带有 inline 的定义放在标题中(或 .c 的开头)并放置一个“实例化”,没有inline 的声明,稍后。这样您就可以确定它是可移植的。
    【解决方案2】:

    我想提供有关内联的详细信息,

    你可以把声明和定义分开,但是那 定义必须在使用 功能,即在您的情况下inline static int foo(int x);

    内联函数包含在 ISO C99 标准中,但目前 GCC 实现的功能与 ISO C99 标准要求的功能之间存在很大差异。

    要声明内联函数,请在其声明中使用 inline 关键字,如下所示:

    static inline int
    inc (int *a)
    {
      return (*a)++;
    }
    

    An Inline Function is As Fast As a Macro

    请注意,函数定义中的某些用法可能使其不适合内联替换。

    请注意,在 C 中,与 C++ 不同的是,inline 关键字不会影响函数的链接。

    【讨论】:

      【解决方案3】:

      是的。内联和静态应该包括在内。例如,函数的代码行在您声明的 .h 文件和您定义的 .c 文件中应该是相同的(在这两种情况下都是如此),但在您的主 code.c 文件中它应该只调用时具有函数名称,因此“foo(传递的参数)”。

      希望这会有所帮助!

      【讨论】:

      • 什么参考资料可以证实你所说的?我想我个人同意你的看法,但我更愿意指出 C 标准的某些部分或有声望的风格指南。
      【解决方案4】:

      您只需要在声明中使用inline static。您可以将其排除在函数定义之外。

      7.1.1/6:

      在没有存储类说明符的命名空间范围内声明的名称具有外部链接,除非它由于先前的声明而具有内部链接并且如果它没有声明为 const。声明为 const 且未显式声明为 extern 的对象具有内部链接。

      【讨论】:

      • 不仅它不相关,对于 C 来说它只是给出了错误的方向。将inline 附加到声明而不附加到定义是毫无意义的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多