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
Should one never use static inline function?
提问by Alok Save
There are two implications of using the inline
keyword(§ 7.1.3/4):
使用inline
关键字有两个含义(第 7.1.3/4 节):
- It hintsthe compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
- Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
- 它暗示编译器在调用点替换函数体比通常的函数调用机制更可取。
- 即使省略内联替换,也遵循内联的其他规则(尤其是一个定义规则)。
Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inline
merely for #1
is not really needed.
通常任何主流编译器都会在需要时在调用点替换函数体,因此inline
仅仅将函数标记为 for#1
并不是真正需要的。
Further w.r.t #2
, As I understand when you declare a function as static inline
function,
进一步来说#2
,据我所知,当您将函数声明为static inline
函数时,
The static
keyword on the function forces the inline
function 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 static
function and the keyword inline
has no importance anymore, it becomes redundant.
因此,这样的函数就像任何其他static
函数一样,关键字inline
不再重要,它变得多余。
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),
So, Is using static
and inline
together on a function practicallyuseless?
因此,实际上标记一个函数static
并且inline
两者都没有用。它应该是static
(不是最喜欢的)或inline
(最喜欢的),
那么,在一个函数上使用static
和inline
一起使用实际上没用吗?
采纳答案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 inline
just to describe intent.
您的分析是正确的,但并不一定意味着无用。即使大多数编译器自动执行内联函数(原因#1),最好声明inline
只是为了描述意图。
Disregarding interaction with inline
, static
functions should be used sparingly. The static
modifier 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.
不考虑与 的交互inline
,static
应谨慎使用函数。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. static
implies that different functions with the same signature may exist in different .cpp
files (translation units). inline
without static
means 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 inline
makes 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 inline
is 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 inline
you can really substitute the use of a macro, inline
by 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 inline
http://www.greenend.org.uk/rjk/tech/inline.html
一个简单的谷歌搜索“静态内联”将向您显示谈论它的编译器文档页面。我想这应该足以回答您的问题,并说“不,它实际上并非无用”。这是一个讨论使用 的站点的示例inline
,特别是static inline
http://www.greenend.org.uk/rjk/tech/inline.html
回答by iammilind
If you talk about freefunctions (namespace
scope), then your assumption is correct. static inline
functions indeed don't have much value. So static inline
is simply a static
function, which automatically satisfies ODR and inline
is redundant for ODR purpose.
如果您谈论自由函数(namespace
范围),那么您的假设是正确的。static inline
函数确实没有多大价值。Sostatic inline
只是一个static
函数,它自动满足 ODR 并且inline
对于 ODR 目的是多余的。
However when we talk about membermethods (class
scope), the static inline
function does have the value.
Once you declare a class
method 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 static
keyword has a different meaning when it comes for a class
.
Edit: As you may know that static
function inside a class
doesn't have internal linkage, in other words a class cannot have different copies of its static
method depending on the translation (.cpp) units.
But a free static
function at namespace
/global scope does have different copies per every translation unit.
请记住,static
关键字对于 a 具有不同的含义class
。
编辑:您可能知道static
aclass
中的函数没有内部链接,换句话说,一个类不能static
根据翻译 (.cpp) 单元拥有其方法的不同副本。
但是static
在namespace
/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 的手册页,它特别说明了静态内联与编译器标志的使用。在标志的情况下,它内联函数,如果它也是静态的并且在它被调用的每个实例中都内联,那么它将摆脱永远不会在创建的目标文件中使用的函数定义,从而减少生成的代码的大小。