使用Emscripten编译C代码报shift count >= width of type警告且结果异常
问题根源
你遇到的报错和结果不一致问题核心是不同平台下C基础类型的宽度差异:
- 原生64位环境下GCC的
unsigned long为64位宽度,<<32是合法操作,因此无警告、运行结果符合预期 - Emscripten默认编译为wasm32目标时,
unsigned long为32位宽度,移位32位超过了类型本身的宽度,属于C语言标准规定的未定义行为,因此触发-Wshift-count-overflow警告,运行结果和原生不一致。
为什么-s WASM_BIGINT没有生效
-s WASM_BIGINT仅用于开启Emscripten对C语言64位整数和JavaScript BigInt类型的交互支持,不会修改C语言本身的基础类型宽度规则,因此无法解决移位溢出问题。
解决方案
两种方案任选其一即可:
- 方案一(更推荐,跨平台兼容):引入
<stdint.h>头文件,使用固定宽度的64位无符号类型替换unsigned long,修改代码为:
该写法在原生64位环境和Emscripten编译环境下的行为完全一致,从根源避免类型宽度差异导致的问题。SomeVariable = ((uint64_t) x << 32) / (uint64_t) y; - 方案二(无需修改代码):指定Emscripten编译为wasm64目标,添加编译参数
-s MEMORY64=1,该配置下unsigned long会使用64位宽度,移位操作会和原生环境行为一致。需注意wasm64对老旧运行环境的兼容性略低于wasm32。
内容的提问来源于stack exchange,提问作者user14783961
相关产品推荐
相关产品推荐

