当前位置:首页 » 《资源分享》 » 正文

关于我为何要为C++增加新的特性,开刀GCC进行魔改。

20 人参与  2024年04月14日 17:48  分类 : 《资源分享》  评论

点击全文阅读


c++我用了十几年,从小时候接触直到现在也快15.6年了,我开发的所有项目中都使用了这门技术,当然我也使用其他语言参与项目的研发工作。c++算写过代码最多的,参与过的项目数不胜数,从驱动到图形图像,音视频领域,从桌面软件到高并发系统的研发,从windows到linux到macos上软件开发,我几乎都用到过这门语言。它成为了我职业生涯的主力语言,其他像C#,golang,js,dlang,lua,object-c,rust也开发过很多项目,但没有C++用的多。毕竟他是一门能够让广大程序员了解计算机原理和理论的一门语言,网上说不懂C++不算是一个正真的程序员,我认为也是,因为其他语言只能算是业务型语言,当然大部分程序员不搞基础研究,只能算是业务型程序员,很难成为一名技术专家,会有严重的中年危机,35岁了,只能送外卖,开滴滴,完全会被AI取代,写业务对于AI来说太简单了,描述几个关键字,不到1秒,AI就写完了,没有任何bug,根本不需要专业的人写业务代码。而在基础领域研发就不一样了,这个是探索未知领域的道路,AI很难胜任,这也是人类和其他动物或者AI最大的区别。

所以我还是比较了解不同语言的优势和劣势,以及不同的应用场景,但是我对C++的理解还是比较深刻的,毕竟是靠这门技术吃饭的,他是一门万能的语言,几乎很多项目都离不开它的存在,甚至你不会使用它,依旧只是一个初级入门级的程序员而已。而这门语言门槛极高,很多写了5年10年甚至20年的程序员,依旧会因为指针问题而头疼,甚至会犯一些很低级的错误,特别是多人项目的开发工作,会被一些莫名其妙的问题而困住,软件时好时坏,编译也不会告诉你到底错在哪里!你只能像个无头苍蝇一样,一个个断点打过来,“哦,找了好几天,一拍脑袋,原来有人把这变量忘记赋初值了,变成野指针了,变量值不确定,导致软件时好时坏,是不是让很多人,恨不得把电脑也砸了”。我太了解我们C++程序员了,因为我一直遇到过这种问题,真的让我太焦躁了,一整晚对着屏幕,头皮都差点抓没了。

为了与时俱进,C++大概5年左右更新一次标准。尽管C++更新了几十年,但依旧没有加入现代语言的特性,我以为C++11开始要遥遥领先了,但到下几个版本却让人觉得很无奈,确实增加了不少特性,但“然并卵”,几乎没有什么用,工程领域根本用不到,反正我一次也没用过。过了几年已经被其他语言拉开了非常大的差距,比如说同时期的object-c,早期我用object-c开发cocos2d的游戏引擎,当时内存操作只能retain和release,有点像c++11智能指针的用法,几年后当我打开xcode要开发MacOsX设备驱动程序时,一看连gc 内存池都支持了,亮瞎我的双眼,出钱东西支持起来就是快。但是C++已经十几年过去了,目前依旧不支持GC,似乎让标准委员会那帮老头支持很难?看了C++2026,都是些什么鬼,感觉那帮人从来不写代码。在很多工程领域研发,我几乎都没用过C++11之后的很多特性,我很想破口大骂,但我又不能参与标准的制定,总感觉那帮老年人有点固执或老年痴呆。现在什么年代了,还在搞一些有的没的东西,大家早就支持gc了,很多应用软件开发并不需要很强的计算性能,再说论计算性能你也比不过C和汇编,谁会用户C++写内核级程序?除了应用级驱动,图形图像,密集型计算会用到C++一部分,其他都是C和汇编来优化的,都只是拿C++做简单的模块化封装而已。但是很多应用级软件都是用C++写的,因为要调用一些库之类东西,所以保留方案是C++写来比较方便。

C++的缺陷也很明显,老程序员都会遇到过,比如说ABI兼容问题,RAII问题,指针问题,运行时不确定问题,语法规则问题。特别是大型项目,多人协作问题,代码到了十几万行,甚至上百万行,你会觉得代码就像一座屎山一样,各种各样的奇淫技巧,各种各样的库,各种各样的语法。特别是大家水平层次不齐的时候,比如说windows上开发,vc++用的是匈牙利命名,标准库用的驼峰命名,boost用喜欢用下划线,你该怎么办,感觉像吃了满口的苍蝇一样恶心,项目上线全是bug,找半天也找不到bug在哪里。不像golang,java,c#之类的很标准,可读性很强,排错起来很简单。为什么C++会被那么多人诟病,避免尽量不用,而使用其他语言,是有很多原因,主要是还是对程序员的要求太高,有很多语法漏洞,学习成本太高,项目开发周期长,可控范围不确定,人才难找,不像java,c#,golang可以边学边写,3个月就能完全理解,C++可能要长达3年左右,而且开发的项目风险太高,大部分性能要求不高的研发都会首选java,c#之类的。我想这也是最明智的选着,其实做出来的效果没有任何区别,而且成本低,在可控之内。

