cheoly's language study blog

C++인데도 사고가 나는 이유는 여전히 같다

C++
반응형
SMALL

C++은 C보다 안전한 언어다.
RAII, 스마트 포인터, 표준 라이브러리.
이론만 보면 사고가 날 이유가 없어 보인다.

그런데 현실은 다르다.

C++ 프로젝트에서도
메모리 문제, 크래시, 알 수 없는 동작은
여전히 반복된다.

이유는 간단하다.
언어는 바뀌었지만
사고방식은 그대로이기 때문이다.


C++ 사고 코드를 보면
대부분 이런 전제를 깔고 시작한다.

“C++이니까 알아서 안전하겠지.”

이 기대가
사고의 출발점이다.


1) 스마트 포인터를 쓰면 안전하다고 믿을 때

C++ 사고의 대표적인 장면이다.

  • shared_ptr 남발
  • 수명 관계를 설명할 수 없음
  • 누가 소유자인지 아무도 모름

스마트 포인터는
메모리를 대신 관리해주지만,
의도를 대신 정해주지는 않는다.

소유권이 불분명한 구조에서는
delete가 사라진 대신
복잡한 버그가 남는다.


2) 객체의 수명을 설계하지 않은 클래스

C++에서 객체는
생성보다 소멸이 중요하다.

  • 생성자는 눈에 띄고
  • 소멸자는 조용히 호출된다

그래서 많은 사고가
소멸 시점에서 발생한다.

  • 이미 해제된 자원 접근
  • 종료 순서에 따른 미묘한 버그
  • 전역 객체 정리 문제

객체의 수명을 설명할 수 없다면
그 클래스는 아직 위험하다.


3) 추상화가 책임을 숨길 때

C++은 추상화가 강력한 언어다.
그래서 사고도 더 교묘해진다.

  • 인터페이스 뒤에 숨은 무거운 동작
  • 이름만 보면 가벼워 보이는 함수
  • 호출 비용이 감춰진 구조

코드가 읽기 쉬워진 대신
실제로 무슨 일이 벌어지는지는
보이지 않게 된다.

사고는
보이지 않는 비용에서 터진다.


4) 예외 처리를 믿고 흐름을 설계할 때

예외는 편리하다.
하지만 예외는 흐름을 숨긴다.

  • 어디서 던졌는지
  • 어디까지 전파되는지
  • 정리 코드는 호출됐는지

이게 명확하지 않으면
예외는 안전장치가 아니라
사고 증폭기가 된다.

C++에서 예외를 쓰는 순간
흐름 설계는 더 엄격해져야 한다.


5) “이건 C 스타일 코드라서”라는 방치

많은 C++ 코드베이스에는
C 스타일 코드가 공존한다.

  • raw pointer
  • 수동 메모리 관리
  • 암묵적 규약

문제는
이 코드가
“어쩔 수 없는 영역”으로 방치된다는 점이다.

C 스타일을 쓴다면
C만큼 엄격해야 한다.
그렇지 않으면
가장 위험한 조합이 된다.


C++ 사고의 본질은
언어의 한계가 아니다.

  • 책임을 명확히 하지 않고
  • 수명을 설계하지 않고
  • 흐름을 숨긴 채 믿어버리는 것

이 습관이
C에서도 사고를 만들고,
C++에서도 그대로 사고를 만든다.

C++은 더 안전해질 수 있는 언어다.
하지만 그 안전성은
작성자의 태도 위에서만 작동한다.

다음 글에서는
이 사고를 줄이기 위해
C++에서 반드시 지켜야 할 기준들을
조금 더 구체적으로 정리해보려 한다.

C와 다른 점,
그리고 여전히 같은 점을 함께.

반응형
LIST