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

C++ 컴파일러에서 컴파일되지 않는 C 프로그램 7가지

C++ 언어는 C 언어에 객체 지향(Object Oriented) 개념과 같은 다양한 기능을 추가하여 설계된 언어입니다. 그래서 대부분의 C 프로그램은 C++ 컴파일러로도 문제없이 컴파일됩니다. 하지만 C에서는 허용되는 문법 중 일부가 C++에서는 허용되지 않기 때문에, 모든 C 프로그램이 C++ 컴파일러에서 컴파일되는 것은 아닙니다.


이번 글에서는 C 컴파일러에서는 정상적으로 컴파일되지만 C++ 컴파일러에서는 오류가 발생하는 대표적인 사례들을 코드 예제와 함께 하나씩 살펴보겠습니다.

1. 함수를 선언하기 전에 호출하는 경우

C++에서는 함수가 선언되기 전에 호출하면 컴파일 오류가 발생합니다. 반면 C 컴파일러는 암시적 함수 선언을 허용하기 때문에 정상적으로 컴파일됩니다.

#include<stdio.h>
int main() {
    myFunction(); // myFunction()이 선언되기 전에 호출됨
}
int myFunction() {
    printf("Hello World");
    return 0;
}

C 출력 결과

Hello World

C++ 출력 결과

[Error] 'myFunction' was not declared in this scope

2. 상수 변수를 일반 포인터로 가리키는 경우

C++에서는 일반 포인터(int*)가 const로 선언된 변수의 주소를 가리킬 수 없습니다. 이는 상수 값을 실수로 변경하지 못하도록 C++이 더 엄격하게 타입을 검사하기 때문입니다. 반면 C에서는 허용됩니다.

#include<stdio.h>
int main() {
    const int x = 10;
    int *ptr;
    ptr = &x;
    printf("The value of x: %d", *ptr);
}

C 출력 결과

The value of x: 10

C++ 출력 결과

[Error] invalid conversion from 'const int*' to 'int*' [-fpermissive]

3. void 포인터를 다른 포인터 타입에 대입하는 경우

C++에서는 void 포인터를 int*, char*와 같은 다른 포인터 타입 변수에 대입할 때 반드시 명시적인 형 변환(type casting)을 해야 합니다. 반면 C에서는 형 변환 없이 자동으로 변환되어 컴파일됩니다.

#include<stdio.h>
int main() {
    void *x;
    int *ptr = x;
    printf("Done");
}

C 출력 결과

Done

C++ 출력 결과

[Error] invalid conversion from 'void*' to 'int*' [-fpermissive]

4. 상수 변수를 초기화하지 않는 경우

C++에서는 const로 선언한 변수를 반드시 선언과 동시에 초기화해야 합니다. 반면 C에서는 초기화하지 않고 선언만 해도 컴파일됩니다. 단, 초기화되지 않은 변수의 값을 읽는 것은 예측 불가능한 결과를 낳을 수 있으므로 주의해야 합니다.

#include<stdio.h>
int main() {
    const int x;
    printf("x: %d", x);
}

C 출력 결과

x: 0

C++ 출력 결과

[Error] uninitialized const 'x' [-fpermissive]

5. 'new'를 변수명으로 사용하는 경우

C에서는 'new'라는 이름의 변수를 자유롭게 사용할 수 있습니다. 하지만 C++에서는 'new'가 동적 메모리 할당에 사용되는 예약 키워드(reserved keyword)이기 때문에 변수명으로 사용할 수 없습니다.

#include<stdio.h>
int main() {
    int new = 10;
    printf("new: %d", new);
}

C 출력 결과

new: 10

C++ 출력 결과

[Error] expected unqualified-id before 'new'
[Error] expected type-specifier before ')' token

6. int 값을 char* 포인터에 대입하는 경우

다음 코드처럼 정수 값을 char* 포인터에 직접 대입하면 C++에서는 컴파일 오류가 발생합니다. 반면 C에서는 문제없이 컴파일되고 실행됩니다.

#include<stdio.h>
int main() {
    char *c = 123;
    printf("c = %u", c);
}

C 출력 결과

c = 123

C++ 출력 결과

[Error] invalid conversion from 'int' to 'char*' [-fpermissive]

7. main()의 반환 타입으로 void를 사용하는 경우

C에서는 main() 함수의 반환 타입으로 void를 사용할 수 있습니다. 하지만 C++ 표준에서는 main()의 반환 타입으로 반드시 int를 사용해야 합니다.

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

C 출력 결과

Hello World

C++ 출력 결과

[Error] '::main' must return 'int'

마무리 정리

지금까지 살펴본 내용을 표로 정리하면 다음과 같습니다.

항목CC++
함수 선언 전 호출허용컴파일 오류
상수 변수를 일반 포인터로 가리키기허용컴파일 오류
void* → 다른 포인터 암시적 변환허용명시적 캐스팅 필요
const 변수 초기화 생략허용컴파일 오류
'new'를 변수명으로 사용허용컴파일 오류 (예약 키워드)
int → char* 대입허용컴파일 오류
void main() 사용허용컴파일 오류 (int 필수)

이처럼 C++은 C에 비해 훨씬 엄격한 타입 검사 규칙을 적용합니다. 따라서 기존 C 코드를 C++ 프로젝트에서 빌드해야 한다면 위와 같은 부분들을 미리 점검하고, 필요에 따라 명시적 형 변환, 함수 원형 선언, const 포인터 사용 등으로 코드를 수정해야 할 수 있습니다.