Alo*_*ave 61 c++ static inline
使用inline
关键字(第7.1.3/4节)有两个含义:
通常,如果需要的话,那么标记功能的任何主流的编译器会在调用点替代函数体inline
仅仅是#1
是不是真的需要.
进一步说#2
,正如我所知,当你将一个函数声明为static inline
函数时,
该static
对功能关键字强制inline
函数有一个内部连接(内联函数具有外部连接)这样的功能中的每一个实例被视为一个单独的功能(各功能的地址是不同的)和这些功能中的每一种情况下都有自己的副本静态局部变量和字符串文字(内联函数只有这些的一个副本)
因此,这样的函数就像任何其他static
函数一样,并且关键字inline
不再重要,它变得多余.
所以,实际标记一个函数static
,inline
两者都没用.它应该是static
(不是最优选的)还是inline
(最优选的),
那么,在功能上使用static
和inline
一起实际上是无用的吗?
Pot*_*ter 49
你的分析是正确的,但并不一定意味着无用.即使大多数编译器自动执行内联函数(原因#1),最好只声明inline
描述意图.
无视相互作用inline
,static
应谨慎使用功能.static
命名空间范围内的修饰符以前不赞成使用未命名的命名空间(C++03§D.2).由于一些不明原因,我不记得它已从C++ 11中的弃用中删除,但你应该很少需要它.
因此,实际上标记一个静态和内联函数都没有用.它应该是静态的(不是最优选的)或内联的(最优选的),
没有偏好的概念.static
意味着具有相同签名的不同功能可能存在于不同的.cpp
文件(翻译单元)中.inline
没有static
意味着不同的翻译单元可以定义具有相同定义的相同功能.
什么是最好是使用不具名命名空间,而不是static
:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Run Code Online (Sandbox Code Playgroud)
Sum*_*uma 24
静态和内联是正交的(独立的).静态意味着函数不应该在转换单元之外可见,内联是程序员想要内联此函数的编译器的提示.那两个没有关系.
static inline
当在翻译单元之外不使用内联函数时,使用是有意义的.通过使用它,您可以通过在另一个具有相同名称的转换单元中命名另一个内联函数来防止意外违反ODR规则的情况.
例:
source1.cpp:
inline int Foo()
{
return 1;
}
int Bar1()
{
return Foo();
}
Run Code Online (Sandbox Code Playgroud)
source2.cpp:
inline int Foo()
{
return 2;
}
int Bar2()
{
return Foo();
}
Run Code Online (Sandbox Code Playgroud)
如果不在Foo上使用静态(或者不使用匿名命名空间,这是大多数C++程序员的首选方式),此示例违反ODR并且结果未定义.您可以使用Visual Studio进行测试,Bar1/Bar2的结果将取决于编译器设置 - 在Debug配置中,Bar1和Bar2将返回相同的值(内联未使用,链接器随机选择一个实现),在Release配置中每个都是将返回预期值.
div*_*ero 13
我可能不完全正确,但据我所知,声明一个函数 static inline
是使(或允许)编译器生成机器代码的唯一方法,其中函数实际上根本没有在编译代码中定义,并且所有你所拥有的是将声明的函数直接替换为一系列指令,就像它只是一个常规的过程体,在源代码中相对于该函数定义的过程调用的机器代码中没有跟踪.
也就是说,只有static inline
你可以真正替代宏的使用,inline
本身是不够的.
一个简单的Google搜索"静态内联"将向您展示讨论它的编译器文档页面.我想这应该足以回答你的问题了,并说"不,它实际上没用".以下是讨论使用的网站的一个示例inline
,特别是static inline
http://www.greenend.org.uk/rjk/tech/inline.html
iam*_*ind 10
如果你谈论自由函数(namespace
范围),那么你的假设是正确的.static inline
功能确实没有多大价值.因此,它static inline
只是一个static
自动满足ODR 的功能,对于ODR而言inline
是多余的.
但是,当我们谈论成员方法(class
范围)时,该static inline
函数确实具有该值.
一旦你声明一个class
方法inline
,它的全身就必须对包含它的所有翻译单元可见class
.
请记住,static
关键字具有不同的含义class
.
编辑:您可能知道static
a class
内部的函数没有内部链接,换句话说,static
根据转换(.cpp)单位,类不能具有其方法的不同副本.
但是/ global范围内的自由static
函数namespace
确实每个翻译单元都有不同的副本.
例如
// 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
}
Run Code Online (Sandbox Code Playgroud)