Search Results for 'C++'

2 POSTS

  1. 2008/04/30 C++0x : 새로운 C++의 문법
  2. 2008/02/04 i++보다 ++i가 더 빠르다? (1)

C++ 창시자. Bjarne Stroustrup 할아버지

C++의 마지막 표준은 1998년도에 제정된 C++98이었습니다. 현재는 C++0x가 제정중입니다. 2008년에 나오면 C++08이 되고, 2009년에 나오면 C++09라고 불리우겠죠. 아무튼, 류광님의 블로그에도 가끔씩 소식이 올라오고, 여기저기서 소식이 들리고 있습니다. 항간에는 2000년대에 안나오고, 2010년대로 넘어간다는 소문도 있습니다. (C++1x 라고.. -_-;)

이번에 바뀌는 부분에 대해선, 정말 마음에 드는 부분들이 많이 있는데, 간단히 몇가지 살펴봤습니다.

#include <vector>
typedef std::vector<std::vector<int> > Table;  // OK
typedef std::vector<std::vector<bool>> Flags;  // error

위에서 >> 에서 에러가 납니다. >> 를 Right Shift 연산자로 인식하기 때문이죠. 에러가 나지 않으려면, >와 >의 사이를 띄워서, > > 라고 해야합니다. 처음 이 현상을 만났을 때에는 정말 헤메었습니다. C++98에서 >>가 되면 Right Shift로 인식하기로 한 것은 여러가지 복합적인 이유가 있다고 합니다. 그럼에도, 이에 대한 수요가 많아져서, C++0x에는 저것도 파싱단계에서 처리를 해주도록 하기로 했다고 합니다.

C++0x에는 Lisp에서 시작되어 수많은 언어들에 영향을 끼친 람다도 추가됩니다.

[](int x, int y) { return x + y }

이에 따라서, for_each를 위해서 별도의 메소드를 만들어야하는 귀찮음은 없어진 것 같습니다. 진작에 이런게 있었어야 해요. ㅠㅠ

std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&total](int x) {
  total += x
});
std::cout << total;

위처럼 해버리면 됩니다. 람다의 경우는 Boost를 통해 이미 사용할 수는 있었지만, 언어 레벨에서 지원해주는 것과, 별도의 라이브러리에서 지원해주는 것은 굉장히 큰 의미가 있습니다. (Perl의 CPAN이나 Ruby의 gems같은 라이브러리를 쉽게 설치 가능한 형태도 아니고요.)

요즘, 프로그래밍 언어들의 춘추전국시대를 맞이하여, 람다나 클로저는 유행이 되어가고 있는 것 같습니다. 자바도 Java 7 에서는 클로저가 추가된다는 소문이 있습니다. :-)

템플릿에 대한 typedef도 있습니다. 아래와 같습니다.

template<typename first, typename second, int third> class SomeType;
template<typename second> using TypedefName = SomeType<OtherType, second, 5>;

네임스페이스 선언에서 사용하던 기존의 using 키워드를 사용합니다.

UTF-8이나 UTF-16과 같은 특정 인코딩의 문자열 리터럴을 지원합니다. 요러코롬 씁니다.

u8"I'm a UTF-8 string."
u"This is a UTF-16 string."
U"This is a UTF-32 string."

정말 너무나도 필요했던 기능입죠. ㅠㅠ

또한, 멀티태스킹을 위한 메모리 모델을 계획하고 있다면서 쓰레드 어쩌구 하는 항목도 있는데, 이건 잘 모르겠네요; -_-a 그리고, C99에서 추가된 64비트 Integer 타입인 long long int 타입을 지원합니다. 사실, g++이나 몇몇 컴파일러는 미리 지원하긴 했었죠.

그리고, sizeof(SomeType::member); 이렇게 생긴 sizeof는 지원하지 않았는데, C++0x에는 추가 된다고 하고요. 튜플(tuple)도 생기고, 정규표현식(regex)도 공식적으로 지원합니다. (Boost::regex랑 GRETA같은 대안이 있긴 했지만요.) 다만, C++에서의 문자열은 큰따옴표로 감싸지는 형태밖에 없기 때문에, 정규식을 쓰려면 좀 불편한데요! C++0x에서는 raw string이라는 형태를 추가함으로써 이를 해결한다고 하네요!! 와우~ GRETA로 정규식 사용할때 그놈의 백스페이스 때문에 X고생 했는데;; (사실, 정규식은 TR1에서 포함되었습니다.)

