首先,你这么写肯定是不对的,既然有%x,%d,又不加参数,那肯定会输出未定义的值。
如果你一定要追究为什么,其实看一下汇编就知道了:
va_start(ap,fmt);
00011024: E28D3E11 add r3, sp, #0x11, 28 //r3=sp+0x110
00011028: E2833004 add r3, r3, #4 //r3=r3+4
0001102C: E58D3100 str r3, [sp, #0x100] //[sp+0x100]=r3 => ap=r3
vsprintf(string,fmt,ap);
00011030: E59D2100 ldr r2, [sp, #0x100] //r2=[sp+0x100] => r2=ap
00011034: E59D1110 ldr r1, [sp, #0x110] //r1=[sp+0x110] => r1=fmt
00011038: E28D0000 add r0, sp, #0 //r0 =sp => r0= str
0001103C: EB000229 bl vsprintf
所以vsprintf的第三个参数ap是传入的fmt+sizeof(fmt)的地址,由于fmt在栈上的位置已经固定了,而栈是从高到低的,所以fmt+sizeof(fmt)的值虽然是未定义的,实际上也是固定的值。