error: static assertion failed: std::atomic requires a trivially copy type

1. 报错信息

在这里插入图片描述
编译期错误,gcc version 7.5.0

错误示例代码:

#include <atomic>
#include <iostream>
#include <vector>

int main()
{
    std::atomic<std::vector<int>> a;
}

2. 问题分析

报错信息里明确说了,atomic类需要一个trivially copy type,所以关键就在于什么是trivially copy type
https://en.cppreference.com/w/cpp里边,解释了什么是trivially copy type
在这里插入图片描述cppreference对TriviallyCopyable的稍微总结了一下,“这意味着可平凡复制类没有虚函数或虚基类”。

我们一条一条看
TriviallyCopyable类型主要分为三类:

  • 标量类型
    这里的标量我猜测应该是int,double,long之类的内置类型。

  • 而对于类,cppreference说的6条,可以总结成三条:
    ①这个类,至少一个复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符未弃置 ,就是至少有一个未被delete;
    ②未被弃置的复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符都是平凡的;
    ③析构函数也得是平凡的。
    所以,主要问题在于,“平凡”是个什么意思?这个后边说
  • TriviallyCopyable对象组成的数组,这个好理解。

关于“平凡”,cppreference给出的解释是这样的:

在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

其实都差不多,主要在于一是不能由用户显示定义,二是该类不能存在虚函数以及虚基类,这也是cppreference说“这意味着可平凡复制类没有虚函数或虚基类”的由来。

再回到文章文章开头的示例代码,问题就变成了std::vector\<int\>是不是TriviallyCopyable了,答案明显是否定的。

### 实现原子交换语义 为了实现在编译器中的原子交换语义并解决静态断言失败的问题,可以考虑采用特定的汇编指令来确保操作的原子性。现代处理器提供了专门用于执行原子操作的指令集,这些指令可以在不被中断的情况下完成读取、修改和写入的操作。 对于C++而言,标准库已经提供了一套完善的原子操作接口,通过`std::atomic<T>`模板类能够轻松定义具有原子特性的变量,并利用成员函数如`exchange()`来进行原子交换[^1]。然而,在更底层或者自定义编译器环境中,则需手动编写相应的机器码或内联汇编代码以支持这一特性。 以下是基于GCC风格的内联汇编实现的一个简单例子: ```cpp #include <iostream> // 假设目标架构为x86_64 void* atomic_exchange(void*& dest, void* exch) { __asm__ volatile ( "lock;" // 锁定总线直到该指令结束 "xchg %0, %1" // 执行XCHG指令进行原子交换 : "=r"(exch) // 输出参数列表 : "m"(dest), "0"(exch)// 输入参数列表 : "memory"); // 更新内存状态 return exch; } ``` 上述代码片段展示了如何使用`xchg`指令配合`lock`前缀来保证跨多个CPU核心间的同步效果。需要注意的是不同体系结构下的具体语法可能会有所差异,因此实际应用时应参照对应平台的手册文档调整相应部分。 当涉及到复杂的数据结构或是更高层次的语言抽象时,可能还需要进一步设计合适的锁机制或者其他并发控制手段来辅助实现完整的原子行为模式。此外,如果是在开发新的编程语言或者是改进现有编译工具链的过程中遇到此类需求,则建议深入研究相关硬件手册以及参考其他成熟项目的源码实现方式获取灵感和支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值