内联函数中的静态变量 [英] static variables in an inlined function

查看:504
本文介绍了内联函数中的静态变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在头文件中声明和定义的函数。这本身就是一个问题。当该函数未内联时,使用该头的每个翻译单元都会获取函数的副本,当它们链接在一起时,它们会重复。我通过使函数内联来固定,但恐怕这是一个脆弱的解决方案,因为据我所知,编译器不保证内联,即使你指定inline关键字。如果这不是真的,请纠正我。



无论如何,真正的问题是,这个函数内的静态变量会发生什么?

解决方案

我想你在这里缺少了一些东西。



静态函数?



声明一个函数static会使它在其编译单元中隐藏。


具有命名空间范围(3.3.6)的名称具有内部链接,如果它是

的名称

- a变量,函数或函数模板;



3.5 / 3 - C ++ 14(n3797)



当名称具有内部链接时,其表示的实体可以通过相同翻译单元中其他范围的名称来引用。



3.5 / 2 - C + +14(n3797)


如果您在标题中声明此静态函数,则包括此标题的所有编译单元都将有自己的函数的副本。



事情是,如果函数中有静态变量,每个包含这个头的编译单元也都有自己的个人版本。 p>

内联函数



声明它内联使它成为内联函数的候选字符,因为编译器将内联或不内联,有时忽略关键字inline存在或不存在的事实):


函数声明5,9.3,11.3)与一个内联说明符声明一个内联函数。内联说明符向实现指示,在调用点处的函数体的内联替换优选于通常的函数调用机制。在调用点处执行这种在线替换不需要实现;但是,即使省略此行内替换,仍应遵守7.1.2定义的内联函数的其他规则。



7.1.2 / 2 - C ++ 14(n3797)


在标题中,它有一个有趣的副作用:内联函数可以在同一个模块中多次定义,并且链接器将简单地将them连接到一个(如果他们没有内联的编译器的原因)。



对于在内部声明的静态变量, ,并且只有其中一个:


外部内联函数中的静态局部变量总是引用同一个对象。



7.1.2 / 4 - C ++ 98 / C ++ 14(n3797)




这里有static的优点(即函数默认为extern,所以除非你特别标记你的函数为静态的,



静态局部变量?


(可以在标题中定义它)没有它的缺陷(如果没有内联,它最多存在一次)

静态局部变量没有链接(它们不能被其范围之外的名称引用),但具有静态存储持续时间它是全球性的,但其构造和破坏服从特定规则)。



static + inline?



inline和static将会有你所描述的后果(即使函数是内联的,内部的静态变量也不会是,你将以尽可能多的静态变量结束,因为你有编译单元,包括静态函数的定义)



回答作者的其他问题




它与Visual Studio 2008.我试图打开所有的选项,使VS行为符合标准,但可能是我错过了一些。这些是结果:



当函数只是inline时,只有一个静态变量的副本。



当函数是静态内联时,有与翻译单位一样多的副本。



真正的问题是,


所以我想你有这样的东西:

  void doSomething()
{
static int value;
}

你必须意识到函数内部的静态变量,



内联函数不会改变任何东西:

  inline void doSomething()
{
static int value;
}

只有一个隐藏的全局变量。



现在,如果你的函数声明为static:

p>

  static void doSomething()
{
static int value;
}

然后对于每个编译单元都是private,意味着每个CPP文件包括声明静态函数的头部将具有它自己的函数的私有副本,包括它自己的全局隐藏变量的私有副本,因此变量与包括头部的编译单元一样多。



将inline添加到static变量中的static函数中:

  static void doSomething()
{
static int value;
}

具有与不添加此inline关键字相同的结果,



所以VC ++的行为是正确的,你错误地认为inline和static的真正含义。 / b>


I have a function that is declared and defined in a header file. This is a problem all by itself. When that function is not inlined, every translation unit that uses that header gets a copy of the function, and when they are linked together there are duplicated. I "fixed" that by making the function inline, but I'm afraid that this is a fragile solution because as far as I know, the compiler doesn't guarantee inlining, even when you specify the "inline" keyword. If this is not true, please correct me.

Anyways, the real question is, what happens to static variables inside this function? How many copies do I end up with?

解决方案

I guess you're missing something, here.

static function?

Declaring a function static will make it "hidden" in its compilation unit.

A name having namespace scope (3.3.6) has internal linkage if it is the name of

— a variable, function or function template that is explicitly declared static;

3.5/3 - C++14 (n3797)

When a name has internal linkage , the entity it denotes can be referred to by names from other scopes in the same translation unit.

3.5/2 - C++14 (n3797)

If you declare this static function in a header, then all the compilation units including this header will have their own copy of the function.

The thing is, if there are static variables inside that function, each compilation unit including this header will also have their own, personal version.

inline function?

Declaring it inline makes it a candidate for inlining (it does not mean a lot nowadays in C++, as the compiler will inline or not, sometimes ignoring the fact the keyword inline is present or absent):

A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

7.1.2/2 - C++14 (n3797)

In a header, its has an interesting side effect: The inlined function can be defined multiple times in the same module, and the linker will simply join "them" into one (if they were not inlined for compiler's reason).

For static variables declared inside, the standard specifically says there one, and only one of them:

A static local variable in an extern inline function always refers to the same object.

7.1.2/4 - C++98/C++14 (n3797)

(functions are by default extern, so, unless you specifically mark your function as static, this applies to that function)

This has the advantage of "static" (i.e. it can be defined in a header) without its flaws (it exists at most once if it is not inlined)

static local variable?

Static local variables have no linkage (they can't be referred to by name outside their scope), but has static storage duration (i.e. it is global, but its construction and destruction obey to specific rules).

static + inline?

Mixing inline and static will then have the consequences you described (even if the function is inlined, the static variable inside won't be, and you'll end with as much static variables as you have compilation units including the definition of your static functions).

Answer to author's additional question

Since I wrote the question I tried it out with Visual Studio 2008. I tried to turn on all the options that make VS act in compliance with standards, but it's possible that I missed some. These are the results:

When the function is merely "inline", there is only one copy of the static variable.

When the function is "static inline", there are as many copies as there are translation units.

The real question is now whether things are supposed to be this way, or if this is an idiosyncrasy of the Microsoft C++ compiler.

So I suppose you have something like that:

void doSomething()
{
   static int value ;
}

You must realise that the static variable inside the function, simply put, a global variable hidden to all but the function's scope, meaning that only the function it is declared inside can reach it.

Inlining the function won't change anything:

inline void doSomething()
{
   static int value ;
}

There will be only one hidden global variable. The fact the compiler will try to inline the code won't change the fact there is only one global hidden variable.

Now, if your function is declared static:

static void doSomething()
{
   static int value ;
}

Then it is "private" for each compilation unit, meaning that every CPP file including the header where the static function is declared will have its own private copy of the function, including its own private copy of global hidden variable, thus as much variables as there are compilation units including the header.

Adding "inline" to a "static" function with a "static" variable inside:

inline static void doSomething()
{
   static int value ;
}

has the same result than not adding this "inline" keyword, as far as the static variable inside is concerned.

So the behaviour of VC++ is correct, and you are mistaking the real meaning of "inline" and "static".

这篇关于内联函数中的静态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