@
abcbuzhiming 结论上我同意这位说的。
不过到这个份上,所有在这楼里提到问题的其实还只是冰山一角……能只考虑单一项目的问题而不是更长期的副作用,实在是很幸福的了。一方面,做项目会遇到选型问题;另一方面,维护个人技术栈也是很坑的。
虽然和主题没有直接的关系,我在这里想多补充一点生态而不是方案上的牢骚:造成现在的混乱的原因,虽然算不上是有意的,但过于放纵 naive 的 native 方案的开发者多少都有历史责任。
首先,业界公认的一些基础方案的可移植性实际是非常强的,远远超过在个别指定平台中选择可行方案的跨平台需求,但欠缺足够多的用户去鸟,造成形同虚设,还要在标准化上倒贴维护成本。
像 ISO C 从一开始就强调 portability,强到了绝大多数应用开发者匪夷所思的地步——比如 CHAR_BIT >=8 ( 1 字节可以大于 8 位),比如整数的表示可以源码补码反码之一,比如 '0' ~ '9' 执行字符集要求编码连续但 'A' ~ 'Z' 就不是……
一方面这些差异因为几乎从来没什么开发者去纠结而默认了—— POSIX 和 Win32 以及常见体系结构都钦定 1 字节 = 8 位,几乎所有体系结构都要求机器数用反码,除了 IBM 的某些异类都要求 'A' ~ 'Z' 的编码连续……这样的一个结果就是大多数 C 的开发者其实只是使用了一个较弱可移植性的子集。而 C 的层次上,因为提供了这样强的可移植性,对实现的约束就非常弱,所谓 strictly conforming program 几乎就没什么实际的活能干。其实 C 的用户在这个意义上已经分裂了,绝大多数的人都在用 GNU C、POSIX C 或者 Win32 下的 MSVC 方言,外加一票嵌入式平台的魔改方言。另一方面,ISO C 又不可能把这些方言都吸收了,因为这削弱可移植性,跟 C 的设计者的意愿就有冲突,也会引起不同厂商之间不可调和的矛盾。这就是一个长期没人能解决的两难状况。
ISO C++ 因为 C++ 的复杂性这样的一坨屎的情况,比 C 总体好得多(虽然 C++ 的乱加特性还导致另外的问题),比如干脆直接回避了 strictly conforming program 的概念。不过大部分 C 的可移植性包袱包括用户脱离语言 spec 的认知的问题也还是继承了下来(如大部分用户可能都不知道直到 C++20 才刚刚要去除除了补码以外的机器数的支持)。这样长期下来的结果就是 C++ 和 C 用户一样具有强烈的碎片化倾向,而标准语言长期不够用又反过来让不可移植的小圈子扩展更加猖獗继续加剧碎片化(如 Qt 的 moc )。加上非通用工具使用经验的依赖,进一步大幅提升招人的成本。
对关心以后业界发展的生态用户来说,这一直是两难问题。一方面不能否认 Qt 这样的(相对标准 C++ )半吊子扩展方案确实解决了标准语言不便搞定的不少问题;另一方面,越是依赖 Qt 这样的方案,越是没有办法阻碍分裂,以至于以后越来越不可能有标准化的跨平台方案能用(直接的原因:人员和工具成本越来越高)。
所以在选型的立场上我也是两难的态度:一方面用 C++ 这样的基础方案本身已经在承受无法彻底解决问题的困难;另一方面,足够大的项目中不去用 C++ 这样的单一基础方案而分别重复造轮子的选项,多出来的开销迟早会让你无法自拔。
WG21 已经认识到这里的问题的严重性了,所以才强推不适合在语言 spec 里搞定的 module 之类的东西,以便加强 tooling。不过技术上这种强行乱来我是不看好,该无视的还是无视吧。
(至于 C/C++ 最终是靠什么才在一片混战下活了下来?山中无老虎猴子称大王+历史包袱。)
其次,有不少大企业想建立生态填补这里的矛盾,但实际上技术上都失败了,败给了 C/C++ 的历史包袱。
考虑现在应用的技术栈,操作系统(是个大坑)先不提,光是运行时的实现,只要有些定制需求,就不可能彻底甩脱这个包袱。比如,各种服务器语言的运行时不是 C 就是 C++ 实现的;最终用户碰到的 web agent 几乎无一例外都是 C++ 实现的。结果就是你逃离 C/C++ 完成常规的开发基本还算可行,但一旦要“调优”,就得多少储备这些实现上的细节。然而运行时基本都不是自己开发的……谁能保证这样的任务总是能够被解决?(于是有的企业干脆就自己定制语言实现了,但还是一种循环。)
好在大部分项目在接触到这个坑之前,业务上可能就已经自然死了。但万一没死……恭喜你又制造了一坨业界历史包袱……
苦中作乐的话这也不全是坏事:恶心的屎全归结到 C/C++ 以后,C/C++ 就是屎的事实上的金标准,甚至在没有具体厂商撑腰的前提下就可以避免 vendor lockin。比如听说某果想仗着 ObjC 搞垄断?没关系,你 ObjC 糊弄多少新的开发者也没 C/C++ 的历史包袱和群众基础,只要能糊得上,就算没 native 程度的支持是会恶心到大多数开发者,但谅你也不敢彻底不支持,否则就是自寻死路。(相比之下,web 自己作另说,搞图形学什么的就有点惨了。)
最后,作为历史包袱的受害者能怎么做?
横竖都不咋地,如果没法改变所谓的生态,自求多福,祈祷不会遇到意外吧。
如果谁真能在业务以外实际推动跨平台的实践,我姑且代表个人表示感谢。不过我是真不太信整个蓝星人都不太搞得好的问题,一般人能不添乱的。能尽量别依赖并且能适当抵制不靠谱的半吊子 native 方案就不错了。
请量力而行。