为何Emscripten与原生代码运行整数运算结果不同?
原生编译与WASM环境下整数运算结果差异的原因
在原生编译环境(g++ 11.4.0,Ubuntu 22.04)下,以下C++代码运行输出-1;但经Emscripten 3.1.66编译为WASM并在Node.js中运行时,输出4294967295。修改HB的类型为long long后,两种环境均输出-1。
#include <iostream> int main() { unsigned F = 20; long HB = 19; // 若此处改为`long long`,两种环境均输出-1 std::cout << HB-F << std::endl; return 0; }
差异原因分析
核心原因是不同环境中long类型的宽度不同,触发了C++整数运算转换规则的差异:
- Ubuntu g++环境:
long是64位类型,其类型秩高于32位的unsigned int(变量F的类型)。计算HB - F时,F会被提升为64位有符号整数,19 - 20的结果为-1,直接输出该有符号整数。 - Emscripten WASM环境:
long是32位类型,和unsigned int的类型秩相同。此时C++规则会将有符号的HB转换为32位无符号整数,19减去20得到的-1会被解释为32位无符号整数的最大值4294967295,因此输出该值。
当将HB改为long long后,无论哪种环境下long long都是64位类型,其秩高于32位unsigned int,F会被提升为64位有符号整数,计算结果始终为-1,所以两种环境输出一致。
内容的提问来源于stack exchange,提问作者Sir Nate
相关产品推荐
相关产品推荐

