clang和gcc为相同的代码生成不同的逻辑.哪个是正确的
Different logic produced by clang and gcc for same code. Which is correct?
我发现gcc-8和clang-6产生的逻辑之间存在差异。
这发生在一个真实的代码库中,当我使用clang进行开发时,我使用gcc进行部署。
请告知哪个编译器有错误,这样我就可以适当地提交错误。
简介
A
可隐式转换为B
CCD_ 3可由CCD_ 4(复制/移动)和CCD_。
从A&&
:初始化A
时
- clang选择move构造函数
- gcc选择
initializer_list
构造函数
现场演示:https://coliru.stacked-crooked.com/a/bc50bd8f040d6476
MCVE
#include <initializer_list>
#include <utility>
#include <iostream>
struct thing;
struct thing_ref
{
thing_ref(thing&& other) : ref_(other) {}
thing_ref(thing& other) : ref_(other) {}
thing& ref_;
};
struct thing
{
thing() {}
thing(std::initializer_list<thing_ref> things)
{
std::cout << "initializer_list pathn";
}
thing(thing&& other)
{
std::cout << "move pathn";
}
thing(thing const& other)
{
std::cout << "copy pathn";
}
};
struct foo
{
foo(thing t) : mything { std::move(t) } {}
thing mything;
};
int main()
{
thing t;
auto f = foo { std::move(t) };
}
编译器设置:
没有什么特别的,根据coliru链接:-std=c++17 -O2
标准草案(T
为thing
)[dcl.init.list]:
列表初始化是从支持的init列表初始化对象或引用。。。
类型T的对象或引用的列表初始化定义如下:
如果支持的初始化列表包含指定的初始化器列表[不适用]
如果T是聚合类并且[不适用]
否则,如果T是字符数组[不适用]
否则,如果T是聚合[不适用]
否则,如果初始值设定项列表没有元素[不适用]
否则,如果T是
std::initializer_list<E>
[不适用]的特化否则,如果T是类类型,则考虑构造函数。枚举适用的构造函数,并通过过载解析选择最佳构造函数[applies]
。。。
[over.match.list]:
当非聚合类类型T的对象被列表初始化,使得[dcl.init.list]指定根据本子条款中的规则执行重载解析时,重载解析分两个阶段选择构造函数:
最初,候选函数是类T的初始化器列表构造函数([dcl.init.list]),参数列表由初始化器列表组成,作为单个参数[适用]
如果找不到可行的初始值设定项列表构造函数,将再次执行重载解析,其中候选函数是类T的所有构造函数,参数列表由初始值设定值列表的元素组成。
如果初始值设定项列表没有元素,并且T有一个默认构造函数,则第一阶段将被省略。[不适用]
返回[dcl.init.list]了解初始值设定项列表构造函数是什么:
如果构造函数的第一个参数是
std::initializer_list<E>
类型,或者引用了某些类型E的可能是cv限定的std::initializer_list<E>
,并且没有其他参数,或者所有其他参数都有默认参数([dcl.fct.default]),则构造函数是初始值设定项列表构造函数。
还有一个方便的注释,重申了结论:
注意:在列表初始化中,初始化器列表构造函数比其他构造函数更受青睐
我的结论:
应首先考虑初始值设定项列表构造函数候选者,并在其有效时使用。由于thing
隐式转换为thing_ref
,因此它应该是有效的。在我看来,GCC符合要求。
如果您想初始化具有初始化器列表构造函数的类型的对象,但不想使用该构造函数,则不要使用列表初始化,即不要使用大括号init-list。
- LLVM |如何实现逻辑非操作的 IR 代码生成
- C++基于输入参数的动态代码生成
- C++使用代码生成错误
- C++代码生成核心文件,就像 gdb >> gcore 一样
- 卤化物:X86汇编代码生成
- 如何将 MATLAB 图像处理库内置函数转换为 MATLAB 编码器代码生成不支持的 C++?
- 为什么我的代码为同一代码生成不同的值
- 我应该担心动态代码生成与用C++编写的其他模块不匹配吗?
- 企业架构师 - 单独的代码生成标头和实现
- C++ 代码生成和模板专用化
- IBM Rhapsody c++ 代码生成 - 为什么总是在状态图周围放置一个活动状态
- 如何从 c++ 代码生成 arm64-v8a 64 位共享对象?
- 在语法文件上运行C 的ANTL4解析器显示错误33:缺少代码生成模板非局部trrefheader
- 使用LLVM在代码生成期间,更喜欢LLVM :: StringMap或STD :: MAP
- 如何根据模板参数制作代码生成
- 如何在C++中使用以下代码生成秒表/倒计时
- 为什么 C++ 和 Python 中的相同代码生成不同的输出?
- 获取 llvm::MCJIT 代码生成后的函数大小
- clang和gcc为相同的代码生成不同的逻辑.哪个是正确的
- 编译为C 与C的GCC代码生成的很大差异