STL 컨테이너 안에 넣을수도 없었던 auto_ptr 같은거 말고 -_-;; TR1에서 결정된 shared_ptr 라는 좀 제대로 된 스마트 포인터도 제공하고요. 함수를 호출할 때에, 호출부에서는 레퍼런스타입(&)인지 복사생성인지 알기 어려운데요. g( f, ref(i) ) ; 이런 식으로, 레퍼런스를 지정해서 호출할 수도 있다는군요. (사실, 이건 호출부에서 결정하는게 좀 더 타당한 것 같아요!)

그리고 가장 맘에 드는 것.. auto라는 키워드로, 이터레이터의 적당한!! 타입을 담을 수 있게 되었습니다. (당연히 컴파일 타임에 결정될테고요.) 아래와 같던 보기 싫던 문장을..

for (vector<int>::const_iterator itr = myvec.begin(); itr != myvec.end(); ++itr)

아래처럼 깔끔쌈빡하게 표현할 수 있게 되었습니다!

for (auto itr = myvec.begin(); itr != myvec.end(); ++itr)

이 기능은 정말 죽이네요.. ㅠㅠ STL을 두어개만 겹쳐써도, map<string, vector<string> >::iterator iter = hashStr2VecStr.begin()처럼 굉장히 길어져서, 정작 for문의 평가식을 보기 힘들었는데, 정말 좋아졌네요.

자바는 5.0부터 지원했고, Perl, Python, Ruby 등등은 옛날부터 지원하던 향상된 반복문이지만.. C++도 이제 아래와 같은 반복문을 지원합니다.

int my_array[5] = {1, 2, 3, 4, 5};
for(int &x : my_array)
{
  x *= 2;
}

여기서 &x가 아니고 x로 쓰면, 복사생성이 되나보네요;; 어쩔 수 없죠 뭐.. 그 편이 좀 더 의미 전달이 확실하니깐.

비야네 스트로스트럽 할아버지가 작성하신, C++0x 특징을 한데 모은 소스가 있는데요;;

template<class T> using Vec = vector<T,My_alloc<T>>;
Vec<double> v = { 2.3, 1.2, 6.7, 4.5  };
sort(v);
for(auto p = v.begin(); p!=v.end(); ++p)
    cout << *p << endl;

요기 둘쨋줄을 보면.. 허걱. initilize를 리스트를 보내서 할 수 있습니다. -_-)=b 진작 이게 있었어야지!!

