함수 부분 제어 반환에 대해

프로그래밍/C 2020.07.08 댓글 Plorence

C, C++에서는 함수의 모든 경로에서 반환하지 않아도 됩니다.

#include <stdio.h>
int function(int n) {
    if (n == 1) {
        return 1;
    }
}
int main(void) {
    printf("%d \n", function(1));
    printf("%d \n", function(2));
}

이런 상황을 말합니다.
function 함수는 항상 의도한 값이 반환되지 않습니다.

warning C4715: 'function': 모든 제어 경로에서 값을 반환하지는 않습니다.

컴파일하면 이런 경고가 나타납니다.

C#의 경우

C와는 완전히 다른 언어지만, 모든 코드 경로에서 return 문이 있어야 합니다. 는 저도 반드시 적용되어야 한다고 생각하기에 꺼내봤습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Policy;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            f(10);
        }
        public static int f(int n)
        {
            if (n == 1)
            {
                return 1;
            }
        }
    }
}

컴파일하면 아래와 같은 에러가 발생합니다.

CS0161 C# '': not all code paths return a value
(심각도    코드    설명    프로젝트    파일    줄    비표시 오류(Suppression) 상태
오류    CS0161    'Program.f(int)': 코드 경로 중 일부만 값을 반환합니다.)

C# 같은 경우 어떠한 코드 경로라도 반드시 반환을 해야 합니다.

MSDN CS0161

왜 C++에서는 이런 문제가 발생할까?

develop preference에 올라온 내용에 따르면, C와의 역 호환성(backwards compatibility)때문이라고 합니다.
C에서 이것을 허용하고 있기 때문에, C++도 그렇다는 겁니다.

Why is C++ backward compatible with C ? Why isn't there some “pure” C++ language?(Stackoverflow)

그럼 C는 왜 그러는 건가?

#include <stdio.h>
int function(int n) {
    if (n == 1) {
        return 1;
    }
}
int main(void) {
//https://stackoverflow.com/questions/14737104/what-is-the-default-c-std-standard-version-for-the-current-gcc-especially-on-u 참고함
    #ifdef __STDC_VERSION__
    printf("__STDC_VERSION__ = %ld \n", __STDC_VERSION__);
#endif
#ifdef __STRICT_ANSI__
    puts("__STRICT_ANSI__");
#endif
    printf("%d \n", function(1));
    printf("%d \n", function(2));
    return 0;
}

이 코드를 온라인 컴파일러로 돌려봅시다.

-Wall -std=c89 -O2 -o a.out source_file.c

인자는 이렇게

1734980228/source.c: In function ‘function’:
1734980228/source.c:6:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
__STRICT_ANSI__
1 
0

C89에서도 Warning으로 발생합니다.

그럼 C는 왜 그러는 건가?

많이 찾아봤는데, 일부러 허용하고 있는 것 같습니다.

코드 짜는 건 당신의 몫이니까

다만 함수의 끝으로 인해 종료되고 이 반환 값을 읽으려고 시도하면 UB입니다.
UB란?

int foo(){

}
int main(void){

    int a = foo();

}

이런 경우, UB입니다.

추가로 읽어보면 좋은 것들

C and C++ functions without a return statement [duplicate](Stackoverflow) 참고

댓글