본문 바로가기

Programmer.cpp/Cplusplus.cpp

C++ 버전별 변천사 #1 - C++98

앞으로 연재하듯 써내려갈 글들은 초보자를 위한 글이 아닙니다. 그렇다고 친절한 메뉴얼 같은 성격의 글도 아닙니다. 다분히 주관적인 입장에서 적는 소개의 글이 될 것이고, 개인적인 견해나 경험담이 주를 이룰것 같습니다.

따라서, 혹시나 C++의 입문자이거나 전혀 익숙치 않은 분들에게 제 글은 오히려 혼란스러울 수도 있다는 점 미리 유의하시기 바랍니다.


하나하나의 항목들을 살펴보기 앞서 이번 포스트 부터, 지금껏 C++에 적용된 (혹은 앞으로 적용될 예정인) 사항들을 각 버전별로 간략히 정리해 보는 내용으로 채워볼까 합니다.


C++98


ISO 표준으로 공식 등록된 첫 버전입니다. 이름 그대로 1998년에 등록되었고, Stroustrup의 저서인 "The C++ Programming Language (이하 TC++PL)" 2판에 소개된 버전이기도 합니다.

첫 표준이니 문법적인 모체가 된 언어 C를 중심으로 추가/변화된 점을 '표면적으로만' 살펴보겠습니다.


class 가 추가되었습니다.

 (C++의 클래스는 설명할 것도 많은지라 C++98 버전의 클래스 정도는 아시는 분들이 읽으시길 바랍니다.)

C++98버전의 class에서는 constructor, destructor, member fuction, friend, user defined data type, virtual function, pure virtual function, pure virtual class, inheritance, multiple inheritance. 대충 이 정도 키워드에 '이게 뭐지?' 라는 정도의 거부감이 없으신 정도면 충분합니다.


C언어에 비해 강력한 type checking이 이루어집니다.

덕분에 C에 익숙한 사람들은 좀 불편을 느끼기도 합니다만, User-defined data type이 많이 사용되는 C++ 입장에서는 당연한 결과이기도 합니다. 하지만, 익숙해지면 오히려 에러도 잘 잡히고, 잠재적인 버그도 많이 걸러주기 때문에 좋은 점이라고 봐야겠죠.


