c++这门语言真的越了解越反对——记今天我被C++硬控的5H

本人之前开发需求都是Java/Kotlin+rust通杀GC语言和非GC语言,现在有了codex娘这匹神级坐骑后更是如入无人之境。近期接到一个安卓需求,大致链路是C++底层库调用上层链路,保险起见我把所有C++代码视为unsafe,业务逻辑放在rust层,尽量确保安全。

codex写完之后编译运行,不出所料崩溃了,毕竟接触到C++了,大概率会变得不幸。我本来以为就是rust和C++层的ffi边界问题,两边接口对不上,语言不通把应用给骂崩溃了,让codex排查它也认为是这个方向,于是开改。

改完后一跑又崩溃了,这下逐渐开始发现事情不对了,仔细看看崩溃栈:

libc++_shared.so     std::__ndk1::basic_string::append(...)
<app>.so  AppendString(...)
<app>.so  request_policy_callback(...)
<biz>.so  <callback caller>

很疑惑,就一个stringappend能出啥问题?

崩溃信息:

NOTE: Function names and BuildId information is missing for some frames due to unreadable libraries. For unwinds of apps, only shared libraries found under the lib/ directory are readable. On this device, run setenforce 0 to make the libraries readable.

biz库提供了一个这样的接口:

extern "C" int request_policy_callback(
    const char* method,
    const char* url,
    const std::map<std::string, std::string>& header,
    const unsigned char* body,
    int body_size,
    const std::map<std::string, std::string>& info);

如果不动header和info这俩天尊,应用就不会崩溃。

这个功能还给了其他业务的接入样例,是一比一照着写的,感觉已经不是一般的问题了,不应该局限于代码。遂把apk扔给codex,让它给我狠狠查so里面的符号,严查!

这一查啊,果然查出大鱼了:
我们编出的app.so认为std::map<std::string, std::string>是
std::__ndk1::map<std::__ndk1::string, std::__ndk1::string> ,但是biz.so里面却是std::Cr::map<std::Cr::string, std::Cr::string>。

:clap:t2:

询问库的维护方,得到质疑:

为什么其他的业务没问题,就你们有问题?

继续排查后,库维护方得知他们给其他业务提供的库编译时动态链接了ndk的stdcpp,给我们提供的版本静态链接了内部的stdcpp。

事情目前进展到此,现在我正在等动态链接stdcpp的新版本。

SB C++,标准库都没一个统一的,用rust从来没遇到过这个问题

15 个赞

虽然我理解你的遭遇

但是不赞同你的看法
rust作为后起之秀吸取了cpp很多教训,比cpp做得好是正常的
同时cpp利益方太多了,没办法统一

5 个赞

库的维护方也太有意思了,不过也很正常的想法,他们后面怎么愿意去查的呢

语言的好坏是客观的,cpp 客观上就是设计得极烂,这种烂体现在编译困难、分发困难、语法问题、潜在错误发现困难等方方面面,纯靠历史惯性活着。当然我支持学习 cpp,毕竟一个得了几乎所有病的病人比一个很少得病的健康人研究价值大太多了。

5 个赞

他们可能也想不到,明明提供的都是 STD 标准接口,为啥有的业务方能用,有的业务方用不了?

2 个赞

前半句说得很好
少一个官方的cargo

但是绝对不只是靠历史惯性活着
新项目用cpp的很多,尤其是llm相关的

一个语言程序员存量的积累也是历史惯性的一部分

2 个赞

不多说了

4 个赞

非要拿一个有40多年历史包袱的语言和一个没什么历史包袱的语言比,那也是没招了,客观上没有c++还没有rust呢

4 个赞

不这么认为,因为要是一统计站内真搞cpp的没多少的
cpp用得多肯定是有比rust好的地方

所谓没有银弹

1 个赞

看成 codex 娘希匹了:rofl:

7 个赞

关于统一,rust只有一份当然统一了,要是rust也有多个阵营的编译器,你看看还统一吗?

理论上导出接口应该使用C,C++ abi兼容性比较差,否则内存布局可能不一致
要不然就给源码自己编译
当然没使用C++/C开发的很难懂 哈哈
C++ 历史包袱太多,基本每个厂商都有自己的标准库

2 个赞

而且c++abi在这些高级语言中稳定性已经是非常高的了,非要拿不同编译器那我只能说是极其不公平的,当然你也可以像rust那样直接走源码分发,但是这不能说明rust abi比c++稳定.然后就是c++标准委员会给自己的定位就是纯粹的抽象层

c++是真的乱,工具链也乱、看不进去

C++的编译器差别很大的,不仅不同厂家的编译器(MSVC、G++、CLANG/LLVM)std会有区别,而且甚至不同的架构或者不同版本的,基本std都会变,而且报错也会变,不同厂家的静态检查策略也不一样,嵌入式也是五花八门。而且包管理器也是一个没有的,我现在都只用QT来跨平台兼容了……

1 个赞

你但凡说点 C++ 其他的优势呢?:distorted_face: ABI 业界的唯一标准就是 CABI,生产环境,谁敢拿 C++ 标准做 ABI?然后我这次遇到的问题和 ABI 是没有关系的。而是类似两个库之间约定使用了同一个接口,结果因为实现不同而崩溃了。

1 个赞

庆幸现在是2026,放4年前至少得排查3天吧

3 个赞

我什么时候说拿c++abi做标准了?

我主要是没搞明白,你突然来一句“C++ 的 ABI 稳定性已经非常高了”想表达什么意思,如果仅仅是这句话的字面意思,为什么要发在这里,感觉这句话本身和我遇到的 bug 以及讨论的主题好像没有什么特别大的关系。