C语言函数参数入栈顺序问题

wanyikang 2011-06-26 01:12:34
#include <stdio.h>

void va_test(char *fmt, ...); //参数可变的函数声明

void main()
{
int a = 1, c = 55;
char b = 'b';
va_test("hello,world", a, b, c);
}

void va_test(char *fmt, ...)
{
//char buf[128];
char *p = NULL;
p = (char *) &fmt;
int i;
for (i = 0; i < 16; i++)
{
printf("%.4d ", *p);
p++;
}

}
可变参数的入栈顺序问题,一开始注释掉char buf[128];这条语句,用gdb(ubuntu 10.10下写的)调试结果为:
(gdb) p &fmt
$1 = (char **) 0xbffff320
(gdb) x/4xw 0xbffff320
0xbffff320: 0x08048510 0x00000001 0x00000062 0x00000037
可见确实是C调用约定,由于对齐,字符占4个字节。但当不注释掉char buf[128]时,用gdb调试结果为:
(gdb) p &fmt
$1 = (char **) 0xbffff27c
(gdb) x/4xw 0xbffff27c
0xbffff27c: 0x080485a0 0x00000000 0x00000000 0xbffff27c
后面参数不是传进来的 a, b, c.似乎不符合C调用约定。求原因?
...全文
269 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2011-06-28
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编并单步执行。)

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
wanyikang 2011-06-28
  • 打赏
  • 举报
回复
应该更IDE和平台无关吧!
icyice1989 2011-06-26
  • 打赏
  • 举报
回复
你到windows下调试试,我越到累死的问题,VS下调对了。。
5t4rk 2011-06-26
  • 打赏
  • 举报
回复
帮你顶
有高手来看
wanyikang 2011-06-26
  • 打赏
  • 举报
回复
实际情况是我将char buf[9];这条语句替换掉原来的//char buf[128];这条注释,编译并用gdb调试,结果如下:
(gdb) p &fmt
$1 = (char **) 0xbffff2bc
(gdb) x/4xw 0xbffff2bc
0xbffff2bc: 0x08048590 0xb7f78e79 0xb7e9f785 0xbffff2bc
(gdb) p fmt
我查看了fmt实参的地址,并接着查看了fmt后面12字节的内容:0xb7f78e79 0xb7e9f785 0xbffff2bc,这3组4个字节并不是传进来的a(1),b('b'),c(55)。实际上fmt这个变量并不是传参数时压入栈中的"hello,world"字符串的地址。我想知道为什么加了char buf[9];这条语句fmt就不是传参时字符串的地址了。(不加是fmt确实是传参数时字符串的地址)
金刚葫芦娃 2011-06-26
  • 打赏
  • 举报
回复
va_test("hello,world", a, b, c);
void va_test(char *fmt, ...)
这样, "hello,world" 形参传进来等于复制了一块内存.
wanyikang 2011-06-26
  • 打赏
  • 举报
回复
其实刚才我用<stdarg.h>中的va_start()宏发现C调用约定还是满足的,只是fmt值好像被复制了一份,并且将fmt这个表号解释为复制后的那块内存。不过只是猜测,求大牛指点?
金刚葫芦娃 2011-06-26
  • 打赏
  • 举报
回复
友情帮顶...

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