Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.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++;11保证;int a[8]={}&引用;在语义上等同于;int a[8]{}&引用;?_C++_Performance_C++11_Initialization_Standards - Fatal编程技术网

C++ C++;11保证;int a[8]={}&引用;在语义上等同于;int a[8]{}&引用;?

C++ C++;11保证;int a[8]={}&引用;在语义上等同于;int a[8]{}&引用;?,c++,performance,c++11,initialization,standards,C++,Performance,C++11,Initialization,Standards,在C++11中,以下两种语句都是合法的: 报表1int a[8]={} 报表2int a[8]{} 然而,我更喜欢语句1而不是语句2,因为我认为语句1更具表现力 C++11标准是否保证这两个语句在语义上是等价的?在语义上,它们是不同的,很像复制/直接初始化: 8.5.4列表初始化[dcl.init.List] 1列表初始化是从带括号的初始化列表初始化对象或引用。这样的初始值设定项是 称为初始值设定项列表,列表中以逗号分隔的初始值设定项子句称为 初始化列表。初始值设定项列表可能为空列表初始化可以在

在C++11中,以下两种语句都是合法的:

报表1<代码>int a[8]={}

报表2<代码>int a[8]{}

然而,我更喜欢语句1而不是语句2,因为我认为语句1更具表现力


C++11标准是否保证这两个语句在语义上是等价的?

在语义上,它们是不同的,很像复制/直接初始化:

8.5.4列表初始化[dcl.init.List] 1列表初始化是从带括号的初始化列表初始化对象或引用。这样的初始值设定项是 称为初始值设定项列表,列表中以逗号分隔的初始值设定项子句称为 初始化列表。初始值设定项列表可能为空列表初始化可以在直接初始化或复制初始化中进行 语境;直接初始化上下文中的列表初始化称为直接列表初始化和 复制初始化上下文中的列表初始化称为复制列表初始化。[…](emphasis mine)

原始答案,涉及比较绩效: 不,该标准规定了算法的一些复杂性限制,但没有规定此类问题的性能。这最好留给编译器处理,但所有编译器都可能生成相同的代码

考虑复制初始化与直接初始化。标准只规定了它们是什么,它从来没有说一个必须比另一个快,或者它们必须表现相同。这完全取决于编译器


这是一件好事,因为编译器知道什么最适合该平台。如果标准确实施加了这样的限制,它可以说
+
必须比
*
快,这是非常直观的。但是想想为乘法而构建的平台,在那里用机器代码计算
*
实际上更快。编译器必须竭尽全力将
*
转换为较慢的指令,以符合标准。

标准仅定义所谓的“可观察行为”,即I/O库调用和易变数据读写的顺序。没有速度要求


你无法确定哪一个在实践中更快。好的编译器应该发出相同的代码,但有时编译器中会有bug,这些bug可能会影响代码的发出。

C++11标准甚至不能保证
int a[8]={
的速度与int aVeryLongName[8]={}一样快

是的,它们在语义上是等价的

聚合(8.5.1,例如数组)上的列表初始化(8.5.4)执行聚合初始化(8.5.4p3b1)。聚合初始化不关心语法形式是直接初始化还是复制初始化;在这两种情况下,聚合初始化规则的应用是相同的。特别是,聚合的成员总是从初始值设定项列表的相应子句进行复制初始化

有一个例外,几乎但不完全适用于您的情况;如果没有足够的元素初始化聚合的所有成员,则标准不清楚如何初始化剩余成员;它们是从
{}
(空列表初始值设定项)进行列表初始化的,但未指定它们是复制列表初始化还是直接列表初始化,或者这是否取决于原始列表初始化(请参见注释);事实上,clang和gcc在这个角落案例中的行为有所不同。但是,这与您的情况无关,因为聚合成员类型是
int
,对于非类类型,从
{}
进行列表初始化调用值初始化,即零初始化,这是直接的,无论语法形式如何(即
int i{};
int i={};
在语义上是相同的)

选择
=
(复制初始化)语法有几个原因:首先,它是标准在几乎所有示例中使用的形式(例外是8.5.4p3中的最后两个示例,其中一个示例演示了缩小转换范围的错误,另一个示例演示了从空初始值设定项列表进行初始化)。而且,正如你所说,它更有表现力;我还发现,当列表初始化聚合时,复制初始化语法更好地反映了聚合的元素本身是复制初始化的这一事实


最后,在一种情况下,不带
=
的语法是必要的:对象是带有
显式
构造函数的非聚合类类型。因此,应该为这种情况保留直接列表初始化语法。

我很遗憾,任何人都必须处理编译器,这是至关重要的。不,C++标准不能保证性能比渐近复杂性更高。我认为,就编译性能而言,语句2比第一个要快得多。我严重怀疑规范中提到的性能。这取决于编译器和标准库实现者。我还怀疑一个好的编译器是否会为这两个声明生成不同的代码,但这至少很容易找到:编译两个版本并检查生成的汇编代码。也许提到性能就给问题蒙上了阴影。也许要问的问题是这两条语句在语义上是否等价(对于内置类型的固定大小数组的特殊情况)?这甚至不是评论material@thecoshman如果你不理解它,那么考虑C++标准对运行时环境的假设很小。特别是它允许JIT,其中符号解析时间可能不同。一个要求两个相似结构速度相等的标准会产生更多的假设。(注意,t