C++ 나쁘다.

고백하면 난 C++을 모른다. 잘 모르겠다.


타입은 중요하다. C++에서도 마찬가지다. 특히, 함수 오버로딩이 언어의 핵심 기능 중 하나이고 이것이 타입에 기반하기 때문에 제대로 정의되어 있어야 한다.

'제대로? 그게 뭔데?'

나는 최근까지도 (사실 지금도) C++의 타입이 매우 혼란스러웠다. 문서를 읽어도 읽어도 무슨 말을 하는 건지 와닿지가 않았다. 나는 분명 타입시스템이 궁금해서 검색을 시작했는데 정신을 차려 보면 lvalue, rvalue, xvalue 등등 표현식(expression)에 대한 설명을 읽고 있었다. 왜 그런지 최근에 이유를 안 것 같다.

내가 생각하던 타입은 여러 값들의 요약(abstraction)이었다. 정수들은 int로, 문자열들은 string으로, pointer, union, struct, 모두 프로그램에서 표현하고자 하는 어떤 개념적인 값들의 요약 말이다.

하지만 C++에서의 타입은 그 이상이다. 개념적인 값들 뿐 아니라 표현식도 타입에 영향을 준다. 예를 들어,

int x = 42;
foo(x);

foo(42);

두 함수 호출이 있다고 하자. 두 함수 호출은 같은 결과를 낼까? 아닐 수도 있다. 인자로 주어지는 x42가 모두 동일한 int 타입을 가질 것 같지만, 하나는 lvalue이고 다른 하나는 rvalue이다. 표현식이 다른 것이지만 여기선 그게 타입이니까 그 둘은 타입이 다른 것이다.

void foo(int& x) { ... }

void foo(int&& x) { ... }

만약 두 타입을 구분하는 함수 오버로딩이 있다면 각각 다른 함수를 호출할 것이다.

이걸 왜 이제야 알았을까 싶다. 6년 전 C++ 포스트에서 auto 타입 추론에 수학적인 모델이 있니 없니 이야기했는데 내가 얼마나 뭣도 몰랐는지 알았다. 지금도 상황이 크게 다르지 않다.
blog.kkeun.net/computer/2016-08-01-effective-modern-cpp


깊이 들어가면 들어갈수록 규칙이 제각각이다. 물론 다들 역사적 이유가 있는 것이겠지만. 예를 들면,

en.cppreference.com/w/cpp/language/reference#Forwarding_references

함정이 도처에 있다. C++ 표준 버전마다 의미와 생김새가 달라지는 건 덤이다.


오늘의 결론: C++은 역사다.

오랜 시간 명맥이 이어져 왔고, 시대에 따라 많은 변화가 있었다. 지금 이런 모양을 하고 있는 건 다 이유가 있긴 있다. (아마도?)
그리고 암기 과목이다. 그리고 난 암기 과목 젬병이다.

2022-04-28 씀.