我发现wasm3和Emscripten处理负溢出的方式不同。例如,如果我调用一个数组的负下标,wasm3将返回下标0处的值,但Emscripten将返回似乎来自堆栈的值。
这是由于内置于wasm3的保护不存在于Emscripten,还是由于他们如何处理他们的堆栈不同?
示例输出
C代码:
#include <stdio.h>
int ar[]={1,2,3,4,5};
int visit(int n){
return ar[n];
}
int main()
{
for(int i=6; i>-5;i--){
printf("Loop num: %dn",i);
int temp = visit(i);
printf("Loop val: %dn",temp);
}
}
Emscripten | Wasm3 |
---|---|
循环数:6循环值:5 | 循环数:6循环值:0 |
循环数:5循环数:0 | 循环数:5循环数:0 |
循环数:4循环数:5 | 循环数:4循环数:5 |
循环数:3循环数:4 | 循环数:3循环数:4 |
循环数:2循环数:3 | 循环数:2循环数:3 |
循环数:1循环值:2 | 循环数:1循环值:2 |
循环数:0循环数:1 | 循环数:0循环数:1 |
循环次数:-1循环次数:117894759 | 循环次数:-1循环次数:1 |
循环次数:-2循环次数:2457754 | 循环次数:-2循环次数:1 |
循环数:-3循环数:25634578 | 循环数:-3循环数:1 |
循环num: -4循环val: 85773057694 | 循环num: -4循环val: 1 |
访问不属于对象的内存(在这种情况下访问边界外的数组元素)会调用未定义行为(UB)。
-数组下标超出范围,即使对象明显超出范围可通过给定的下标访问(如左值表达式中)一个[1][7]鉴于宣言int[4][5])(6.5.6)。
不应该期望有任何行为,也不能保证在未来的版本中相同的编译器会以相同的方式运行
还是因为它们处理堆栈的方式不同?
C标准不知道关于堆栈的任何事情。即使使用堆栈实现也不会将静态存储持续时间对象(代码中的ar
)放在堆栈上。