CppCon 2015 - "Stop Teaching C" (Kate Gregory)
시작하기에 앞서
“Stop Teaching C” 토크는 C++ 컨퍼런스인 CppCon에서 Kate Gregory가 발표한 토크의 제목입니다.
C 언어를 쓰지 말라는 의미가 아니라, C++을 가르치는데 C처럼 가르치지 말라는 의미입니다.
C 언어는 좋은 언어입니다. 오해가 없길 바랍니다 ㅎㅎ,,
C->C++ 공부 방법이 만드는 문제
현재 많은 C++ 커리큘럼들이 C를 먼저 공부한 후 C++을 공부하는 방향을 지향합니다.
이는 두 언어가 상당히 비슷해 C를 아는 사람에게 C++을 가르치기 쉽기 때문입니다.
상당수의 현업 C++ 유저들이 C++이 생겨나기 전 C를 먼저 사용하다가 넘어온 경우가 많은데, 본인들이 겪은 공부 과정을 전수하기 위해 이 방법을 사용하기도 합니다.
하지만 이 방법을 채택하면 제대로 된 C++를 공부하는데에 더 오랜 시간이 걸리게 됩니다.
C와 C++에는 극명한 차이가 있습니다.
C에는 RAII, type-safety, template, lambda, exceptions, iterator와 같은 기능이 없습니다.
C로는 Object-oriented design을 공부할 수 없습니다.
C를 먼저 배운 후 C++을 공부하게 되면, 이미 익숙해진 C스타일을 버리고 C++을 새롭게 공부해야합니다.
그럴바에는 Day 1 부터 C++ 스타일을 공부하는게 더 효율적일 겁니다.
C++ 코스 Day 1에 가르쳐서는 안될 것들
아래에 있는 내용들은 ‘C++에서 쓰면 안되는 것들’이 아닙니다.
C++을 공부하는데에 Day 1에 가르치면, 공부하는 사람 입장에서 굉장히 헷갈리게 되는 것들입니다.
대학교에서 C++ 코스를 듣고 ‘와 에반데- C++은 내 길이 아닌가보다’ 하고 생각하게 만드는 것들입니다.
char* string
char*
로 string을 다루기 위해서는 pointer를 이해해야합니다.
기본적인 Hello world까지야 printf()
와 sscanf()
로 어떻게든 됩니다.
하지만 조금만 더 깊게 들어가 string을 다루기 위해서는 1. char array에서 pointer를 이동하는 방법, 2. off-by-one error 이해, 3. null terminator의 대한 개념까지 이해해야합니다.
그 이후에 구현을 위해 여러가지 C에서 제공하는 string 함수들을 외워야합니다 (e.g. strcmp()
).
5분만 들어도 ‘와 쓰읍 C++은 어렵구나’라고 생각하게 만드는 주범 입니다.
해결책
C++ 방식으로 처음부터 가르치면 char*
대신에 <string>
을 사용할 수 있습니다.
<string>
은 char*
에 비해 이해하기 훨씬 쉬우며, Python이나 javascript와 같이 string이 built-in 기능으로 포함되어있는 다른 프로그래밍 언어를 겪은 사람들은 string을 곧바로 이해할 수 있습니다.
1980~년대에 공부하신 분들은 char*로 배우셨을 텐데, 이는 그 당시에 <string>
이라는 기능 자체가 최신 기능처럼 느껴졌을 것 이기 때문입니다. (그리고 2021년 현대에 string은 그냥 어디에든 있는 기본 기능입니다)
<string>
을 사용하면서 C++의 강점인 operator overloading과 strong type을 소개할 수도 있습니다.
1 |
|
printf
변수의 값을 확인하기 위해 printf()
를 가르칩니다.
printf()
를 사용하기 위해서는 format specifier를 다 외워야합니다.
그리고 많은 경우 초보자들은 format specifier로 인해 에러를 경험합니다. (e.g. %c
vs %s
)
오전 10시 반 Day1 C++ 클래스를 들으면서, 초보자들은 벌써 복잡한 에러메세지를 마주하며 본인이 짠 간단한 프로그램의 변수 값도 확인하지 못하게 됩니다.
해결책
Debugger를 써서 코드 한줄한줄 넘어갈 때 변수 값이 어떻게 바뀌는지 보여줍시다.
실제로 출력도 해야하는 경우에는 cout
, cin
, cerr
로 빠르게 결과를 보여줍시다.
stream 방식을 사용할 경우 속도가 좀 느려질 수 있다는 걸 언급만 하고 넘어가도 괜찮습니다.
Day1 이니까요.
[] arrays
char*
와 비슷하게, 초보자에게 array의 기본 기능을 가르치기도 전 부터 포인터 개념을 요구합니다.
기본적으로 address와 reference의 개념을 익혀야하고, 그 후 bounds checking, off-by-one 과 같은 에러에 부닥치며, array를 익히기도 전에 여러가지 개념을 헷갈리기 시작합니다.
심지어 대부분의 [] array를 사용한 예제는 더 쉽게 적을 수 있는 방식이 있음에도 raw for loop 내부에 알고리즘을 직접 구현하는 방식을 씁니다.
예를 들어, “이 array 안에 3이 몇개가 있을까요?”라는 문제를 푸는 코드를 작성할 때, 쉽게 하려면 range-based for loop를 써서 가독성을 높이거나, 또는 std::count
를 쓰면 됩니다. raw for-loop에서 i 값 하나하나 세면서 하지 말구요.
해결책
std::vector
를 쓰면 됩니다.
초심자에게는 std::vector
로 거의 모든 케이스를 커버할 수 있습니다.
기본기를 익히고나서, 성능이 중요하게 될 때 STL에 성능을 개선할 수 있는 다른 형태의 자료구조들이 존재한다고 알려주기만 해도 충분합니다.
하지만 처음부터 iterator를 알려주는건 추천하지 않습니다.