上个月,在CppCon2022上Herb Sutter介绍了他的一个处于实验中的新编译器:CppFront。
他通过该编译器来实践一种潜在的C++替换语法,简称为Cpp2,C++当前语法则称为Cpp1。Herb从2015年就着手设计该项目,如今推了出来,一时激起不小浪花,项目地址为https://github.com/hsutter/cppfront。官方描述如下:Cppfront is a experimental compiler from a potential C++ 'syntax 2' (Cpp2) to today's 'syntax 1' (Cpp1), to learn some things, prove out some concepts, and share some ideas. This compiler is a work in progress and currently hilariously incomplete… basic functions work, classes will be next, then metaclasses and lightweight exceptions.C++这是在自我破局,开辟第二曲线啊!标准是想再次实现C++11那种巨大的成功,使C++再次焕然一新,更加现代、简单、高效。(虽然Herb说这个项目只代表个人的实践,但是好的点子标准也不会放过,而且是实践可行的点子)其实近几年C++的发展速度真不慢,许多特性迟久未入,只是不想刚引入就遭淘汰。当你再次见到C++更新时,很可能又会是像见到了一个新语言一样,语法完全变化,近几次的标准已有这个趋势。下面我将提供一些Cpp2的例子,这些例子都是可以使用CppFront手动编译运行的,大家可以看看它的语法。Cpp2的目标可以概括为两个词:安全和简洁,语法也以此为导向。先来看一个最简单的例子:
main:()->int={ s:std::string="world"; std::cout<< "Hello"<< s << " "; }这就是使用纯Cpp2编写的代码,所有的声明都由原来的r-to-l变为了l-to-r。其实从trailing-return-type开始,C++已经慢慢变成了这种l-to-r形式的语言。可以混合使用Cpp1和Cpp2的语法,但是对于纯Cpp2语法,它可以隐式地引入C++ 23的"import std"模块,因此无需手动添加任何头文件。接着来看一个文件读写的例子:
main:()->int={ s:std::string="Lily"; myfile:=fopen("dog","w"); myfile.fprintf("Hello%s! ",s.c_str()); myfile.fclose(); }这个代码的确简单不少,而且fprintf(), fclose()是作为成员函数存在的,这意味着可以触发IDE的智能提示,提升开发效率。下面是一个类型安全的例子:
main:()->int={ v:std::variant<int,double>=42.0; a:std::any="xyzzy"asstd::string; o:std::optional<int>=(); test_generic(3.14); test_generic(v); test_generic(a); test_generic(o); std::cout<< " "; v=1; a=2; o=3; test_generic(42); test_generic(v); test_generic(a); test_generic(o); } test_generic:(x:_)={ std::cout << std::setw(30)<< typeid(x).name() << "valueis" << inspect x ->std::string{ isint=std::to_string(xasint); isstd::string=xasstd::string; is_="notanintorastring"; } << " "; }Cpp2中函数不需要前置声明,它具有顺序无关性(其实是生成代码的时候自动提供前置声明了)。其中的"_"是隐式模板的通配符,相当于T,而inspect is as等等这些都是Pattern Matching的语法。在CppFront中,typeid().name()返回的类型名称是可读的,因此最终输出如下图。对于指针,许多运算符都被禁止了,看如下例子:
main:()->int={ words:std::vector<std::string>= ("decorated","hello","world"); first:*std::string=words.front()&; last:*std::string=words.back()&; whilefirst<= last { print_and_decorate(first*); first++; //unsafe //first+1; //first[1]; //first~; //deletefirst; } } print_and_decorate:(thing:_)= std::cout<< ">>"<< thing << " ";当试图对指针使用这些操作时,将产生编译期错误。上述代码将报错:
error:++-pointerarithmeticisillegal-usestd::spanorgsl::spaninstead它会推荐你使用更好的替代特性,有些特性甚至内置为了原生特性,比如智能指针,它会推荐你使用unique.new
main:()->int={ cpp2::Bounds.set_handler(call_my_framework); words:std::vector<std::string>= ("decorated","hello","world"); s:std::span=words; print_and_decorate(s[3]); } print_and_decorate:(thing:_)= std::cout<< ">>"<< thing << " "; call_my_frameword:(msg:*constchar)= std::cout << "sendingerrortomyframework...[" << msg << "] ";代码中访问s[3]越界,编译时指定-s标志,便可以帮你开启边界检查,运行之时进行报错。此外,还可以通过第2行的代码设置一个handler,来捕获错误。只有一个表达式的函数,"{}"将作为可选项,省略掉要更加简洁。 此外,Cpp2也支持初始化安全,对此,指针不可赋值为nullptr/0/NULL。看一个例子:
main:()->int={ cpp2::Bounds.set_handler(call_my_framework); p:*std::string; ifstd::rand()%2{ p=words.front()&; } //else{ //p=words.back()&; //} print_and_decorate(p*); } print_and_decorate:(thing:_)= std::cout<< ">>"<< thing << " ";例子中,p是一个指针,但是赋值语句没有遍及各个分支,访问之时肯定会存在错误。因此它会直接产生编译期错误:
example.cpp2(4,5):error:localvariablepmustbeinitializedonbothbranchesorneitherbranch example.cpp2(6,5):error:"if"initializespon: branchstartingatline6 butnoton: implicitelsebranch ==>programviolatesinitializationsafetyguarantee-seepreviouserrors这个特性可以保证变量在使用前初始化。最后,还有一个有意思的特性用于函数多返回值,一个简单的例子:
f:()->(i:int,s:std::string)={ i=10; s="haha"; return; } automain()->int{ auto[a,b]=f(); std::cout<< a << ""<< b << " "; }这个代码混合了Cpp1和Cpp2。函数f()具有多个返回值,可以不用借用std::paire与std::tuple等等组件。实际上,它会自动生成一个结构体,作为函数的返回值。该例子生成的为:
structf__ret{ inti; std::strings; };这些例子都来自Herb的演讲内容,他说Cpp2会比原来的C++语法简单和安全10倍,想看的地址为:https://www.youtube.com/watch?v=ELeZAKCN4tY。Cpp2一直只是Herb个人的一个实验性产品,项目必然存在很多缺陷,但正是这些不断的探索,为C++提供了更多可能。 大家觉得目前的Cpp2设计怎样呢?有没有哪些不错的点子?
审核编辑 :李倩
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
C++
+关注
关注
22文章
2104浏览量
73480 -
编译器
+关注
关注
1文章
1618浏览量
49043
原文标题:Herb Sutter 介绍一个处于他实验中的 C++ 新编译器和一种潜在的 C++ 替换语法
文章出处:【微信号:CPP开发者,微信公众号:CPP开发者】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
AI编译器技术剖析
随着人工智能技术的飞速发展,AI编译器作为一种新兴的编译技术逐渐进入人们的视野。AI编译器不仅具备传统编译器的功能,如将高级语言编写的源代码
人工智能编译器与传统编译器的区别
人工智能编译器(AI编译器)与传统编译器在多个方面存在显著的差异。这些差异主要体现在设计目标、功能特性、优化策略、适用范围以及技术复杂性等方面。以下是对两者区别的详细探讨,旨在全面解析其内在差异。
esp8266如何修改枚举在编译器中的字节宽度?
在移植一个项目到esp8266上,这个项目原来平台的编译器中,enum枚举占的字节数是1,但是到了esp的平台,发现编译器会
发表于 07-12 08:16
Meta发布基于Code Llama的LLM编译器
近日,科技巨头Meta在其X平台上正式宣布推出了一款革命性的LLM编译器,这一模型家族基于Meta Code Llama构建,并融合了先进的代码优化和编译器功能。LLM
芯来科技与华东师范大学SOLE实验室合作推动LLVM/CLANG编译器优化
随着RISC-V这一革命性的开源指令集架构在全球范围内的迅速普及,它为半导体行业带来了前所未有的机遇与挑战。在此大背景下,芯来科技和华东师范大学SOLE实验室携手合作,致力于在RISC-V处理器上进
SEGGER编译器优化和安全技术介绍 支持最新C和C++语言
。 SEGGER编译器无缝集成到Embedded Studio中。它与SEGGER Linker、Assembler和Runtime Library一起,
C语言:嵌入式开发中的关键编译器角色
嵌入式程序开发跟硬件密切相关,需要使用C语言来读写底层寄存器、存取数据、控制硬件等,C语言和硬件之间由编译器来联系,一些C标准不支持的硬件特性操作,由编译器提供。
发表于 04-26 14:53
•540次阅读
XC2234l-20F如何使用16位tasking编译器定义一个段?
如何使用16位tasking编译器定义一个段(section指定地址,用于存储常量),使用的芯片是XC2234l-20F。
发表于 02-20 07:05
Triton编译器的原理和性能
Triton是一种用于编写高效自定义深度学习原语的语言和编译器。Triton的目的是提供一个开源环境,以比CUDA更高的生产力编写快速代码,但也比其他现有DSL具有更大的灵活性。Tri
评论