음. 여기까지가 이미 알려진 C++0x의 내용중 눈에 띄는 것 몇개 골라봤고요. 그 밖에도 constexpr이라던가, 배열의 선언시에 사이즈에 constexpr의 값은 넣을 수 있다던가(사실 #define으로 구현할 수 있는 부분이긴 합니다.), enum class의 도입이나, 템플릿 alias의 방법이나, STL의 에러 메시지를 훨씬 간결하게 해줄 것 같은 static assertion에 대한 것 등등의 흥미진진한 내용들이 있습니다.

여기 사용된 코드들은 아래와 같은 사이트들에서 참조했습니다.

  1. http://occamsrazr.net/tt/tag/C++0x
  2. http://www.artima.com/cppsource/cpp0x.html (비야네 할아버지 글!)
  3. http://en.wikipedia.org/wiki/C++0x

아래와 같은 TR1(C++0x에 포함될 표준 라이브러리 확장)에 관한 책도 이미 있습니다. (Visual C++ 2008에선 TR1을 설치할 수도 있습니다.)

아아.. 비야네 스트로스트럽 할아버지는 아직 건장하시구나 싶습니다. 드래프트 들어간지 한참 된 것 같은데.. 얼렁 나와만 주세요! 1~2년 안에 나오면, Visual C++ 2012 정도에는 적용 되려나? -_-;; (g++은 야금야금 적용해줄테고!)

어떤분은, "C++은 C++0x가 제정되면서 MMORPG같은 언어가 되어버렸다."라고 하시던데 -_-;; 정말 이건 뭐, 절차지향 언어이면서, 객체지향 언어이면서, 제네릭 프로그래밍도 되면서, 메타프로그래밍도 되었는데, 이젠 그것도 모잘라서 람다도 되고, 이것저것 점점 뭔가 문법 자체가 난잡해지는 것 같습니다. 물론, 이런 편한 기능들이 추가된다는데 반기지 않을수야 없습니다만.. C++은 점점.. 어려운 언어가 되어가는 것 같아 안타깝기도 합니다. 제일 좋아하는 언어인데도, 알면 알수록 점점 어렵다고 느껴지네요.. OTL

-- Jong10

p.s. 틀린 부분 있으면 리플/트랙백 날려주세요. 수정할께요. =_=


Trackback URL : http://www.jong10.com/trackback/246

  1. C++0x : 새로운 C++의 문법

    Tracked from 이름없는 블로그 2008/05/10 20:43 Delete

    좋은 글이여서 퍼왔답니다! http://www.jong10.com/246 C++의 마지막 표준은 1998년도에 제정된 C++98이었습니다. 현재는 C++0x가 제정중입니다. 2008년에 나오면 C++08이 되고, 2009년에 나오면 C++09라고 불리우겠죠. 아무튼, 류광님의 블로그에도 가끔씩 소식이 올라오고, 여기저기서 소식이 들리고 있습니다. 항간에는 2000년대에 안나오고, 2010년대로 넘어간다는 소문도 있습니다. (C++1x 라고.. -_-..

Leave a comment

More Effective C++ C++에서 postfix보다 prefix가 더 빠르다는 말이 있습니다. 결론을 먼저 말하자면, 어떤 경우에는 맞는 말이고 다른 경우에는 그렇지 않습니다. 사실, 이는 MEC++항목 6에서 다루고 있는 주제입니다. 책에 나온 내용 말고는 얻을게 없으므로, 읽어보신 분은 skip하심 되겠습니다. :-)

저는 몇년전에 후위연산자보다 전위연산자가 더 빠르다는 말을 처음 들었을 때에, 도저히 이해하지 못했습니다. 제가 이해하지 못한 이유는, 컴파일된 어셈 코드가 ++i 쪽이 빠르다고 들었기 때문이죠. 지금 생각해보면, 이것은 상당한 오해였습니다. 당시에 Visual C++ 6.0에서 만들어진 어셈코드를 비교하면서, 멋대로 전위 연산자가 더 빠르다고 믿어버렸는데, 사실 어셈코드의 차이는 그것때문이 아니었습니다. 이에 대해 설명하기 시작하면 너무 장황해지므로 생략하고요.. 에, 또, Accelerated C++의 예제들에서도 별 다른 설명 없이 전위연산자를 선호했기 때문에 오해가 증폭된 점도 있었습니다만.

전위연산자든 후위연산자든 증가하려는 i라는 인스턴스가, char, int, double 따위의 내부 타입이라면, 속도는 다르지 않습니다. 실제로 몇몇 컴파일러들에서 컴파일을 하고 디스어셈블을 때려보면, 같은 코드가 나옵니다.

하지만, i가 객체의 인스턴스라면 얘기가 달라집니다. MEC++에 나오는 예제를 사용하겠습니다.

04: class UPInt {
05: public:
06:     UPInt& operator++();
07:     const UPInt operator++(int);
08: };

 

여기에서 참조를 반환하는 6번째 줄의 operator++()가 전위연산자이고, const을 반환하는 7번째 줄의 operator++(int)는 후위연산자입니다. 이 모습을 보면 3가지 의문점이 듭니다.

  1. 왜 후위연산자는 int 타입의 argument가 있는가?
  2. 후위연산자의 리턴타입은 왜 const인가?
  3. 전위연산자의 리턴은 참조인데, 후위연산자는 왜 값인가?

첫번째는, 단순히 함수를 구분하기 위함입니다. -_-; C++에서 호출될 함수를 구분하는 것은, 함수의 이름과 매개변수타입 말고는 없지요. 이거 뭐.. 언어 제약 안에서 힘겹게 저런 이상한 모습을 창조해낸 분들이 참 불쌍하게 느껴집니다.