内存问题一直是c++长久以来诟病的事情,特别是内存泄漏这块,有人说用内存检测代码,我只能说你用过Qt没,虽然已经把C++封装的完美,很强大,但qt内存泄漏很多,用过都知道。但目前主流的内存检测代码,依旧会照成内存泄漏。特别项目中野指针和悬空指针,导致查bug费时费力,吃力不讨好。到了几十人上百人协作开发的项目,简直就是噩梦一样,项目上线就会遇到很多奇奇怪怪的崩溃,就是指针造成的,而且这种bug dump出来也很难找。曾经为了找这类bug,我2个月没睡好,简直就是着了魔一样,差点疯掉。内存碎片的问题也是比较严重的问题,长时间运行,堆上分配的内存,会一直碎片化,导致内存越来越少,需要重启服务才能解决。因为C++内存管理是手动的,没有GC和内存池,特别是服务器7*24小时运行。当流量上来后,你的服务器一下子会因为内存问题而崩溃,当然相关内存池库可以用,但是没有GC管理内存,依旧会因为内存泄漏而爆掉。特别对指针的操作,很容易造成异常问题,除非你一个人写代码,你对指针的调用很了解,不然多人参与项目其中,就会产生很多匪夷所思的事情。你会百思不得其解,打了好几天的断点,你发现原来释放后没赋值,导致变成野指针或者悬空指针。想起这个事情我就想砸电脑,连很多第三方库里面都会有很多类似的问题。如果c++加了GC的话,不容易出现崩溃问题,野指针问题,还有内存泄漏和碎片化等问题。所以服务器一般会用java和golang写,因为支持协程,有内存池,简单又高效。

RAII问题也是,虽然语法上支持了手动RAII,但是很多人在构造的时候忘记初始化了,导致变量或者指针的不确定性,添加了成员变量,结果忘记在构造函数里面初始化了,特别是大型项目开发的时候,这种操作太多了,导致大家排查bug的时间超过写代码的时间。像c#,dlang,object-c变量就不需要手动初始化,全部赋值为0,其实c++也是可以做到的,就是为了追求所谓的性能,就是一条指令的事情,真的很浪费性能吗?那为什么还要在构造函数里面在手动初始化?为啥多此一举?

像rust, C#,golang都早就支持反射了,而c++依旧没有,那么好用的功能大家都有了,代码动态加载就不说了,C++可能需要虚拟机之类才能做到,但是最基本的序列化那么烂是什么情况?别人都支持json,xml绑定了,完全可以简单实现,但他们到目前为止还没支持,我表示叹为观止,我就说那帮人真的就是动动嘴,混口饭吃而已。

ABI问题还是严重的历史包袱,特别是开发动态库的时候,也只能用c来做接口,C++封装一下就完了,其他软件就无法正常使用了,因为符号又变了,导致无法链接到库函数。这也是很让人头疼的问题,你说C++还能拿来干嘛?扯淡吗?要论性能我为什么不直接用C和汇编?nginx,ffmpeg不都是大型项目吗?C怎么不行了?

所以我一直认为标准委员会就是混饭吃的,大家常用的功能没添加进去,搞了一些没用的东西。如果非得一根经,rust很快就取代了,就是语法比较晦涩而已,早期的dlang就是为了取代c和c++的缺陷,而且编译很快,几乎修正了C++很多缺陷,但还是有很多库,框架都是C++写的,很难替换掉。

我一直想从C++的编译上下手,消除C++的过于明显的缺陷,所以打算在GCC的编译器上动刀,比如对GC以及RAII和反射的支持。只需要加入参数就能够编译出带GC版本的C++,能够让C++在通用的场景下开发,特别是应用层软件开发的时候,大家不必为了指针和内存问题而烦恼。如果要开发内核,驱动或者系统级别的程序,可以用Iso版本的。这样也可以向下兼容,能够在让C++适用在不同的场景下,我觉得也蛮好的,降低开发周期和学习成本才是最重要的事情。计算机最终目的是把复杂的事情简单化,而不是更加复杂!当然你是大神的话,也可以一起加入我们的组织,共同改进很多问题。

项目地址:https://github.com/jasonsalex/china-gcc-cpp

联系邮箱:531401335@qq.com


点击全文阅读


本文链接:http://zhangshiyu.com/post/95299.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1