새로운 주석 형식 ( // )이 추가되었습니다.

C에서는 사실 주석 달려면 작정하고 해야할 정도로 살짝 귀찮았었죠.


const 타입이 추가되었습니다. (constant function을 설계할 수 있습니다.)

개인적으로 매우 좋아하는 개선사항입니다. 여러가지 장점이 있는데

- #define 으로 사용하던 상수를 대체하여 literal이 아닌 type을 가진 constant를 사용할 수 있게 되었습니다.

- 함수의 argument로도 사용할 수 있어서, 이 경우 pointer를 함수에 전달할 때 발생할 수 있는 side-effect를 설계과정에서 차단해 줄 수 있게 되었습니다.

- 부가적으로 이미 type이 지정되고, 해당 type으로 value가 존재하기 때문에 상수 사용에 따른 자동 형변환 등의 오버헤드를 줄여줄 수 있습니다.


inline 함수가 추가되었습니다.

이 부분은 전적으로 run-time performance에 관련된 부분이라고 봅니다. 선택적인 사항이기도 합니다만, 간단한 기능의 함수를 아무런 성능상의 부담없이 함수로 분리할 수 있는 여건이 마련된 것이죠.

단, 주의할 점은 inline 함수는 논리적으로 함수를 #include 하듯이 쓰는 녀석인지라 주의할 점이 있습니다.

즉, 너무 큰 함수를 inline으로 설계하거나, inline 함수를 너무 남용해서 공룡같은 함수를 만들어낼 가능성도 존재한다는 겁니다. 특히나 한정적인 메모리를 가진 embedded system에서 (역시나) 한정된 성능의 하드웨어 하에서 성능을 끌어올린답시고 남용하다간 code overflow 라는 신기한 경험을 하게 될 가능성도 있습니다.


default argument가 제공됩니다.

뭐.. 그렇다고 합니다. overloading 할 때 타입 중복 안되게 해주는것만 주의하시면 됩니다.


레퍼런스 타입이 추가되었습니다.

요거 참 유용합니다. 이 덕분에 C++에서도 Call-by-reference가 가능해집니다. 특히나 class로 대변되는 user-defined type을 매개변수로 전달할 때 심각한 암묵적인 형변환이나 복사문제에서 해방될 수 있습니다. 단, 그 장점만큼이나 side effect는 주의해서 사용해야 합니다. 하지만, const 만 잘 활용해도 이런 문제는 거의 해결할 수 있습니다.


함수 overloading이 지원됩니다. (연산자 overloading이 지원됩니다.)

overloading이 뭔지는 아시는 분들이 글을 읽고 계신다고 생각하고, 여튼.. 그게 지원됩니다.

심지어 연산자도 하나의 operator function으로 정의될 수 있기 때문에 overloading 할 수 있습니다.

한 가지 주의할 부분은 연산자를 overloading할 경우 그 우선순위는 원래의 연산자(기본 type에서 쓰이는)가 가지는 우선순위를 그대로 따른다는 점에 유의하셔야 합니다.


extern "C" {} 를 이용하여 C 스타일 코드를 링크할 수 있습니다.

C에 익숙하고 C++가 C를 완전히 포함하고 있다고 '착각' 하시는 분들에게는 이게 도대체 왜 필요한건지 모를 수도 있습니다. 실제로 프로그램 코드가 컴파일 되면 우리가 보고 있는 함수들의 이름은 눈에 보이는 대로의 이름을 가지지 않습니다. 만약, 눈에 보이는 대로의 이름을 가지고 있다면 overloading된 함수들은 이름만으로 구분지을 수 없을테니까요.

예를 들어(실제로는 컴파일러에 따라 다릅니다)

int f( int ); 라는 함수가 있다면

C에서는 _f 라는 이름으로 만들어지고, C++에서는 _f_i_i 와 같이 함수의 return type과 argument type이 포함된 이름으로 만들어집니다. 즉, 번역된 상태(object file이나 library file 내에서 쓰인 상태)의 이름이 다르기 때문에 C언어로 번역된 라이브러리 등을 사용할 때에는 extern "C" 를 해주어야 한다는 겁니다.


template가 지원됩니다.

exception handling이 지원됩니다.

template와 exception handling은 짧게 설명하기 힘든 부분이니 나중에 따로 언급하도록 하겠습니다. 이게 좀 생소하시다면 독한 마음 먹고 따로 공부하셔야 합니다.


C++ 스타일의 입출력 스트림 라이브러리가 제공됩니다.

cout << "Hello, C++" << endl;

이런 비슷한 문장을 보셨다면 그겁니다. 파일도 비슷하게 처리할 수 있습니다. (사실, C에서의 printf도 따지고 보면 console file을 처리하는 것인지라 별 차이는 없어보이네요)


C++ 스타일의 메모리 할당 연산자 new와 delete가 제공됩니다.

C에서 malloc과 free를 쓰던 부분을 대체할 수 있는 연산자입니다. C++답게 type을 기반으로 만들어진 것이라 malloc처럼 일일이 byte 단위로 계산해줘야하는 번거로움은 사라졌습니다. 심지어 이것도 연산자라고 overloading이 가능하기 때문에 활용방법이 많습니다.


대충 이 정도가 C++98이 C와 다른 부분들입니다.

아마도 C++를 처음 접하셨거나, 학교에서 한 학기 수업을 들으셨거나, 학원에서 C++ 과정을 이수하신 분들이라면 대부분 이 C++98 버전을 알고 계실겁니다. 그것도.. template와 exception handling은 모르고 계신 경우가 많으실겁니다. (단지, 교제의 뒷 부분에 등장하는 녀석이라는 이유로.. 물론, 어렵기도 합니다)

만약, 여기 서술된 항목들이 생소하지 않다면 앞으로 제가 써내려갈 글들은 충분히 소화하실 수 있을겁니다. 대부분의 경우 앞으로의 글은 C++98을 알고 있는 분들을 대상으로 쓰도록 하겠습니다. ('대부분'인 이유는 저도 모르게 폭주해서 C++98만 아는 상태로는 이해하기 힘든 글을 적어버릴 수도 있기 때문)


'Programmer.cpp > Cplusplus.cpp' 카테고리의 다른 글

C++ 버전별 변천사 #3 - C++11  (0) 2015.02.01
C++ 버전별 변천사 #2 - C++03  (1) 2015.01.23
C++ 이야기를 시작하면서  (0) 2015.01.18