最近在修改一个 C 的开源小项目。因为是想在 Win 下用的,但项目是用 autoconf 构建的,所以准备了 MSYS2 UCRT64 环境来开发。然后就踩了处理不了大于 2G 文件的坑(用了 fstat)。虽然说就是一个 _FILE_OFFSET_BITS 宏的事,但毕竟是个跨平台项目,所以就查了下主流系统下这个问题的支持情况,感觉好多槽点。
个人觉得 2GB 以上大文件并不是什么很罕见的用例,为什么开发环境就不能默认支持这些情况呢,难道还影响兼容性?
标题里的“为未来准备好”是指,只使用跨平台的 C/C++,加上 2000 年后的 POSIX:
似乎要在无第三方依赖的情况下做到这个是很困难的事?
1
Thymolblue 21 小时 31 分钟前
- 即使是 2026 年了,微软也没解决中文路径编码问题。我在程序里的字符串统一使用的是 UTF-8 编码,POSIX 下没有任何问题,但是在 Windows 下路径直接就识别不了。
- 另外跨平台项目更推荐使用 CMake 提供构建支持。autoconf 依赖 bash 环境,不是所有设备都能够很容易安装的。 - 现在很多开源的都库不支持编译成 32 位,32 位的系统也不常见了,不如直接只支持 64 位设备。 |
2
pursuer 21 小时 13 分钟前
因为 C/C++跨平台本就不怎么样,autoconf 更是重量级,要跨平台就 libuv+CMake 。
确实 2GB 以上大文件不算罕见,但就像你说的,这是 ABI 不兼容,对于 c/c++,兼容性更重要。虽然 Glibc 自己都做不好 ABI 兼容。 |
3
xtreme1 20 小时 56 分钟前
因为在 WINAPI / libc 层面是玩不了黑魔法的, 分分钟内存越界
|
4
capric 20 小时 44 分钟前
你让 ai 把 autoconf 转换为 meson ,然后用 zig cc 当交叉编译器就很舒服
|
5
penisulaS 20 小时 44 分钟前
见过一个项目直接用 rust 写壳包 c 核,就是因为 posix 兼容太烦人
|
6
changnet 20 小时 15 分钟前
1. posix 是一套操作系统接口标准,而 C 是一门语言。写 C 不能按 posix 去写。就好比打包出来一个 apk ,老是有人问在 win 上为什么安装不了 apk 一样。
1. posix 在 linux 下还行,但在 win 下就是不行。这个是微软的问题,它早年就是独立于 posix 的。后来 posix 用得广了才勉为其难加了兼容接口,但一直不怎么维护,和 posix 的兼容性也不太好。 2. C/C++都是专注于语言而不是应用,它们所给的标准都是基于语言层面的。各个平台自己咋实现它不管。所以它的标准库接口很少,stl 也很少。很多功能必须用系统 api 3. minGW 和 CyWin 这东西本来就冷门,维护也是跟不上的。我试过把 linux 上的程序迁移到 win ,想着用 CyWin 可以少改些。但实际勉强能跑起来但很难维护,第三方库大多没有官方支持,所以直接切换到 MSCV 了。 4. C/C++现代一些的应该是用 CMake 的项目,autoconf 应该是 linux 下的项目了。 C/C++因为历史的原因,它就是没法做到像其他语言那样跨平台 api 统一的。如果是新项目,用 cmake + 新标准(比如 C++ 17 以上)可以解决 90%的问题,比如你说的用 C++的 std::filesystem 应该是可以的。剩下的 10%用各自原生的平台接口维护(比如网络接口)。 但你是旧项目,要么全改,要么写各种兼容 |
7
Mithril 20 小时 13 分钟前 所以“新程序”已经尽量不用 C/C++来写了,特别是如果你的程序想要跨平台的话,项目做大了就会发现到处都是坑。
更别说你做个开源项目了,大半精力都要花在维护这些乱七八糟的编译环境上。 |
8
Mithril 20 小时 6 分钟前
另外基于我之前做的调查结果,最省心最简单的 C++跨平台,就是你只针对 Windows 开发,然后各种*nix 全用 Wine/Proton 去跑。
Wine 上面的 API 兼容需要测试,你用到一些奇怪的 API 很可能在 Wine 上跑不通。不过但凡能跑通,绝对比你去每个平台维护一套编译,测试,要容易太多了。测试通过以后把 Windows 的二进制扔进去直接跑。 有人说 Wine 是各种 Linux 上最稳定的 ABI 不是没有道理的。各种发行版你要都支持,光是 glibc/Musl 都能搞你一下。 缺点就是这项目维护最好的只有游戏能用得到的那些 API ,如果你的程序还要调用别的 API ,比如硬件相关的,那就没办法了。 |
11
Ketteiron 19 小时 16 分钟前
Rust 会流行,有很大原因就是 C/C++ 这些狗屁倒灶的事情无法解决。
根本原因还是 ABI ,C/C++ 选择绝对的向后兼容,代价就是历史遗留问题几乎无法处理; Rust 非常激进走了另一条路,不提供任何稳定 ABI ,因此清理历史包袱的代价非常轻。但是,哈哈,Rust 有稳定的 C ABI 。 要我说,还是 C++ 太贪婪了,既想要一切抽象和范式,又想要保证向后兼容,还得为 n 个平台擦屁股,根本是做梦。 目前最务实的做法还是 Rust + C ,两个语言都有各自的破事,不如合起来只用最好的部分。 |
12
xuanbg 18 小时 53 分钟前
直接让 AI 翻译成 rust 好了
|
13
WorseIsBetter 18 小时 40 分钟前
我的个人项目(参考我发的第一个主题帖)也有处理 32-bit/64-bit 的 off_t/time_t 。我觉得这块其实是很 trivial 的,没你说的那么复杂。
原则只有一条:管好自己的项目就行。 你的代码里需要意识到这些类型有 32-bit 和 64-bit 两种可能,并且分别对其做支持(或者不对某些情况做支持并让构建过程失败),就足够了。至于和其他程序的 ABI 兼容,是由发行版的包维护者或者用户自己(如果他们选择自行构建)来保证的。 除此之外,你唯一能做的,大概只有把构建脚本写得更灵活、优雅,再配上清晰明确的构建文档,让包维护者和用户少走或不走弯路。 另外:不建议依靠 autoscan ,那玩意只起到一个基本的示例作用,对实际项目的帮助不大。还是得想清楚自己具体需要在 autoconf.ac 中检查什么、配置什么,然后根据需求来写 |
14
xiliuya 15 小时 17 分钟前
不要用 windows 就可以完美解决这个问题,不是 c/c++的问题,而是 win 的锅。
|
15
beautyplus 14 小时 46 分钟前
本质还是编码对不上,跟 windows 系统 **交互** 是要尽量用 wchar 的,尤其是带路径参数的函数比如 wfopen ,CreateFileW ,因为你不确定目标机器有没有开启 utf-8 (区域设置中的使用 utf-8 还标记着 beta 默认不勾选)
|
16
cnbatch 13 小时 21 分钟前
这是 C 的事情,发到 C++板块不怎么妥当吧
前半部分 1 ,这是 MSYS MinGW 的锅,它们没处理好 64 位的适配。Windows 提供了 fseeko64 的替代品 _fseeki64(),中间转换层本该做好映射支持的。 2~6 ,这就是系统 API / SDK 的锅,包括 Android 至于换语言能“解决”这些锅,本质上只是它们在标准库里面帮忙擦屁股而已。 「为什么开发环境就不能默认支持这些情况呢,难道还影响兼容性?」 开发环境当然可以默认支持这些情况,正常 POSIX 环境、正常 MSVC 环境直接写程序调用标准库 API 都没问题。 没做到默认支持,很多时候完全是疏忽 (MSYS MinGW),或者是怕麻烦、赶进度(Android 5.0~6.0)。 后半部分 1 、若是 OS Level 的限制,编程语言本身能做的事情其实很有限。如果 OS 本身没解决 2038 问题,只要系统关机、重新开机,系统时间直接就是乱的,再完善的编程语言都没办法强行掰回来。 若 OS Level 已经解决了 2038 问题,那么无论是 C 还是 C++,都不需要担心这种事。 2 、纯 POSIX 可以。跨平台跨到 MSYS MinGW 的话,按理说 MSYS MinGW 应当处理好相应转换(像是背后处理编码调用带 W 的 API 、检测目标 Windows 有没有启用 UTF-8 区域选项),但这就不是普通使用者可以强制要求的了。 3 、这就有点霸道了,别说 C 语言、C++,哪怕是 Python 都没法如此保证。 4 、单纯“不拒绝使用”的话,那还是不需要担心。如果想要更高要求达到“表现一致”,那就不太可能了。 Linux 的 IPV6_V6ONLY 默认为 false ,而 BSD 和 macOS 还有 Windows 的 IPV6_V6ONLY 默认是 true 。 OpenBSD 更是搞起了内部限制,无论 IPV6_V6ONLY 设成什么值,它都按照 true 处理。 5 、类似 2 6 、支持近十年出厂的系统很合理。但硬件??这可不是编程语言可以掌控的吧,这是 OS 和驱动程序的责任啊。 |
17
adoal 13 小时 9 分钟前 文件系统和其它需要 text label 的 API 支持 Unicode 用什么模式只是一种选择而已。Unix 世界为了兼容标准 C 库的字符串 0 结尾语义而选择了 UTF-8 locales ,Windows 为了不破坏已有的 MBCS locales 里的编码语义而选择了用双模 API ,本来就是不同理念,各有优缺点。没理由 POSIX 的做法比 Windows 更正确或更“标准”。
|
18
xyx0826 8 分钟前 via iPhone
参见 [jart/cosmopolitan]( https://github.com/jart/cosmopolitan) 项目,一个让 C 语言一次编译、到处运行的库。现支持 Windows, Linux, macOS, *BSD 。UTF-8 读写支持也包含在内,例:[romanize.c]( https://github.com/jart/cosmopolitan/blob/master/examples/romanize.c)
这是我所知的最接近你要求的项目。 |
19
xyx0826 3 分钟前 via iPhone
附:redbean 是同作者基于 Cosmopolitan C 开发的一个跨平台 web server, 本身还是一个 zip 包用来装 lua 脚本和静态资源。
https://redbean.dev/ |