2014-09-05 1 views
0

여기에 스택을 인스턴스화하고 포인터를 반환해야하는 함수 get_stack이 있지만 여기에는 없습니다. 그러나 프로그램은 스택을 계속 업데이트합니다.함수는 return 문 없이도 의도 한 값을 반환합니다.

#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

'-Wall'로 컴파일하면 어떻게됩니까? 또한이 링크를보십시오 : http://stackoverflow.com/questions/10079089/implicit-int-return-value-of-c-function – AntonH

+0

최적화 플래그를 사용하고 있습니까? 정의되지 않은 동작은 프로그램을 신비하게 작동시키는 것을 포함합니다. – hugomg

+0

'-Wall'로 컴파일 할 때,'warning : 제어가 비공유 함수의 끝에 도달 함'을 얻었지만 프로그램은 아무런 문제없이 여전히 실행됩니다. – Unos

답변

4

컴파일러에서 진단 여부에 관계없이 함수에 void 반환 유형이없는 경우 값을 반환하지 않고 함수 끝에서 벗어나는 (즉, 닫는 }에 도달하는) 것은 항상 오류입니다. 그것은 정의되지 않은 동작입니다.

이제 정의되지 않은 동작은 다양한 방식으로 나타납니다. 프로그램이 충돌하거나 잘못된 값을 받거나, 하드 드라이브를 지우거나, 불쾌한 이메일을 어머니에게 보내거나, 이 다른 악영향없이 성공적으로 작동하는 것으로 나타날 수 있습니다.. 이러한 모든 동작은 C 언어 표준에서 허용됩니다. 코드가 올바로 작동하는 것으로 보일 수 있다고해서 그것이 실제로 정확하고 작동한다는 것을 의미하지는 않습니다.

정의되지 않은 동작을 호출 할 때 충돌이 발생하면 대개 진단하기가 쉽기 때문에 운이 좋은 것으로 간주해야합니다. 그러나 프로그램이 자동으로 메모리를 손상시킨 다음 나중에 "불가능한"상황에서 중단되면 어려운 디버깅 작업을 수행 할 수 있습니다. 이야기의

도덕은 (; 가능성도 -Wextra 및/또는 -pedantic을 당신이 그것을 감당할 수 있다면, 예를 들어,이 -Wall 컴파일러 옵션을 사용 -Werror도 적극 권장) 높은 경고 수준의 코드를 컴파일합니다. 염분이있는 컴파일러는 과 같은 오류를 catch하지만 기본 경고 수준이이 아닌 경우가 많습니다.

+0

정의되지 않은 행동의 한 경우에 '뱀'이라는 게임이나 그 효과가있는 컴파일러를 기억하는 것 같습니다. 참조를 찾을 수 있기를 바랍니다. – AntonH

+0

@AntonH : 뱀은 아니지만 충분히 발전된 컴파일러 [정의되지 않은 동작을 감지하면 시간 이동을 유발할 수 있습니다.] (http://blogs.msdn.com/b/oldnewthing/archive/ 2014/06/27/10537746.aspx) - 나중에 특정 조건이 UB를 나중에 트리거 할 수 있다고 판단 할 수 있다면 일반적으로 정의 된 동작 인 코드를 적극적으로 최적화 할 수 있습니다. –

1

이전에 응답되었습니다 : Function returns value without return statement.

요점 : d = get_stack()을 수행 할 때 시스템은 반환 값을 찾을 메모리의 일부 위치를 찾습니다. 그 장소에있는 쓰레기가 무엇이든 기억에 남습니다.

"eax 레지스터"또는 호출 스택의 슬롯 일 수 있습니다. malloc()에서 돌아 오는 것이 그 자리에 머물렀다는 것은 운이 좋다. get_stack()에 몇 가지 추가 명령을 추가하면 기적이 사라집니다.

관련 문제