头文件中定义的小函数:内联还是静态?

时间:2022-08-24 16:28:59

I have a number of small functions which are defined in a .h file. It is a small project (now) and I want to avoid the pain of having declarations and definitions separate, because they change all the time. To avoid multiply-defined symbols, I can either have them static or inline. What should be preferred and why?

我有一些在。h文件中定义的小函数。这是一个小项目(现在),我希望避免分离声明和定义的痛苦,因为它们一直在变化。为了避免多重定义的符号,我可以让它们保持静态或内联。应该选择什么,为什么?

I know it is in general bad practice to define functions in headers. You don't have to mention that in answers, this question is meant technically.

我知道在header中定义函数通常是不好的做法。你不必在回答中提到这一点,这个问题在技术上是有意义的。

3 个解决方案

#1


23  

I'd use static inline, but static would work just as well.

我将使用静态内联,但是静态也可以。

extern and extern inline are out because you'd get multiple external definitions if the header is included in more than one translation unit, so you need to consider static, static inline and inline specification.

extern和extern inline时,由于您将获得多个外部定义(如果头包含在多个转换单元中),因此您需要考虑静态的、静态的内联和内联规范。

Heptic correctly states in his answer that most compilers consider functions for inlining regardless of whether inline is specified or not, ie the main impact of inline is its effect on linkage.

Heptic在他的回答中正确地指出,无论是否指定内联,大多数编译器都考虑内联函数。

However, static definitions have internal linkage, so there's not much difference between static and static inline; I prefer static inline for function definitions in header files for purely stylistic reasons (rule of thumb: header files should only contain extern declarations, static const variable definitions and static inline function definitions).

但是,静态定义有内部链接,所以静态和静态内联没有太大的区别;我更喜欢静态内联,而不是在头文件中使用函数定义,这是出于纯粹的文体原因(规则:头文件应该只包含外部声明、静态const变量定义和静态内联函数定义)。

inline without static or extern results in an inline definition, which the standard states (C99 6.7.4, §6)

内联没有静态的或外来的结果在内联定义,标准的州(C99 6.7.4§6)

provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.

提供外部定义的替代方法,译者可以使用它来实现对同一翻译单元中的函数的任何调用。对函数的调用是使用内联定义还是使用外部定义是不确定的。

ie inline definitions should always be accompanied by external definitions, which is not what you're looking for.

ie内联定义应该始终伴随着外部定义,这不是您要寻找的。

Some more information about the subtleties of C99 inline semantics can be found in this answer, on the Clang homepage and the C99 Rationale (PDF).

关于C99内联语义的更多细节可以在这个答案中找到,在Clang主页和C99基本原理(PDF)上。

Keep in mind that GCC will only use C99 semantics if -std=c99 or -std=gnu99 is present...

请记住,GCC只使用C99语义,如果-std= C99或-std=gnu99。

#2


3  

Since the question is about C (not C++), inline means that

