一个简单的函数,返回一个全局的指针:
_Uint64t *xxxxx()
{
return 全局指针;
}
但运行时发现xxxxx的返回值的高32位被清空。
函数的汇编没有问题
0000000000003a0c <xxxxx>:
3a0c: f0000080 adrp x0, 16000 <__dso_handle>
3a10: 91018000 add x0, x0, #0x60
3a14: d65f03c0 ret
但调用的地方
4308: 97fffbad bl 31bc <xxxxx>
430c: 93407c00 sxtw x0, w0 //x0作为返回值,被做了 符号扩展, 即x0的高32位被清掉了
4310: aa0003e5 mov x5, x0
439c: 97fffb88 bl 31bc <xxxxx>
43a0: 93407c00 sxtw x0, w0 //x0作为返回值,被做了 符号扩展, 即x0的高32位被清掉了
43a4: aa0003e3 mov x3, x0
所用调用的地方都是一样。
奇怪的是用GDB 调试一切正常,但程序单独运行就崩溃。
仔细看编译是的warning
:178:24: warning: implicit declaration of function 'xxxxx'; did you mean ''? [-Wimplicit-function-declaration]
这个说xxxxx函数未声名。反正函数存在,链接是没问题
: warning: assignment to '_Uint64t *' {aka 'long unsigned int *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
关键这条, 说 函数返回值_Uint64t * 被转成了int.
这就是高32bit 别清的原因啊。
平时感觉 warning treated as error 有点烦,现在看还是很有用的。
这个问题用了几个小时才查出来。