C++ 应该永远不要使用静态内联函数吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10876930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:34:25  来源:igfitidea点击:

Should one never use static inline function?

c++staticinline

提问by Alok Save

There are two implications of using the inlinekeyword(§ 7.1.3/4):

使用inline关键字有两个含义(第 7.1.3/4 节):

  1. It hintsthe compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
  2. Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
  1. 暗示编译器在调用点替换函数体比通常的函数调用机制更可取。
  2. 即使省略内联替换,也遵循内联的其他规则(尤其是一个定义规则)。

Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inlinemerely for #1is not really needed.

通常任何主流编译器都会在需要时在调用点替换函数体,因此inline仅仅将函数标记为 for#1并不是真正需要的。

Further w.r.t #2, As I understand when you declare a function as static inlinefunction,

进一步来说#2,据我所知,当您将函数声明为static inline函数时,

The statickeyword on the function forces the inlinefunction to have an internal linkage(inline functions have external linkage) Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these)

static对功能力关键字inline函数有一个内部连接(内联函数具有外部连接)这样的功能中的每一个实例被视为一个单独的功能(各功能的地址是不同的)和这些功能中的每一种情况下都有自己的副本静态局部变量和字符串文字(内联函数只有这些的一个副本

Thus such a function acts like any other staticfunction and the keyword inlinehas no importance anymore, it becomes redundant.

因此,这样的函数就像任何其他static函数一样,关键字inline不再重要,它变得多余。

So, Practically marking a function staticand inlineboth has no use at all. Either it should be static(not most preferred) or inline(most preferred),
So, Is using staticand inlinetogether on a function practicallyuseless?

因此,实际上标记一个函数static并且inline两者都没有用。它应该是static不是最喜欢的)或inline最喜欢的),
那么,在一个函数上使用staticinline一起使用实际上没用吗?

采纳答案by Potatoswatter

Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inlinejust to describe intent.

您的分析是正确的,但并不一定意味着无用。即使大多数编译器自动执行内联函数(原因#1),最好声明inline只是为了描述意图。

Disregarding interaction with inline, staticfunctions should be used sparingly. The staticmodifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.

不考虑与 的交互inlinestatic应谨慎使用函数。static命名空间范围内的修饰符以前被弃用,取而代之的是未命名的命名空间(C++03 §D.2)。由于一些模糊的原因,我不记得它在 C++11 中被弃用了,但你应该很少需要它。

So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),

因此,实际上将函数标记为静态和内联根本没有用。它应该是静态的(不是最喜欢的)或内联的(最喜欢的),

There's no notion of preference. staticimplies that different functions with the same signature may exist in different .cppfiles (translation units). inlinewithout staticmeans that it's OK for different translation units to define the same function with identical definitions.

没有偏好的概念。static意味着具有相同签名的不同函数可能存在于不同的.cpp文件(翻译单元)中。inline没有static意味着不同的翻译单元可以用相同的定义定义相同的函数。

What ispreferred is to use an unnamed namespace instead of static:

什么最好是使用不具名命名空间,而不是static

namespace {
    inline void better(); // give the function a unique name
}

static inline void worse(); // kludge the linker to allowing duplicates

回答by Suma

Static and inline are orthogonal (independent). Static means the function should not be visible outside of the translation unit, inline is a hint to the compiler the programmer would like to have this function inlined. Those two are not related.

静态和内联是正交的(独立的)。静态意味着函数在翻译单元之外不应该是可见的,内联是对编译器的一个提示,程序员希望将这个函数内联。这两者没有关系。

Using static inlinemakes sense when the inlined function is not used outside of the translation unit. By using it you can prevent a situation of accidental violation of ODR rule by naming another inlined function in another tranlation unit with the same name.

static inline当内联函数不在翻译单元之外使用时,使用是有意义的。通过使用它,您可以通过在另一个具有相同名称的翻译单元中命名另一个内联函数来防止意外违反 ODR 规则的情况。

Example:

例子:

source1.cpp:

源1.cpp:

inline int Foo()
{
  return 1;
}

int Bar1()
{
  return Foo();
}

source2.cpp:

源2.cpp:

inline int Foo()
{
  return 2;
}

int Bar2()
{
  return Foo();
}

Without using static on Foo (or without using an anonymous namespace, which is preferred way by most C++ programmers), this example violates ODR and the results are undefined. You can test with Visual Studio the result of Bar1/Bar2 will depend on compiler settings - in Debug configuration both Bar1 and Bar2 will return the same value (inlining not used, one implementation selected randomly by the linker), in Release configuration each of them will return the intended value.

