C++ 静态内联函数中的函数本地静态对象不是';t共享
我在bla.h中有以下内容:C++ 静态内联函数中的函数本地静态对象不是';t共享,c++,static,c++17,language-lawyer,inline,C++,Static,C++17,Language Lawyer,Inline,我在bla.h中有以下内容: #include <iostream> static inline void bla() { static int x; std::cout << "bla @ " << (uintptr_t)bla << ": x @ " << &x << std::endl; } 读完这本书后,我有点惊讶 它说: 在内联函数中 所有函数定义中的函
#include <iostream>
static inline void bla() {
static int x;
std::cout << "bla @ " << (uintptr_t)bla << ": x @ " << &x << std::endl;
}
读完这本书后,我有点惊讶
它说:
在内联函数中
- 所有函数定义中的函数局部静态对象在所有转换单元中共享(它们都引用同一个对象 定义在一个翻译单元中)
bla
显示不同的地址,但为x
显示相同的地址
这是g++中的一个bug吗
注:这是由于C++17中内联的含义发生了变化。正如Igor Tandetnik评论的那样,错误出现在cppreference.com上,因为他们遗漏了标准的一个重要部分:
C++标准的实际文本在[DCL,内联] / 6中有这个注释: “具有外部链接的内联函数中的静态局部变量 始终引用同一对象。”
重点放在我的身上伊戈尔·坦德尼克10月20日4:12因此,观察到的行为符合标准。
函数上的静态
意味着每个翻译单元都有自己的函数副本-它们都是不同的;因此,静态的本地变量也是不同的。C++标准的实际文本在[dCL,内线] / 6中有这样的注释:“一个具有外部链接的内联函数中的静态局部变量总是引用同一个对象。”强调我的。@IgorTandetnik请回答这个问题,然后链接到实际的标准文本给标记为重复的人:这不是一个12年前的问题的重复。C++中的内联含义在C++ 17和12年中被改变,甚至没有标准。没有一个答案超越了c++14。我不认为c++17改变了wrt内联函数和函数静态变量。新的内联变量位于文件范围内(inline)函数之外,因此从未使用过静态变量。这不是一种好的思考方式:这种带有内部链接的声明声明不相关的函数,其中一些函数可能没有所讨论的“The”变量(或者“it”具有不同的类型或值)。带有外部链接的合适声明声明单个函数,因此当然只有一个静态局部变量。C++23预计会重写该注释,以避免暗示函数的地址与它的标识以某种方式分离。@Davidsherring问题在于cppreference.com删除了外部链接,这表明具有内部链接的声明将共享它们的静态变量,但不共享它们的标识。因此,具有内部链接的函数会相互覆盖甚至可能具有不同类型的静态变量。这不是一个合理的解读:为什么不同函数(可能具有不同类型)中的变量是相同的变量(或者具有相同的地址)?问题是为什么Cppreference在任何地方都包含这样的语句(因为它由“内联函数”单数表示),答案可能是,标准有时会说一些愚蠢的话,就像你引用的注释中所说的那样,因为对于带有外部链接的内联函数,不管你有多少个函数和变量实例,它们都是相同的。这就是C++17中编码的更改。假设遵循ODR,则只有一个函数!没有“完全相同”的“实例”。这是自C++98以来不变的。
bla @ 94796100194693: x @ 0x56376fe10178
bla @ 94796100194897: x @ 0x56376fe10180