Mac C++20环境配置
C++20标准出来已经有很长一段时间了,不过苦于各大编译器对于新特性的完成度,坐等到现在才差不多基本completed.(MSVC支持应该是最好的,可惜不怎么用Windows).即使工作上由于项目的各种历史版本依赖问题还不能在现有项目中直接使用到C++20,但是这并不妨碍我们先了解学习一些好玩的内容。
那今天正好趁放假在家给自己放松一下,配置C++20的环境尝个鲜。
环境配置
本次配置基于MacBook M系列,相比起来其他linux平台上配置应该会少一些坑,毕竟Clang对C++20的支持貌似还是三大编译器里最差的。
话不多说,直接开始动手。首先我们先去llvm那里下载新版的(>=16.0)的release,可以直接点击这里llvm0rg-16.0.0,选择对应平台编译好的版本。当然也可以下载源码编译,不过之前弄了一个旧点的版本然后傻乎乎的编译了一下,ninja -j32
之后可以说是我第一次听到这玩意儿的风扇声音,而且编译时间还不算短。
当然了,如果还是懒可以直接brew search llvm
然后install
,不过我这里看到的版本最新的也只有15.x,能不能支持所有特性我也没去尝试。
下载之后,tar -xzvf xxx
直接解压就好,现在环境配置基本就算结束了,没错就这么简单。当然,你也可以去~/.zshrc
里面添加一些环境变量方便直接找到clang啥的,这都是默认操作了我就不多赘述。
这样,前期的配置工作就算完成了。
尝鲜
对于C++20最想尝试的肯定就是std::format()
,再也不用痛苦的去cout
中拼接字符串,只要对占位符相应位置填充就好。
#include <iostream>
#include<format>
int main() {
int a=1;
int b=2;
std::cout<<"a:"<<a<<" b:"<<b<<std::endl;
std::cout<<std::format("a:{} b:{}",a,b)<<std::endl;
return 0;
}
相比起什么保证输出浮点数精度,io效率其他优点,对于懒人的我只关心少写几个<<
。需要注意的是,如果想使用format必须在编译时加入-fexperimental-library
并且链接上下载好的lib。而且由于在arm下,编译还需要一写额外的参数用于交叉编译-arch arm64 -Isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk
我的编译命令如下
clang++ -I../clang16/include -O3 -DNDEBUG -std=gnu++20 -arch arm64 -Isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk -fexperimental-library -L../clang16/lib main.cpp -o test
当然,如果用Clion或者Vscode配置一下CMakeLists也是一样的。
再来说说另一个讨论广泛的特性,Module。毕竟这可涉及到大型项目的组织。可是我今天并不想讲这个,因为我尝试了一下Clang下的Module,坑多且难用,先把自己的测试模块编译出.pcm
然后再编译出.o
,这样才能识别到并顺利编译。。。说实话这完全是反人类,我想设计出这个提案的人绝对期待的是能像其他语言一样,直接import
就能顺利编译出,不然的话即使Module能够怎么减少编译时间或者是能够接口隔离,我还是选择老老实实的使用include
(除非上面的ld发话)。BTW,实在对Module有需要的话可以去尝试一下xmake,说不定有惊喜哦。(看情况要不要出一期xmake的教程再水一篇Blog)
好了,到了我最感兴趣的特性:Coroutine 协程
之前的C++异步基本是Future与Promise,现在有了协程这个新的帮手。C++的协程是一种无栈协程,也就是协程没有独立的栈帧,本质上呢就是挂起和恢复的栈帧不同。相比起goroutine这种有栈协程,它没有栈和上下文切换性能上应该会更好一点,不过也是由于无栈因此挂起与恢复可能会涉及一些其他条件。当然,我对于C++的协程也还在了解学习中,不过有一点还是有点疑惑。对于Go和Rust都有相应的异步协程环境支持,比如#[tokio::main]
,但是貌似C++这部分需要我们自己去实现。总之先慢慢学习一下Coroutine,然后再去看看相关的框架怎么用。
结尾
到这里C++20的初次体验算是结束了,对于协程我会在空余时间再去学习一下,这里先挖个坑后面慢慢再补吧。