为什么这个GNU C可变函数返回一个庞大的数字?

时间:2016-12-21 01:08:20

标签: c undefined-behavior variadic-functions

我正在查看C语言中的this example可变函数,编写GNU.org。我的操作系统是Debian 8.6。

这是我的略微变化,文件名为ex.c

#include <stdarg.h>
#include <stdio.h>

int addEmUp(int count,...){
    va_list ap; // where list of arguments are stored
    int i, sum;

    va_start(ap,count); // initialize the argument list

    sum=    0;
    for(i=0; i<count; i++)
        sum += va_arg(ap,int);  // get the next argument value

    va_end(ap); // clean up

    return sum;
}

int main(void){
    printf("%d\n", addEmUp(3,4,5,6));
    printf("%d\n", addEmUp(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
    printf("%d\n", addEmUp(10,10,10,10));
    return 0;
}

这是我的makefile _example.mak

CFLAGS=-Wall -g
CFILE=ex

run:
    cc $(CFILE).c -o $(CFILE) $(CFLAGS)
    ./$(CFILE)
    rm -f $(CFILE)

打开终端并运行make -f _example.mak

时的输出
./ex
15
55
1141373223
rm -f ex

为什么第三个addEmUp()打印1141373223

1 个答案:

答案 0 :(得分:4)

您有未定义的行为。

您发送10作为第一个参数,但只用3个附加参数调用addEmUp()

printf("%d\n", addEmUp(3, 10, 10, 10));

当您有未定义的行为时,您无法知道会发生什么。当您的函数addEmUp()va_arg()相距太远时。你可以引起很多想法:

  • 分段错误
  • 错误的行为(你得到的)

喜欢@ user3553031在评论中说:

  

最有可能的是,你添加到sum中的那些其他数字是调用堆栈中的其他数字 - 例如保存的返回地址,甚至可能是sum本身的当前值。这在很大程度上取决于您的操作系统,编译器和机器架构; C没有定义调用堆栈的结构,甚至不需要调用堆栈的结构。