두번째는, i++++ 같은 모양을 막기 위함입니다. i++의 결과가 참조라면, i++++ 이라고 해도 문법상 틀린 부분이 없습니다. i.operator++(0).operator++(0) 과 같은 말이거든요. C++은 int타입에 대해서 후위 증가 연산자를 두번 쓰는 것을 금하고 있기 때문에, 우리들의 클래스에서도 맞춰주는 쪽이 좋겠지요. 게다가 i++++ 이라고 하더라도, 2가 증가하지 않고 실제로는 1만 증가하게 될 수 있습니다. i++의 결과에서 ++를 하는 것인데, i++의 결과 자체가 일단 i의 값이잖아요.

마지막으로, 가장 중요한 부분입니다. 전위연산자는 참조를 리턴하는데, 후위연산자는 왜 값을 리턴하는가? 이 부분은 C++ 스펙에 공식적으로 설정된 모양새를 봐야합니다.

10: UPInt& UPInt::operator++()
11: {
12:     *this += 1;
13:     return *this;
14: }
15: 
16: const UPInt UPInt::operator++(int)
17: {
18:     const UPInt oldValue = *this;
19:     ++(*this);
20:     return oldValue;
21: }

 

보다시피, 후위연산자는 현재의 값을 리턴한 후에, 증가를 하는 특수한 작동방식으로 인해서, 구현상 내부에서 복사생성(18번줄)을 하게 됩니다. 저 클래스의 생성에 오버헤드가 별로 없다면 모르지만, 클래스의 크기가 커지면 좀 곤란하겠지요. 후위연산자로 ++를 할때마다 복사생성을 할테니깐요!

그래서.. 그래서, i가 클래스의 인스턴스인 경우는, ++i가 i++보다 빠를 수 밖에 없습니다. 정리하자면, 증가하는 인스턴스가,

  • 내부 타입의 경우는, 속도가 같습니다.
  • 객체인 경우는, postfix가 더 빠릅니다.

C++은 보면 볼수록, 땜빵을 수없이 해버린 언어라는 느낌이 들곤 합니다. 일관성이 결여된 부분도 은근히 많고, 좀 지저분하달까요. C++로 코딩을 하다보면 로직을 위한 부분보다는, 언어의 제약을 벗어나기 위한 꽁수가 더 많아지는 것 같기도 합니다. -_-;; 뭐, 그래도.. 템플릿과 STL이 있어서 참 좋지만...

-- Jong10

꼬랑지. ++Jong10 이란 블로그가 있다면, 저보다는 미묘하게 빠르겠군요?! =_=


Trackback URL : http://www.jong10.com/trackback/228

  1. # 기원 2008/02/04 00:52 Delete Reply

    그래서 그냥 ++i 로 통일 하려고
    C++은 자유롭고 지저분하지

Leave a comment


이 블로그 구독하기!!

Recent Posts

  1. 보헤미안 랩소디
  2. 학교 식당 메뉴를 문자로..
  3. C++0x : 새로운 C++의 문법
  4. Load balancing in my life
  5. 나의 첫 Ruby 사용기

Recent Comments

  1. 응. 아침 10시 25분마다 나한.. jong10 05/03
  2. 결국 만들었구나-_-; 신용불량 05/03
  3. 3학년은 원래 그래... 원래 상.. 신용불량 04/23
  4. 그렇게 바쁘다가 갑자기 한꺼.. 기원 04/23
  5. 루비도 gem에 ruby2exe이란게.. jong10 04/16

Recent Trackbacks

  1. C++0x : 새로운 C++의 문법 이름없는 블로그 05/10
  2. 조엘, 중소S/W기업 사장님들에.. Effortless - 上善若水 - 상선.. 02/20
  3. 긴급재난문자정보 - 20일 OO지.. 용희의 블로그 2007
  4. 오 마이 갓! 3분전쯤에 지진;; Thyme; Weblog + [!] 2007
  5. 방금 전에 지진을 느꼈어!!! 에보니.Q 2007

Bookmarks

  1. Channy's Blog
  2. Daum DNA Lens
  3. Game Log
  4. LangDev
  5. likejazz.COM
  6. OpenLook :: 이야기
  7. Sherrad의 여백의美
  8. ▒ 제닉스의 사고뭉치 ▒
  9. 김국현의 낭만 IT
  10. 미친병아리가 삐약삐약
  11. 애자일 이야기
  12. 하루하루
Statistics Graph
Creative Commons License

이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.