Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C/C++ 프로그래밍에서 발생하는 5가지 오류 유형 총정리

C나 C++로 프로그래밍을 하다 보면 다양한 종류의 오류(error)와 마주하게 됩니다. 이러한 오류는 크게 다섯 가지 유형으로 분류할 수 있습니다.

  • 구문 오류(Syntax Error)
  • 런타임 오류(Run-Time Error)
  • 링커 오류(Linker Error)
  • 논리 오류(Logical Error)
  • 의미 오류(Semantic Error)

지금부터 각 오류 유형이 언제 발생하고 어떻게 해결해야 하는지 하나씩 자세히 살펴보겠습니다.

1. 구문 오류 (Syntax Error)

구문 오류는 C++ 작성 규칙이나 문법(syntax)을 위반했을 때 발생합니다. 이 오류는 대부분 컴파일러가 컴파일 단계에서 미리 감지하여 알려주기 때문에 '컴파일 타임 오류(compile-time error)'라고도 불립니다.

다음 예제는 코드 한 줄 끝에 세미콜론(;)을 붙이지 않아 구문 오류가 발생하는 경우를 보여줍니다.

예제 코드

#include<stdio.h>
main() {
    printf("Hello World")
}

출력 결과

[Error] expected ';' before '}' token

printf 함수 호출 뒤에 세미콜론이 빠져 있어 컴파일러가 '}' 토큰 앞에 ';'가 필요하다는 오류 메시지를 출력합니다.

2. 런타임 오류 (Run-Time Error)

런타임 오류는 프로그램이 실제로 실행되는 도중에 발생하는 오류입니다. 컴파일 단계의 오류가 아니기 때문에 컴파일은 정상적으로 완료됩니다. 대표적인 예로 숫자를 0으로 나누는 경우를 들 수 있습니다.

예제 코드

#include<stdio.h>
main() {
    int x = 52;
    int y = 0;
    printf("Div : %f", x/y);
}

출력 결과

프로그램이 실행 중에 비정상 종료(크래시)됩니다.

x를 y(0)로 나누는 연산은 수학적으로 정의되지 않으므로, 프로그램이 실행 시점에 비정상적으로 종료됩니다. 따라서 나눗셈 코드를 작성할 때는 항상 제수(divisor)가 0이 아닌지 확인하는 로직을 추가하는 것이 좋습니다.

3. 링커 오류 (Linker Error)

링커 오류는 프로그램이 성공적으로 컴파일된 후, 여러 개의 목적 파일(object file)을 하나의 실행 파일로 연결(linking)하는 과정에서 발생합니다. 이 오류가 발생하면 최종 실행 파일이 생성되지 않습니다. 잘못된 함수 프로토타입 선언이나 잘못된 헤더 파일 포함 등이 대표적인 원인입니다. 예를 들어 main()을 Main()처럼 대소문자를 잘못 입력하면 링커 오류가 발생합니다.

예제 코드

#include<stdio.h>
main() {
    int x = 52;
    int y = 0;
    printf("Div : %f", x/y);
}

출력 결과

undefined reference to `WinMain'

위 출력은 Windows 환경(MinGW)에서 진입점 함수를 찾지 못해 발생한 링커 오류의 전형적인 예시입니다. 함수 이름이나 참조 대상이 올바르게 정의되어 있는지 반드시 확인해야 합니다.

4. 논리 오류 (Logical Error)

때때로 프로그램은 정상적으로 실행되지만 우리가 기대한 결과가 출력되지 않을 수 있습니다. 구문이나 문법적인 부분이 모두 올바른데도 논리적인 실수 때문에 잘못된 결과가 나오는 것을 논리 오류라고 합니다.

예를 들어 반복문(for, while) 뒤에 세미콜론(;)을 붙이면 문법적으로는 옳지만, 아무 일도 하지 않는 빈 반복문이 만들어집니다. 그 결과 본래 의도한 출력이 나오지 않습니다.

예제 코드

#include<stdio.h>
main() {
    int i;
    for(i = 0; i<5; i++); {
        printf("Hello World");
    }
}

출력 결과

Hello World

원래 의도라면 "Hello World"가 다섯 번 출력되어야 하지만, for 문 바로 뒤의 세미콜론으로 인해 빈 반복문이 실행되고 printf 문은 딱 한 번만 실행됩니다. 논리 오류는 컴파일러가 잡아주지 않기 때문에 코드 검토와 테스트를 통해 직접 찾아내야 하는 까다로운 오류입니다.

5. 의미 오류 (Semantic Error)

의미 오류는 문법적으로는 올바르지만 문장이 가진 의미가 없는 경우에 발생합니다. 자연어의 문법 오류와 유사한 개념이라고 할 수 있습니다. 대표적인 예로 대입 연산자(=)의 왼쪽에 값이 아닌 식(expression)을 배치하는 경우가 있습니다.

예제 코드

#include<stdio.h>

main() {
    int x, y, z;
    x = 10;
    y = 20;
    x + y = z;
}

출력 결과

[Error] lvalue required as left operand of assignment

x + y는 값을 계산하는 식일 뿐 저장 공간이 아니므로(lvalue가 아님), 대입 연산의 왼쪽 피연산자로 사용할 수 없습니다. 올바르게 수정하려면 z = x + y;처럼 변수를 왼쪽에 두어야 합니다.


마무리

C/C++의 오류는 발생 시점과 원인에 따라 구문 오류, 런타임 오류, 링커 오류, 논리 오류, 의미 오류로 나눌 수 있습니다. 구문 오류와 의미 오류는 컴파일러가 대부분 잡아주지만, 런타임 오류와 논리 오류는 개발자의 꼼꼼한 코드 검토와 테스트를 통해서만 발견할 수 있습니다. 각 오류 유형의 특성을 정확히 이해하고 있으면 디버깅 시간을 크게 줄이고 더 안정적인 프로그램을 작성할 수 있습니다.