即使没有return语句,函数也会返回预期值

时间:2014-09-05 03:44:42

标签: c

我这里有一个函数get_stack,它实例化一个堆栈,并且应该返回一个指向堆栈的指针,但不是。仍然,程序继续并正确更新堆栈。

#include <stdio.h>
#include <stdlib.h>    
#define STACKLIM 1000


struct stack {
    char data[STACKLIM];
    int top;
};

typedef struct stack* Stack;

Stack get_stack() {
    Stack s = (Stack)(malloc(sizeof(struct stack)));
    s->top = -1;
    //return s;
}

void push(Stack s, char val) {
    if(s->top == STACKLIM) {
        printf("ERROR: Stack Overflow\n");
    }
    else {
        s->top += 1;
        s->data[s->top] = val;
    }
}

void display(Stack s) {
    int i;
    printf("Stack -> ");
    for(i = 0; i <= s->top; i++) {
        printf("%c ", s->data[i]);
    }
    printf("\n");
}

int main() {
    Stack d = NULL;
    d = get_stack();
    push(d, 'a');
    display(d);        
    return 0;
}

它与返回声明无关。这可能是什么原因?我在RH5机器上使用gcc 4.5.2。

2 个答案:

答案 0 :(得分:4)

无论编译器是否对其进行诊断,如果函数具有非{,则在不返回值的情况下从函数末尾(即达到结束})始终是错误{1}}返回类型。它的未定义的行为

现在,未定义的行为可以通过许多不同的方式表现出来。它可能导致您的程序崩溃,接收错误的值,擦除您的硬盘驱动器,向您的母亲发送令人讨厌的电子邮件,或似乎成功地工作而没有其他不良影响。所有这些行为都是C语言标准所允许的。仅仅因为代码可能看起来工作正常,这并不意味着它实际上是正确和有效的。

如果在调用未定义行为时崩溃,您应该认为自己很幸运,因为这些通常很容易诊断。但是如果你的程序默默地破坏了内存,然后又在一个“不可能”的内容中崩溃了。这种情况,你将会遇到困难的调试工作。

故事的道德:使用高警告级别编译代码(例如,使用void编译器选项;如果可以承担,也可以使用-Wall和/或-Wextra; { {1}}也强烈推荐)。任何值得盐的编译器都会遇到这种错误,但通常不会出现默认警告级别

答案 1 :(得分:1)

以前回答过:Function returns value without return statement

它的要点:当做d = get_stack()时,系统会查看内存中预期找到返回值的某个位置。无论在记忆中那个地方有什么垃圾 - 算作回报。

可能是“eax寄存器”或调用堆栈中的插槽。你很幸运,malloc()的回归卡在了那个位置。在get_stack()中添加一些额外的命令,奇迹就会消失。