c++ - C++ 语言在使用列表初始化时是否强制执行编译器优化?

标签 c++ gcc optimization clang list-initialization

这是source.cpp

#include <iostream>

struct A {
    A(int i) : i(i) { std::cout << this << ": A(int)" << std::endl; }
    A(A const &a) : i(a.i) { std::cout << this << ": A(A const &)" << std::endl; }
    A(A &&a) : i(a.i) { std::cout << this << ": A(A &&)" << std::endl; }
    ~A() { std::cout << this << ": ~A()" << std::endl; }    

  private:
    int i;
};    

int main() {
    std::cout << "#1 :" << std::endl;
    A a1 = 1; // #1, copy-initialization    

    std::cout << "#2 :" << std::endl;
    A a3(1); // #2, direct-initialization    

    std::cout << "#3 :" << std::endl;
    A a4 = {1}; // #3, copy-list-initialization    

    std::cout << "#4 :" << std::endl;
    A a5{1}; // #4, direct-list-initialization    

    std::cout << std::endl;
    return 0;
}

clang++ -std=c++14 -Wall -fno-elide-constructors -pedantic -o main.exe source.cpp 编译以上代码(这里,我禁用了构造优化。顺便说一句, 我正在使用 Clang 3.8.1)。然后,我得到以下输出:

#1 :
0x61fe40: A(int)
0x61fe48: A(A &&)
0x61fe40: ~A()
#2 :
0x61fe30: A(int)
#3 :
0x61fe28: A(int)
#4 :
0x61fe20: A(int)

0x61fe20: ~A()
0x61fe28: ~A()
0x61fe30: ~A()
0x61fe48: ~A()

令我惊讶的是 #3 不像 #1 那样先调用 A::A(int) 然后调用 A::A(A &&),尽管它们都是复制初始化的。我还使用 gcc 6.1.0 对其进行了测试。同样的事情发生了。据我所知,列表初始化的一种常见用法是禁止缩小转换。我不知道它与编译优化有任何关系。所以,

C++ 语言在使用列表初始化时是否强制编译器优化,或者只是编译器更喜欢这样做,还是其他原因导致上述行为?

最佳答案

在这种情况下,直接初始化和复制列表初始化都会导致调用构造函数。

在[dcl.init.list]/3中的规则中使用了一个消除过程,

List-initialization of an object or reference of type T is defined as follows:

[...]

Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.

重要的是复制初始化和复制列表初始化并不等同,您可以使用复制列表初始化来初始化具有已删除复制和移动构造函数的对象,例如:

struct A
{
  A(int i){}
  A(A const&) =delete;
  A(A&&) =delete;
};    

int main()
{
  A a1 = {1};
  A a2 = 1; // won't compile
}

关于c++ - C++ 语言在使用列表初始化时是否强制执行编译器优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38757079/

相关文章:

c++ - 模板运算符返回对抽象类的引用

c++ - move 语义 : how best to understand/use them

gcc - 32 位构建于 64 位 CentOS 5 主机上

matlab - 如何减少这个特定代码块的处理时间?

c++ - 我如何获得无限小的数字(对于分形)

c++ - 从未使用过分配给变量的 C/C++ 默认值/值

macos - 由于mac上的gcc不支持openmp,我该怎么做才能让它支持呢?

c - 如何防止引用的包含搜索当前源文件的目录?

c++ - 减少 C++ 代码大小

python - 优化代码以查找 DataFrame 中每行过去 30 天的值的中位数