如何将c语言编译器设置为初始状态,使用列表初始化时,C语言是否强制执行编译器优化?...

这是source.cpp

#include

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首先不调用A :: A(int),然后调用A :: A(A&&)作为#1,尽管它们都是复制初始化的.我还用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

}

标签:list-initialization,c,optimization,clang,gcc

来源: https://codeday.me/bug/20190828/1756866.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值