처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.05.26 21
#AI

C에서는 되는데 C++에서는 안 되는 코드들: 두 언어의 미묘한 거리

Hacker News 원문 보기
C에서는 되는데 C++에서는 안 되는 코드들: 두 언어의 미묘한 거리

"C는 C++의 부분집합"이라는 오해

많은 분들이 C와 C++을 거의 같은 언어라고 생각해요. 실제로 "C++은 C에 객체지향을 얹은 것"이라는 설명을 학교에서 들어본 분도 많을 거예요. 그래서 C 코드를 그대로 .cpp 파일로 바꾸면 잘 컴파일될 거라고 기대하기 쉬워요. 그런데 현실은 좀 달라요. 두 언어는 사실 꽤 오래전에 갈라진 형제 같은 사이여서, C에서는 멀쩡히 돌아가는 코드가 C++ 컴파일러에서는 빨간 줄이 잔뜩 그어지는 경우가 생각보다 많거든요.

이번 글은 그런 "C에서는 합법인데 C++에서는 불법"인 구문들을 정리한 내용이에요. 단순히 잡지식이 아니라, 오래된 C 라이브러리를 C++ 프로젝트에 통합하거나, 임베디드 코드를 C++로 마이그레이션할 때 실제로 발목을 잡는 사례들이라 알아두면 쓸모가 있어요.

구체적인 차이들을 하나씩 살펴보기

가장 자주 마주치는 게 void 포인터의 암시적 변환 문제예요. C에서는 mallocvoid를 리턴하면 그걸 intchar든 알아서 변환해줘요. 그래서 int p = malloc(sizeof(int) 10);이 C에서는 그냥 컴파일되거든요. 그런데 C++에서는 안 돼요. 명시적으로 (int)로 캐스팅해줘야 해요. C++이 타입 시스템을 더 엄격하게 다루기 때문인데, 이게 사실은 안전성 면에서는 더 나은 선택이에요. 잘못된 타입 변환으로 인한 버그를 컴파일 시점에 잡아주니까요.

두 번째는 지정 초기화자(designated initializer) 인데, C99부터 들어온 기능이에요. struct Point p = { .x = 1, .y = 2 }; 이런 식으로 멤버 이름을 명시해서 초기화하는 거죠. C에서는 멤버 순서를 마음대로 바꿔도 되고, 일부만 초기화해도 되고, 심지어 배열에 [5] = 10 같은 식으로 특정 인덱스만 지정할 수도 있어요. C++20에 와서야 지정 초기화자가 들어왔는데, 그것도 "선언 순서대로만" 허용하는 등 제약이 더 엄격해요. C에서 자유롭게 쓰던 코드가 C++에서는 reorder 에러를 뱉는 경우가 있어요.

세 번째는 복합 리터럴(compound literal) 이에요. C에서는 myFunction((struct Point){1, 2});처럼 함수 인자 자리에서 임시 구조체를 즉석에서 만들어 넘길 수 있어요. C++에서는 이게 안 돼요. 미리 변수에 담거나 생성자를 호출해야 하죠. 비슷한 효과를 내려면 myFunction(Point{1, 2}); 같은 brace 초기화를 써야 해요.

네 번째로 흥미로운 게 유연한 배열 멤버(flexible array member) 예요. C99에서는 구조체 마지막에 int data[];처럼 크기 없는 배열을 둘 수 있어요. 가변 길이 패킷이나 헤더+페이로드 구조를 표현할 때 정말 편리한 기능이에요. 그런데 C++ 표준에는 이게 없어요. GCC 같은 컴파일러가 확장으로 지원해주긴 하지만, 표준은 아니에요. 그래서 포터블한 C++ 코드를 짜려면 data[1]처럼 더미 크기를 두고 트릭을 써야 해요.

다섯 번째는 함수 포인터 캐스팅과 K&R 스타일 함수 선언. C에서는 int foo();라고 쓰면 "인자 개수가 정해지지 않은 함수"라는 뜻이에요. C++에서는 같은 표기가 "인자가 없는 함수"를 뜻해요. 그래서 옛날 C 코드를 C++로 옮기다 보면 함수 시그니처 해석이 달라져서 미묘한 오류가 나기도 해요. 또 C에서는 enum 값을 정수처럼 자유롭게 쓸 수 있지만, C++에서는 특히 enum class를 쓰면 명시적 캐스팅이 필요해요.

왜 이렇게 갈라졌을까

C++의 설계 철학을 보면 이해가 가요. C++은 "타입 안전성"과 "제로 비용 추상화"를 중요시해요. 그래서 컴파일러가 더 엄격하게 검사하고, 암시적 변환을 줄이고, 정의되지 않은 동작이 적도록 설계됐어요. 반면 C는 "프로그래머를 믿는다"는 철학이 강해요. 위험한 일도 본인 책임 하에 할 수 있게 열어둬요.

C와 C++의 표준 위원회도 분리돼 있어요. WG14가 C, WG21이 C++을 담당하는데, 두 위원회가 서로의 기능을 항상 따라가는 건 아니에요. C99의 지정 초기화자가 C++20에서야 들어온 게 대표적인 예고, 반대로 C++에 있는 템플릿이나 RAII는 C에 없죠.

한국 개발자에게 주는 시사점

실무에서 가장 자주 부딪히는 상황은 레거시 C 라이브러리를 C++ 프로젝트에 통합할 때예요. 임베디드 분야나 게임 엔진, 시스템 프로그래밍 쪽에서 자주 발생해요. 이럴 때는 extern "C"로 감싸서 링킹은 해결하더라도, 헤더에 위에 나온 C 전용 문법이 섞여 있으면 C++ 컴파일러가 헤더를 못 읽거든요. 그래서 호환 헤더를 별도로 만들거나, 매크로로 분기 처리하는 작업이 필요해요.

그리고 "C로 짠 다음 C++로 빌드해도 되겠지"라는 안이한 생각은 위험해요. 정말 두 언어를 다 지원해야 한다면 __cplusplus 매크로로 분기하면서 신중하게 작성해야 하죠. 또 학습 측면에서도, C와 C++을 별개의 언어로 인식하고 각자의 관용구를 따로 익히는 게 장기적으로 더 나아요.

마무리

결론은 "C와 C++은 사촌이지 쌍둥이가 아니다"라는 거예요. 비슷해 보이지만 철학과 디테일이 달라요. 여러분은 C 코드를 C++ 프로젝트에 가져다 쓰면서 가장 곤란했던 호환성 이슈가 뭐였나요?


🔗 출처: Hacker News

이 뉴스가 유용했나요?

이 기술을 직접 배워보세요

AI 도구, 직접 활용해보세요

AI 시대, 코딩으로 수익을 만드는 방법을 배울 수 있습니다.

AI 활용 강의 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.