运行这个简单的程序时,根据编译器的不同,观察到不同的行为。
它在由GCC 11.2编译时打印true
,在由MSVC 19.29.30137编译时打印false
(两者都是截至今天的最新版本)。
#include <type_traits>
#include <iostream>
struct S {
int a;
S() = delete;
S(S const &) = delete;
S(S &&) = delete;
S &operator=(S const &) = delete;
S &operator=(S &&) = delete;
~S() = delete;
};
int main() {
std::cout << std::boolalpha;
std::cout << std::is_trivially_copyable_v<S>;
}
相关引文(摘自最新的C 23工作草案N4901):
给定 20.15.5.4 [元一元道具],标准::is_trivially_copyable_v
这些类型的算术类型(6.8.2)、枚举类型、指针类型、指向成员的指针类型(6.8.3)、std::nullptr_t和cv限定的(6.8.4)版本统称为标量类型。标量类型、普通可复制类类型(11.2)、此类类型的数组以及这些类型的cv限定版本统称为普通可复制类型。
其中
可简单复制的类类型
定义在11.2/1[class.prop]:
1一个普通的可复制类是一个类:
— 至少具有一个符合条件的复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符(11.4.4、11.4.5.3、11.4.6),
—其中每个合格的复制构造函数、移动构造函数、复制赋值运算符和移动赋值运算符都是平凡的,并且
-它有一个普通的、未删除的析构函数(11.4.7)。
合格(11 . 4 . 4[特殊]):
1默认构造函数(11.4.5.2)、复制构造函数、移动构造函数(11.4.5.3)、复制赋值操作符、移动赋值操作符(11.4.6)和预期析构函数(11.4.7)是特殊的成员函数。
6合格特别会员职能是指:
— 函数未被删除,
— 满足相关约束 (13.5)(如果有),以及
— 没有相同类型的特殊成员函数受到更多约束
这些函数的< code >平凡
(如11.4.5.3/11[class . copy . ctor],11.4.6/9 [class.copy.assign],11.4.7/8 [class.dtor]中所定义)通常意味着:
根据9.5.2/5 [dcl.fct.def.default],所提供程序中被删除的功能不是用户提供的:
...如果函数是用户声明的,并且在第一次声明时未显式默认或删除,则该函数由用户提供。...
如果我的理解是正确的,struct S
删除了特殊成员函数
,使它们不符合
和
普通可复制类类型
一般可复制类型
的要求。因此,符合性行为是MSVC的。这是正确的吗?
GCC和Clang报告说,< code>S在C 11到C 23标准模式下很容易被复制。MSVC报告说,< code>S在C 14到C 20标准模式下是不可复制的。
N3337 (~ C 11)和N4140 (~ C 14)说:
普通可复制类是指:
根据这个定义,S
是可以简单复制的。
N4659 (~ C 17) 说:
一个普通的可复制类是这样一个类:
根据这个定义,S
是不可复制的。
N4860 (~ C 20) 说:
一个普通的可复制类是这样一个类:
根据这个定义,S
是不可复制的。
因此,正如所发布的,S
在C11和C14中是可以复制的,但在C17和C20中则不是。
此更改是从 2016 年 2 月的 DR 1734 中采用的。实施者通常将 DR 视为按惯例适用于所有先前的语言标准。因此,根据已发布的 C 11 和 C 14 标准,S
是可复制的,并且按照惯例,较新的编译器版本可能会选择在 C 11 和 C 14 模式下将 S
视为不可复制。因此,对于 C 11 和 C 14,所有编译器都可以说是正确的。
对于C 17及更高版本,S
显然不是可以轻松复制的,因此GCC和Clang是不正确的。这是GCC错误#96288和LLVM错误#39050
发展至今(2020 年 6 月份),GCC 编译器已经更新至 10.1.0 版本,其功能也由最初仅能编译 C 语言,扩增至可以编译多种编程语言,其中就包括 C++ 。 除此之外,当下的 GCC 编译器还支持编译 Go、Objective-C,Objective-C ++,Fortran,Ada,D 和 BRIG(HSAIL)等程序,甚至于 GCC 6 以及之前的版本还支持编译 Java 程序。但本
对于 GCC 的认知,很多读者还仅停留在“GCC 是一个C语言编译器”的层面,是很片面的。从本节开始,我将带领大家系统学习 GCC,本节先带领大家系统地了解一下 GCC。 谈到 GCC,就不得不提 GNU 计划。GNU 全称 GNU's Not UNIX,又被称为“革奴计划”,由理查德·斯托曼于 1983 年发起。GNU 计划的最终目标是打造出一套完全自由(即自由使用、自由更改、自由发布)、开源的
这是一个使用ValArray的简单c程序: 如果我像这样编译并运行它: 产出如预期: 但是,如果我像这样编译和运行它: 输出为: 如果使用优化参数,也会发生同样的情况。 GCC版本是(Archlinux最新版本): 但是,如果我尝试叮当,两者 和 产生相同的正确结果: clang版本是: 我还尝试了在Debian上使用GCC 4.9.2,其中可执行文件会产生正确的结果。 这是GCC中可能存在的错误
为什么在那里插入? 如果没有一个好的理由:我能用什么方法摆脱它吗? 如果您想使用以下示例:https://godbolt.org/z/74ycy63se
我正在编写一些AVX代码,需要从可能未对齐的内存中加载。我目前正在加载4个double,因此我将使用内部指令\u mm256\u loadu\u pd;我编写的代码是: 然后,我使用选项O3-mavx-g进行编译,然后使用objdump获得汇编程序代码以及带注释的代码和行(
我会直接去MCVE: GCC 7.2和7.1拒绝编译,错误如下: 您可以在没有任何标志的情况下复制,也可以使用