既然问题是关于C(而不是c++),内联就是这个意思

  1. You wish "that calls to the function be as fast as possible" (ISO9899-1999, 6.7.4(5)). The same paragraph also states that it is implementation-defined to which extent this suggestion is effective. In other words, it has little bearing and does not imply any inlining at all (in fact, non-inlining may quite possibly be faster due to instruction cache effects).
  2. 您希望“调用函数的速度越快越好”(ISO9899-1999, 6.7.4(5))。同一段还指出,该建议的实施程度是由实施决定的。换句话说,它几乎没有轴承,也不意味着任何内联(事实上,由于指令缓存的影响,非内联可能会更快)。
  3. there are some restrictions and special cases in combination with extern (ISO9899-1999, 6.7.4(6), for example an inline funciton with external linkage must be defined in the same compilation unit, and an inline definition allows an extern definition elsewhere without an error (which is not necessarily a good thing, because the two functions need not be functionally equivalent, and it is unspecified which one the compiler uses at any time!).
  4. 有一些限制和特殊情况结合走读生(iso9899 - 1999,6.7.4(6),例如与外部链接必须定义内联函数在同一编译单元,和内联定义允许一个外来的定义在其他地方没有一个错误(这未必是一件好事,因为这两个函数不需要功能等效,并指定哪一个编译器使用在任何时候!)。

The linker implications given by Heptic are required for C++, but not required by C (as far as I can tell). They are necessarily required by the "shall have the same address in all translation units" clause in ISO14882, 7.1.2(4). I am not aware of any similar clause in C99.
However, since the entirely different languages C and C++ usually go through the same C/C++ compiler and linker, it likely works identically for C, anyway.

在c++中,需要使用Heptic所给出的链接,但不需要C(据我所知)。他们必须在ISO14882, 7.1.2(4)中“在所有翻译单元中都有相同的地址”。C99中没有类似的条款。但是,由于完全不同的语言C和c++通常都使用相同的C/ c++编译器和链接器,所以无论如何,对于C来说,它的工作方式是一样的。

So... how to answer your question? Use inline when you feel it's adequate. Be aware of the possible pitfalls of extern. Otherwise, leave it away and trust the compiler to do it right.

所以…如何回答你的问题?当你觉得合适的时候使用内联。注意extern的潜在隐患。否则,就把它放在一边,相信编译器会做对。

#3


0  

I think static inline is the way to go for functions you want to inline, and only static for those you don't want.

我认为静态内联是一种方法,它可以实现您想要内联的函数,并且只对那些您不想要的函数进行静态。

static refers to visibility, but inline is ambiguous about visibility in the standard (C99). Anyway, it's not its purpose: inline is for inlining functions, thus it has a side-effect from a visibility point of view you might not want.

静态指的是可见性,但是inline对于标准中的可见性是不明确的。总之,这并不是它的目的:内联用于内联函数,因此从您可能不希望看到的可见性角度来看,它有副作用。

#1


23  

I'd use static inline, but static would work just as well.

我将使用静态内联,但是静态也可以。

extern and extern inline are out because you'd get multiple external definitions if the header is included in more than one translation unit, so you need to consider static, static inline and inline specification.

extern和extern inline时,由于您将获得多个外部定义(如果头包含在多个转换单元中),因此您需要考虑静态的、静态的内联和内联规范。

Heptic correctly states in his answer that most compilers consider functions for inlining regardless of whether inline is specified or not, ie the main impact of inline is its effect on linkage.

Heptic在他的回答中正确地指出,无论是否指定内联,大多数编译器都考虑内联函数。

However, static definitions have internal linkage, so there's not much difference between static and static inline; I prefer static inline for function definitions in header files for purely stylistic reasons (rule of thumb: header files should only contain extern declarations, static const variable definitions and static inline function definitions).

但是,静态定义有内部链接,所以静态和静态内联没有太大的区别;我更喜欢静态内联,而不是在头文件中使用函数定义,这是出于纯粹的文体原因(规则:头文件应该只包含外部声明、静态const变量定义和静态内联函数定义)。

inline without static or extern results in an inline definition, which the standard states (C99 6.7.4, §6)

内联没有静态的或外来的结果在内联定义,标准的州(C99 6.7.4§6)

provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.

提供外部定义的替代方法,译者可以使用它来实现对同一翻译单元中的函数的任何调用。对函数的调用是使用内联定义还是使用外部定义是不确定的。

ie inline definitions should always be accompanied by external definitions, which is not what you're looking for.

ie内联定义应该始终伴随着外部定义,这不是您要寻找的。

Some more information about the subtleties of C99 inline semantics can be found in this answer, on the Clang homepage and the C99 Rationale (PDF).

关于C99内联语义的更多细节可以在这个答案中找到,在Clang主页和C99基本原理(PDF)上。

Keep in mind that GCC will only use C99 semantics if -std=c99 or -std=gnu99 is present...

请记住,GCC只使用C99语义,如果-std= C99或-std=gnu99。

#2


3  

Since the question is about C (not C++), inline means that

既然问题是关于C(而不是c++),内联就是这个意思

  1. You wish "that calls to the function be as fast as possible" (ISO9899-1999, 6.7.4(5)). The same paragraph also states that it is implementation-defined to which extent this suggestion is effective. In other words, it has little bearing and does not imply any inlining at all (in fact, non-inlining may quite possibly be faster due to instruction cache effects).
  2. 您希望“调用函数的速度越快越好”(ISO9899-1999, 6.7.4(5))。同一段还指出,该建议的实施程度是由实施决定的。换句话说,它几乎没有轴承,也不意味着任何内联(事实上,由于指令缓存的影响,非内联可能会更快)。
  3. there are some restrictions and special cases in combination with extern (ISO9899-1999, 6.7.4(6), for example an inline funciton with external linkage must be defined in the same compilation unit, and an inline definition allows an extern definition elsewhere without an error (which is not necessarily a good thing, because the two functions need not be functionally equivalent, and it is unspecified which one the compiler uses at any time!).
  4. 有一些限制和特殊情况结合走读生(iso9899 - 1999,6.7.4(6),例如与外部链接必须定义内联函数在同一编译单元,和内联定义允许一个外来的定义在其他地方没有一个错误(这未必是一件好事,因为这两个函数不需要功能等效,并指定哪一个编译器使用在任何时候!)。

The linker implications given by Heptic are required for C++, but not required by C (as far as I can tell). They are necessarily required by the "shall have the same address in all translation units" clause in ISO14882, 7.1.2(4). I am not aware of any similar clause in C99.
However, since the entirely different languages C and C++ usually go through the same C/C++ compiler and linker, it likely works identically for C, anyway.

在c++中,需要使用Heptic所给出的链接,但不需要C(据我所知)。他们必须在ISO14882, 7.1.2(4)中“在所有翻译单元中都有相同的地址”。C99中没有类似的条款。但是,由于完全不同的语言C和c++通常都使用相同的C/ c++编译器和链接器,所以无论如何,对于C来说,它的工作方式是一样的。

So... how to answer your question? Use inline when you feel it's adequate. Be aware of the possible pitfalls of extern. Otherwise, leave it away and trust the compiler to do it right.

所以…如何回答你的问题?当你觉得合适的时候使用内联。注意extern的潜在隐患。否则,就把它放在一边,相信编译器会做对。

#3


0  

I think static inline is the way to go for functions you want to inline, and only static for those you don't want.

我认为静态内联是一种方法,它可以实现您想要内联的函数,并且只对那些您不想要的函数进行静态。

static refers to visibility, but inline is ambiguous about visibility in the standard (C99). Anyway, it's not its purpose: inline is for inlining functions, thus it has a side-effect from a visibility point of view you might not want.

静态指的是可见性,但是inline对于标准中的可见性是不明确的。总之,这并不是它的目的:内联用于内联函数,因此从您可能不希望看到的可见性角度来看,它有副作用。