Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不需要通过内联函数进行静态初始化_C++_Initialization - Fatal编程技术网

C++ 为什么不需要通过内联函数进行静态初始化

C++ 为什么不需要通过内联函数进行静态初始化,c++,initialization,C++,Initialization,下面的代码片段来自3.6.2/3 N3797 C++14最终工作草案: inline double fd() { return 1.0; } extern double d1; double d2 = d1; // unspecified: // may be statically initialized to 0.0 or // dynamically initialized to 0.0 if d1 is

下面的代码片段来自3.6.2/3 N3797 C++14最终工作草案:

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;  // unspecified:
                 // may be statically initialized to 0.0 or
                 // dynamically initialized to 0.0 if d1 is
                 // dynamically initialized, or 1.0 otherwise
                 // may be initialized statically or dynamically to 1.0
double d1 = fd();
正如我理解的那个例子,d1和d2的初始化都不需要静态完成
double d2=d1
是可以理解的(
d1
不是一个
常量表达式
)。我的问题如下:
为什么不要求通过内联函数进行静态初始化

在这种情况下,函数被标记为
inline
这一事实实际上没有太大变化。
inline
关键字的唯一实际效果是告诉编译器/链接器接受该函数的多个定义可能会出现在整个程序中(当将所有目标文件链接在一起时),这是直接在头文件中定义函数时所需的,头文件可能包含多个翻译单元(cpp文件)。这是一种对ODR(一个定义规则)进行例外的方法,对于要在标题中定义的函数,我们称之为“内联定义”(或“内联函数”)如果你查看C++的标准,你会发现大多数提到的<>代码>内联关键字正在讨论与提供内联定义(即实现声明的函数而不是单独的CPP文件)有关的问题。 几乎所有定义可供编译器使用的函数都可以作为“函数内联”(与“内联定义”不同)的候选函数但是,这纯粹是编译器做出的优化选择,而不是一个要求。在C++标准中提到函数内联的唯一时间是为了明确说明,如果编译器选择内联函数,则它对代码的行为不会有任何明显的影响(它们都是类似的注释:“这应该是真的,即使函数是内联的”)。
inline
关键字和“函数内联”之间的唯一关系是,在标准中,该关键字也可以被视为暗示该函数需要函数内联(因为它通常是),但这不是一个要求,我相信许多编译器在决定是否内联函数时完全忽略了这一点(大多数情况下,因为编译器不需要这一提示,他们完全有能力自己做出选择)


也就是说,您的示例中的
d1
变量是通过调用一个不是
constexpr
函数的函数来初始化的,这意味着它不能被要求静态地完成。只有当该函数被标记为
constexpr
时,编译器才必须尝试静态地对其求值,从而导致错误该调用中非局部变量的可能静态初始化。将函数标记为
inline
在这种情况下没有任何区别,因为除了ODR的应用外,需要内联函数的行为(至少表面上)与任何其他函数相同。

因为您的函数调用不是一个
常量表达式
?@Plasmah,但函数调用后缀表达式在编译期间将函数体替换为内联函数。您完全误解了
内联
关键字的作用。它不会以任何方式强制编译对于内联函数,它是为了内联,甚至被大多数编译器忽略。答案详尽无遗。但是你能得到标准参考,内联函数的ODR异常描述吗?@DmitryFucintv描述内联函数ODR异常的子句是n3337版本(C++11)中的7.1.2/4.对于我的其余评论,只需搜索“inline”一词,您就会在标准中找到与此相关的所有相关评论。