应该从不使用静态内联函数吗?

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

  1. 暗示了编译器在调用点上函数体的replace比通常的函数调用机制更可取。
  2. 即使内联replace被省略,其他规则(特别是一个定义规则 )也是内联的。

通常任何主stream的编译器都会根据需要在调用点上replace函数体,所以不需要标记为#1函数。

更进一步的#2 ,据我所知,当你声明一个函数为static inline函数,

函数上的static关键字强制inline函数具有内部链接( 内联函数具有外部链接 )这样的函数的每个实例都被视为一个单独的函数( 每个函数的地址不同 ),并且这些函数的每个实例都有它们自己的静态局部variables和string文本的副本( 内联函数只有这些副本

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

所以,实际上标记一个函数staticinline都没有用处。 要么它应该是static不是最优选的 )或者inline最优选的 ),
那么,在一个几乎没用的函数上使用staticinline

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

忽略与inline交互,应该谨慎使用static函数。 命名空间范围的static修饰符以前不赞成使用未命名的名称空间(C ++ 03§D.2)。 由于一些令人难以理解的原因,我不记得它是从C ++ 11中弃用,但你应该很less需要它。

所以,实际上标记一个函数static和inline都没有用处。 要么它应该是静态的(不是最优选的)或者内联的(最优选的),

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

什么首选是使用一个无名的名字空间,而不是static

 namespace { inline void better(); // give the function a unique name } static inline void worse(); // kludge the linker to allowing duplicates 

静态和内联是正交的(独立的)。 静态意味着函数不应该在翻译单元外部可见,内联是编译器提示程序员想要内联该函数的提示。 这两个不相关。

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

例:

source1.cpp:

 inline int Foo() { return 1; } int Bar1() { return Foo(); } 

source2.cpp:

 inline int Foo() { return 2; } int Bar2() { return Foo(); } 

不使用Foo上的静态(或者不使用匿名命名空间,这是大多数C ++程序员的首选方式),这个例子违反了ODR,结果是不确定的。 您可以使用Visual StudiotestingBar1 / Bar2的结果将取决于编译器设置 – 在Debugconfiguration中,Bar1和Bar2将返回相同的值(内联未使用,链接器随机select一个实现),在Releaseconfiguration中的每一个将返回预期的价值。

我可能不完全正确,但据我所知,声明一个函数static inline是使(或允许)编译器生成一个机器代码的唯一方法,其中函数实际上没有在编译代码中定义,你所拥有的只是把声明的函数直接replace成一系列指令,就像它只是一个常规的过程体,在源代码中相对于该函数定义的过程调用的机器代码中没有跟踪。

也就是说,只有使用static inline才能真正替代使用macros, inline本身是不够的。

一个简单的谷歌search“静态内联”将向您展示编译器文档页面,谈论它。 我想这应该足以回答你的问题,并说:“不,实际上没有用处”。 下面是一个讨论使用inline的网站的例子,特别是static inline http://www.greenend.org.uk/rjk/tech/inline.html

如果你谈论自由function( namespace范围),那么你的假设是正确的。 static inline函数的确没有太多的价值。 所以static inline只是一个static函数,它自动满足ODR, inline对于ODR来说是多余的。

然而,当我们谈论成员方法( class范围)时, static inline函数确实具有值。
一旦将class方法声明为inline ,则对于包含class所有翻译单元,它必须是全部可见的。

请记住, static关键字对于一个class来说有不同的含义。
编辑 :正如你可能知道一个class中的static函数没有内部链接,换句话说, 一个类不能根据翻译(.cpp)单位有不同的static方法的副本
但是在namespace /全局范围内的一个自由static函数每个翻译单元都有不同的副本。

例如

 // 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 } 

我刚刚读了一个gcc的手册页,它特别指出了使用静态内联的编译器标志。 在标志的情况下,它将函数内联,如果它也是静态的,并且在每个被调用的实例中被内联,那么它将删除在所创build的对象文件中永远不会使用的函数定义,从而减less生成的代码的大小由那一点点。