如果没有在 Foo 上使用静态(或者没有使用匿名命名空间,这是大多数 C++ 程序员的首选方式),这个例子违反了 ODR,结果是未定义的。您可以使用 Visual Studio 测试 Bar1/Bar2 的结果将取决于编译器设置 - 在 Debug 配置中,Bar1 和 Bar2 将返回相同的值(未使用内联,链接器随机选择一个实现),在发布配置中,它们中的每一个都将返回将返回预期值。

回答by dividebyzero

I may not be completely right about this, but as far as I know declaring a function static inlineis the only way to make (or allow) the compiler to generate a machine code where the function really is not defined in the compiled code at all, and all you have is a direct substitution of the function call into a sequence of instructions, like it were just a regular procedure body, with no trace in the machine code of a procedure call relative to that function definition from the source code.

我对此可能并不完全正确,但据我所知,声明一个函数 static inline是使(或允许)编译器生成机器代码的唯一方法,其中该函数实际上根本没有在编译代码中定义,并且您所拥有的只是将函数调用直接替换为一系列指令,就像它只是一个常规过程体,在与源代码中的函数定义相关的过程调用的机器代码中没有任何痕迹。

That is, only with static inlineyou can really substitute the use of a macro, inlineby itself is not enough.

也就是说,只有用static inline你才能真正替代使用一个宏,inline光靠它本身是不够的。

A simple Google search for "static inline" will show you compiler documentation pages that talk about it. I guess this should be enough to answer your question, and say, "no, it is not practically useless". Here is one example of a site discussing the use of inline, and specifically of static inlinehttp://www.greenend.org.uk/rjk/tech/inline.html

一个简单的谷歌搜索“静态内联”将向您显示谈论它的编译器文档页面。我想这应该足以回答您的问题,并说“不,它实际上并非无用”。这是一个讨论使用 的站点的示例inline,特别是static inlinehttp://www.greenend.org.uk/rjk/tech/inline.html

回答by iammilind

If you talk about freefunctions (namespacescope), then your assumption is correct. static inlinefunctions indeed don't have much value. So static inlineis simply a staticfunction, which automatically satisfies ODR and inlineis redundant for ODR purpose.

如果您谈论自由函数(namespace范围),那么您的假设是正确的。static inline函数确实没有多大价值。Sostatic inline只是一个static函数,它自动满足 ODR 并且inline对于 ODR 目的是多余的。

However when we talk about membermethods (classscope), the static inlinefunction does have the value.
Once you declare a classmethod as inline, it's full body has to be visible to all translation units which includes that class.

但是,当我们谈论成员方法(class范围)时,static inline函数确实具有值。
一旦您将class方法声明为inline,它的完整主体必须对包括该 的所有翻译单元可见class

Remember that statickeyword has a different meaning when it comes for a class.
Edit: As you may know that staticfunction inside a classdoesn't have internal linkage, in other words a class cannot have different copies of its staticmethod depending on the translation (.cpp) units.
But a free staticfunction at namespace/global scope does have different copies per every translation unit.

请记住,static关键字对于 a 具有不同的含义class
编辑:您可能知道staticaclass中的函数没有内部链接,换句话说,一个类不能static根据翻译 (.cpp) 单元拥有其方法的不同副本
但是staticnamespace/global 范围内的自由函数对于每个翻译单元确实有不同的副本。

e.g.

例如

// file.h
static void foo () {}
struct A {
  static void foo () {}
};

// file1.cpp
#include"file.h"
void x1 ()
{
  foo();  // different function exclusive to file1.cpp
  A::foo();  // same function
}

// file2.cpp
#include"file.h"
void x2 ()
{
  foo();  // different function exclusive to file2.cpp
  A::foo();  // same function
}

回答by Luke Small

I just read a man page for gcc and it specifically states the use of static inline with a compiler flag. In the case of the flag, it inlines the function and if it is also static and is inlined in every instance that it is called, then it gets rid of the function definition which will never be used in the created object file, thereby reducing the size of the generated code by that little bit.

我刚刚阅读了 gcc 的手册页,它特别说明了静态内联与编译器标志的使用。在标志的情况下,它内联函数,如果它也是静态的并且在它被调用的每个实例中都内联,那么它将摆脱永远不会在创建的目标文件中使用的函数定义,从而减少生成的代码的大小。