<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>김윤수의 이상계를 꿈꾸며</title>
    <link>https://yesarang.tistory.com/</link>
    <description>이상계는 이쪽에 속해있지 않고 저쪽에 속해 있다. 이쪽에 사는 우리는 이쪽에 머무르지 않고 저쪽을 꿈꾸며 살아야 한다. 여기 오는 모든이들이 저쪽의 충만함을 이쪽에서의 매일의 삶에 경험할 수 있기를...
E-mail: (yesarang) at (yahoo.co.kr)</description>
    <language>ko</language>
    <pubDate>Tue, 14 Apr 2026 20:23:31 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>김윤수</managingEditor>
    <image>
      <title>김윤수의 이상계를 꿈꾸며</title>
      <url>https://t1.daumcdn.net/cfile/tistory/242BB54351DACAEC27</url>
      <link>https://yesarang.tistory.com</link>
    </image>
    <item>
      <title>C++ 최근 소식</title>
      <link>https://yesarang.tistory.com/378</link>
      <description>정말 오랜만의 포스팅입니다.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;몇 가지 최근 C++ 소식 알려 드립니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. C++14 Committee Draft가 벌써 나왔습니다. 다음은&amp;nbsp;PDF파일 다운받을 수 있는 링크입니다.&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://isocpp.org/files/papers/N3690.pdf&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://isocpp.org/files/papers/N3690.pdf&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2. &lt;a href=&quot;http://herbsutter.com/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Herb Sutter&lt;/a&gt;씨가 최근 Microsoft channel 9에서 &quot;The Future of C++&quot;라고 강연한 내용에서도 C++14 feature가 간략하게 소개되고 있네요.&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://channel9.msdn.com/Events/Build/2013/2-306&quot; style=&quot;font-size: 9pt; line-height: 1.5;&quot;&gt;http://channel9.msdn.com/Events/Build/2013/2-306&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3. Clang의 C++14 구현 상황입니다.&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://clang.llvm.org/cxx_status.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://clang.llvm.org/cxx_status.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;4. g++의 C++14 구현 상황입니다.&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://gcc.gnu.org/projects/cxx1y.html&quot;&gt;http://gcc.gnu.org/projects/cxx1y.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;5. Visual Studio C++14 구현 계획입니다. MS는 C++11과 C++14을 한 묶음의 일로 보고 작업 중이라는군요.&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://blogs.msdn.com/b/somasegar/archive/2013/06/28/cpp-conformance-roadmap.aspx&quot;&gt;http://blogs.msdn.com/b/somasegar/archive/2013/06/28/cpp-conformance-roadmap.aspx&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;6. 참고로&amp;nbsp;&lt;a href=&quot;http://isocpp.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow nofollow&quot; style=&quot;font-size: 13px; line-height: 1.38; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; color: rgb(59, 89, 152); cursor: pointer;&quot; class=&quot;tx-link&quot;&gt;http://isocpp.org/&lt;/a&gt;&lt;span style=&quot;font-size: 13px; line-height: 1.38; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 13px; line-height: 1.38; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;&quot;&gt;는 얼마전에 만들어진 C++ 언어 포털이라고 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <category>c++</category>
      <category>C++14</category>
      <category>clang</category>
      <category>g++</category>
      <category>standardization</category>
      <category>visual c++</category>
      <category>Visual Studio</category>
      <category>표준화</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/378</guid>
      <comments>https://yesarang.tistory.com/378#entry378comment</comments>
      <pubDate>Mon, 8 Jul 2013 00:44:26 +0900</pubDate>
    </item>
    <item>
      <title>C++11의 rvalue reference 흉내내기</title>
      <link>https://yesarang.tistory.com/377</link>
      <description>&lt;p&gt;C++11의 큰 특징 중의 하나로 rvalue reference라는 것이 도입되었습니다. reference라는 것이 기본적으로 lvalue로 작동할 수 있는 것인데 rvalue reference라는 개념이라는 게 있을 수가 있나 하는 생각이 들지만, 불필요한 임시객체 생성 및 삭제로 인한 성능 저하를 막기 위해 도입된 것이라 할 수 있습니다. 일명 &lt;a href=&quot;http://thbecker.net/articles/rvalue_references/section_01.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;move semantic과 perfect forwarding을 위한 것&lt;/a&gt;이라고 합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;성능이라는 단어가 나오면 보통 C++ 프로그래머들은 관심을 갖기 마련이고, 그런 좋은 것이 있다면 빨리 쓰고 싶기도 할 터인데요, C++11을 일부 지원하는 기능을 컴파일러가 시장에 나오긴 했더라도 자신이 속한 프로젝트에서는 정책상 C++11 기능을 사용하지 못하게 해 놓을 수도 있을 것입니다. 그렇다고 이 좋은 기능을 그냥 보고 넘어갈 수도 없는 노릇이겠지요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그래서 한 번 생각해 봤습니다. rvalue reference를 흉내낼 수는 없을까하구요. 한 동안 고민하고 있었는데, 어느 순간 갑자기 아이디어가 떠오르더군요. 떠오른 생각을 빠르게 한 번 옮겨 봤습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;using namespace std;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;namespace buffer {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// 테스트용 클래스&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class Foo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;public:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; Foo() {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; ~Foo() {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class BufferRvRef;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class Buffer&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;public:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // 아래 template Move 함수의 일반적 정의를 위한 보조 타입&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; typedef BufferRvRef RvRef;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; Buffer() : buf_(new Foo()), id_(id) {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++id;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // move constructor&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // rvalue reference를 받는 경우를 흉내내서 move semantic&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // 구현&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; Buffer(const RvRef&amp;amp; rvref);&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; ~Buffer() {&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; delete buf_;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;private:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // move semantic 구현. copy construction시 const 객체를&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // 받으므로 const&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;멤버 함수로 정의함&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; Foo* release() const {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Foo* ret = buf_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; buf_ = 0;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // release() 함수에서 buf_ 조작을 위해서 mutable 붙임&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; mutable Foo* buf_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // 화면 출력 메시지에서 각 객체 구분 용도. 실제 클래스라면 불필요&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; int id_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // BufferRvRef가 release()를 호출할 수 있도록 하기 위해&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // friend로 선언&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; friend class BufferRvRef;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; static int id;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int Buffer::id = 0;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// Buffer 내부 데이터를 move 시키기 위한 임시 저장소 역할&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class BufferRvRef&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;public:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // const Buffer 객체를 임시로 저장함&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; explicit BufferRvRef(const Buffer&amp;amp; buf)&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : buf_(buf.release()), id_(id) {&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++id;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; BufferRvRef(const BufferRvRef&amp;amp; other)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : buf_(other.release()), id_(id) {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++id;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // move semantic 구현&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; Foo* release() const {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Foo* ret = buf_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; buf_ = 0;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return ret;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; ~BufferRvRef() {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; delete buf_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;private:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // release() 함수에서 buf_ 조작을 위해 mutable 붙임&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; mutable Foo* buf_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // 화면 출력 메시지에서 각 객체 구분 용도.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;실제 클래스라면 불필요&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; int id_;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; static int id;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;};&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int BufferRvRef::id = 0;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;inline Buffer::Buffer(const Buffer::RvRef&amp;amp; rvref&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;)&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; : buf_(rvref.release()), id_(id) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; - &quot; &amp;lt;&amp;lt; id_ &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; ++id;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// Move() 템플릿 함수가 하는 역할은 T를 T::RvRef로 형변환해주는 역할&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// Buffer 라면 Buffer::RvRef(BufferRvRef형)로 형변환해주므로&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// BufferRvRef(const Buffer&amp;amp;buf)가 호출되면서 Buffer.buf_가&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// BufferRvRef.buf_로 옮겨감&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;template &amp;lt;typename T&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(9, 0, 255); font-family: 'Courier New'; &quot;&gt;typename T::RvRef Move(const T&amp;amp; buf)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(9, 0, 255); font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; starts&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; return typename T::RvRef(buf);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// Buffer를 value로 반환하게 되는 함수는 이전과 다르게&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// Move()를 호출할 경우, move semantic을 구현하는&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// constructor가 호출됨&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer ReturnBuffer()&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; starts&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Move(&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer()&lt;/span&gt;&lt;span style=&quot;color: rgb(9, 0, 255); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int main()&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; starts&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; buffer::Buffer buf(ReturnBuffer());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__ &amp;lt;&amp;lt; &quot; ends&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;위와 비슷한 형태로 작성하면 move semantic을 구현할 수 있을 것 같습니다. 중요한 것은 rvalue reference를 흉내낼수 있는 클래스(FooRvRef)를 각 클래스별(Foo)로 하나 정의하고, Foo --&amp;gt; FooRvRef 변환, FooRvRef --&amp;gt; Foo 변환이 가능하게 하고, 이 변환시 resource를 가져오는 방식으로 구현하면 될 것 같습니다. 물론 value를 반환하는 경우에 일관성있게 Move() 함수를 호출해 줘야만 원하는 변환이 일어날 수 있을 것입니다(ReturnBuffer() 참조). 마지막으로 Move()라는 함수 구현을 쉽게 할 수 있도록 move enable 시키고 싶은 클래스에는 일관성 있게 Foo::RvRef 라는 typedef 를 정의해 줘야합니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;다음은 위 프로그램을 한 번 실행시켜본 결과입니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ ./rvalemul&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int main() starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer::RvRef ReturnBuffer() starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Foo::Foo()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer::Buffer() - 0 constructed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;typename T::RvRef Move(const T&amp;amp;) [with T = buffer::Buffer, typename T::RvRef = buffer::BufferRvRef] starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Foo* buffer::Buffer::release() const - 0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::BufferRvRef::BufferRvRef(const buffer::Buffer&amp;amp;) - 0 move constructed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer::~Buffer() - 0 destroyed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Foo* buffer::BufferRvRef::release() const - 0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer::Buffer(const RvRef&amp;amp;) - 1 move constructed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::BufferRvRef::~BufferRvRef() - 0 destroyed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int main() ends&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Buffer::~Buffer() - 1 destroyed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;buffer::Foo::~Foo()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;위 출력 메시지를 자세히 쫒아가시면 BufferRvRef가 중간에 개입되어 main() 함수에 선언된 buf 객체가 move construction 되고 있는 것을 확인할 수 있습니다.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;추가적으로 알아둘만한 점은 move semantic은 성능을 위해서도 좋지만, 예외 처리를 위해서도 좋다는 점입니다. 왜냐하면 copy construction이 deep copy가 일어난다면 통상 일시적으로 두 개의 copy가 생성되는 셈인데, 그 와중에 exception이 발생할 가능성이 아무래도 커지고, 메모리가 부족할 가능성이 있을 것이니 아무래도 value 반환을 위해서는 move semantic이 훨씬 안전한 방식이라고 생각이 됩니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;마지막으로 한 가지 첨언하면&amp;nbsp;위 Buffer 클래스는 copy constructor를 정의하지 않았으므로 move-only 클래스라고 할 수 있습니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;혹시 C++11 컴파일러를 아직 사용하지 못하시더라도 위와 같은 방식으로 rvalue reference의 유용성을 한 번 느껴보시는 것도 좋을 것 같습니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <category>c++</category>
      <category>c++11</category>
      <category>Emulation</category>
      <category>rvalue reference</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/377</guid>
      <comments>https://yesarang.tistory.com/377#entry377comment</comments>
      <pubDate>Sun, 1 Jul 2012 22:40:36 +0900</pubDate>
    </item>
    <item>
      <title>C++11 atomic 객체 맛보기</title>
      <link>https://yesarang.tistory.com/376</link>
      <description>&lt;p&gt;C++11 atomic을 이용해서 프로그래밍할 때 어떻게 해야 하는지 맛 보기 위해 간단한 예제를 작성해 봤습니다. multiple thread에서 공유 integer 변수를 loop 한번 당 매번 1씩 경쟁적으로 증가시키는 간단한 프로그램입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일반 integer 변수와 atomic integer 변수로 비교해 보았고, 일반 integer 변수의 경우 역시 예상대로 정확한 결과가 나오지 않았고, atomic integer 변수는 정확한 결과가 나왔습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또, 일반 integer 변수는 상당히 빠르게 수행되지만 atomic integer 변수는 상당히 느리다는 것을 확인할 수 있었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;테스트 프로그램은 다음과 같습니다. C++11 프로그램인 만큼 몇 가지 C++11 스타일을 적용했습니다&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;#include &amp;lt;atomic&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;#include &amp;lt;vector&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// C++11&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;lt;thread&amp;gt;가 있으나 버그가 있어 사용하지 못하고&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// boost::thread 사용&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;#include &amp;lt;boost/thread.hpp&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;using namespace std;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;using boost::thread;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;enum {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; NTHREADS = 8, &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// Core i7 Desktop이라 8로 설정&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; NRUN = 10000000,&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; NLOOP = NRUN * 10&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;};&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// atomic integer type. atomic&amp;lt;int&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;라고도 할 수 있음.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// atomic하게 증가됨&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;atomic_int an{0}&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int n{&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;0};&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int id, int nloop)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; id &amp;lt;&amp;lt; &quot;) starts&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; while (nloop-- &amp;gt; 0) {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; // relaxed memory ordering.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 4em; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;// 단순 카운트인 경우에 충분&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; an.fetch_add(1, memory_order_relaxed);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // an.fetch_add(1, memory_order_seq_cst);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // or ++an;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;일반 integer처럼 prefix ++&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;지원&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 4em; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;// 이 때 memory ordering은 memory_order_seq_cst&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (nloop % NRUN == 0)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; id &amp;lt;&amp;lt; &quot;) running...&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; id &amp;lt;&amp;lt; &quot;) exits&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int id, int nloop)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; id &amp;lt;&amp;lt; &quot;) starts&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; while (nloop-- &amp;gt; 0) {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ++n;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (nloop % NRUN == 0)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; id &amp;lt;&amp;lt; &quot;) running...&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; __PRETTY_FUNCTION__&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;&amp;lt; &quot;(&quot; &amp;lt;&amp;lt; id &amp;lt;&amp;lt; &quot;) exits&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void test_func(void (*incr)(int, int), void (*print)())&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; vector&amp;lt;thread&amp;gt; thrs{};&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; &quot;Creating threads&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; for (int i = 0; i &amp;lt; NTHREADS; ++i)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // 개선된 push_back&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;()이라 할 수 있는&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // emplace_back() 활용&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; thrs.emplace&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;_back(thread(incr, i, NLOOP));&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; &quot;Waiting for all threads to terminate&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// lambda 함수 사용&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; for_each(thrs.begin(), thrs.end(), [](thread&amp;amp; thr) {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; thr.join();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; });&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; print();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void usage()&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; &quot;Usage:&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; &quot;test-atomic atomic|int&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int main(int argc, char* argv[])&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; if (argc == 2)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; string type{argv[1]}&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (type == &quot;atomic&quot;)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;/&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;/ lambda 함수 사용&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; test_func(increment_atomic,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;[]() {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; &quot;atomic int = &quot; &amp;lt;&amp;lt; an &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else if (type == &quot;int&quot;)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// lambda 함수 사용&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; test_func(increment_int, &lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;[]() {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cout &amp;lt;&amp;lt; &quot;int = &quot; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; usage();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; else&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; usage();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;컴파일 및 실행 환경은 다음과 같습니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ uname -a&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Linux ubuntu 3.2.0-26-generic #41-Ubuntu SMP Thu Jun 14 17:49:24 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ g++ --version&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;g++-4.6.real (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Copyright (C) 2011 Free Software Foundation, Inc.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;This is free software; see the source for copying conditions. &amp;nbsp;There is NO&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;boost thread와 컴파일할 때는 다음과 같이 library를 명시해 줘야 합니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ g++ --std=c++0x -o test-atomic test_atomic.cpp -lboost_thread-mt&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;실행한 결과는 다음과 같습니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ ./test-atomic&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Usage:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;test-atomic atomic|int&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(255, 0, 0); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ time ./test-atomic atomic&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Creating threads&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(void increment_atomic(int, int)(void increment_atomic(int, int)(void increment_atomic(int, int)void increment_atomic(int, int)((24) starts) starts1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;3) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;0) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(6) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Waiting for all threads to terminate&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(7) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(5) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(6) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(3) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(5) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(0) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(1) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(7) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(2) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(4) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(5) running...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(0) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(7) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(7) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(4) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(4) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(6) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(6) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(1) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(1) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(2) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_atomic(int, int)(2) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(255, 0, 0); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;atomic int = 800000000&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;real&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;0m14.613s&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;user&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;1m40.774s&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;0m0.032s&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(255, 0, 0); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ time ./test-atomic int&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Creating threads&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(1) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(2) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(0) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(3) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(4) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(5) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Waiting for all threads to terminate&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(6) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(7) starts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(4) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(1) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(7) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(2) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(4) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(5) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(6) running...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(3) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(2) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(2) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(0) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(0) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(6) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(3) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(6) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(3) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(3) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(6) running...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void increment_int(int, int)(6) exits&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(255, 0, 0); &quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int = 117287057&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;real&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;0m2.518s&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;user&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;0m16.345s&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-family: 'Courier New'; &quot;&gt;0m0.004s&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;atomic type 을 이용하여 &lt;a href=&quot;http://yinsochen.com/thread-safe-and-or-lockless-data-structures/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;lock-less data structure&lt;/a&gt;를 구현할 수 있다고 하더군요.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description>
      <category>S/W개발/C++11</category>
      <category>atomic types</category>
      <category>c++</category>
      <category>C++0x</category>
      <category>c++11</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/376</guid>
      <comments>https://yesarang.tistory.com/376#entry376comment</comments>
      <pubDate>Sun, 1 Jul 2012 17:29:01 +0900</pubDate>
    </item>
    <item>
      <title>C++11 기능 소개: 중첩 '&amp;gt;' 문제 해결</title>
      <link>https://yesarang.tistory.com/375</link>
      <description>&lt;p&gt;&lt;b id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;여러 말로 설명하기 보다 관련 예제부터 한 번 보겠습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;map&amp;lt;string,vector&amp;lt;int&amp;gt;&amp;gt; heroChronicles;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;C++98에서는 위 코드가 컴파일되지 않습니다. 왜냐하면 “&amp;gt;&amp;gt;”이 연속된 ‘&amp;gt;’으로 인식되는 것이 아니라 구문 분석 시작 전 어휘 분석 단계(lexical analysis)에서 최대 흡수(Maximal munch) 규칙에 따라 &amp;nbsp;“&amp;gt;&amp;gt;” 토큰으로 인식되고 이는 다시 문법 단계에서 “&amp;gt;&amp;gt;” 연산자로 인식되고, &quot;&amp;gt;&amp;gt;&quot; 연산자 좌우로 int, heroChronicles 같은 토큰들이 있는 것으로 인식되기 때문입니다. 템플릿 초심자들이 많이 저지르는 실수이죠. 그래서 C++98에서는 다음과 같이 작성해야 했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size: 12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;map&amp;lt;string,vector&amp;lt;int&amp;gt; &amp;gt; heroChronicles;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;이 뿐 아니라 새로운 형태의 형변환 연산자도 비슷한 문제가 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;static_cast&amp;lt;List&amp;lt;B&amp;gt;&amp;gt;(ld);&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;// static_cast&amp;lt;List&amp;lt;(B&amp;gt;&amp;gt;(ld)); 로 해석&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&amp;gt;&amp;gt;= 및 &amp;gt;= 도 비슷한 문제가 발생할 수 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;void func(List&amp;lt;B&amp;gt;= default_val1);&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;font face=&quot;'Courier New'&quot;&gt;&lt;span style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&amp;nbsp;&amp;nbsp;// 원래 의도는 List&amp;lt;B&amp;gt; lb = default_val1이나&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;font face=&quot;'Courier New'&quot;&gt;&lt;span style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;  // List&amp;lt;(B &amp;gt;= default_val1)); 으로 해석&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;

&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;void func(List&amp;lt;List&amp;lt;B&amp;gt;&amp;gt;= default_val2);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: rgb(0, 0, 0); line-height: normal; &quot;&gt;&lt;font face=&quot;'Courier New'&quot;&gt;&lt;span style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&amp;nbsp;&amp;nbsp;// 원래 의도는 List&amp;lt;List&amp;lt;B&amp;gt;&amp;gt; llb = default_val2이나&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: rgb(0, 0, 0); line-height: normal; &quot;&gt;&lt;font face=&quot;'Courier New'&quot;&gt;&lt;span style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;  // List&amp;lt;List&amp;lt;(B&amp;gt;&amp;gt;= default_val2)); 으로 해석&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;템플릿이 많이 사용되면 많이 사용될 수록 이런 코드는 더 큰 문제가 될 것입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;애초에 C++98에서 이런 문제가 발생했던 것은 컴파일러가 이론적으로 어휘분석, 문법분석, 형식체크와 같이 몇 단계를 거쳐 처리하므로 &lt;/span&gt;&lt;/span&gt;&lt;b id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size: 12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;이 문제를 해결하기 위해서는 어휘 분석 단계가 문법 분석 단계와 협력해야 하는 문제가 발생하게 되기 때문이었습니다. 결국 컴파일러 구현자들을 위한 결정이었던 것이죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그런데 시중에 출시된 C++ 컴파일러들이 이 문제를 인식하고 친철한 에러 메시지를 출력하고 있다는 것이 표준화를 진행하는 동안 밝혀졌습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;예를 들어, g++에서는 다음과 같은 에러 메시지를 출력하고 있었습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;error: ‘&amp;gt;&amp;gt;’ should be ‘&amp;gt; &amp;gt;’ within a nested template argument list&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;이 정도로 이미 컴파일러들이 이 문제를 나름대로 인식하고 해결하고 있었기 때문에 C++11에서는 어휘 분석 단계와 문법 분석 단계가 협력하여 문제를 해결하도록 표준에 명시하기에 이르렀습니다. 기본적으로 다음과 같은 규칙을 따르도록 되어 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;b id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;왼쪽 ‘&amp;lt;’ 이 ‘&amp;gt;’과 서로 매치가 되어 있지 않은 동안에는 &amp;gt;&amp;gt; 토큰은 오른쪽 shift 연산자가 아닌 두 개의 연속된 ‘&amp;gt;’로 인식되어야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;&lt;b id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;위와 같은 규칙은 어휘 분석 단계와 문법 분석 단계가 긴밀하게 협력할 필요 없이 문법 분석 단계에서 간단한 검사만 하면 구현할 수 있을 정도이므로 컴파일러 구현에도 큰 문제가 되지는 않을 것입니다.&lt;/span&gt;&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;항상 그렇듯 이 규칙에도 예외가 있습니다.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;다음 예제를 보시죠.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;Y&amp;lt;X&amp;lt;6&amp;gt;&amp;gt;1&amp;gt;&amp;gt; x4;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;코드를 보고 예측해 보건데 프로그래머는 6&amp;gt;&amp;gt;1의 결과값을 X 템플릿의 인자로 주고 싶었을 것입니다. 즉, 다음과 같은 의미였겠죠.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap; font-family: 'Courier New'; &quot;&gt;Y&amp;lt;X&amp;lt;(6&amp;gt;&amp;gt;1)&amp;gt;&amp;gt; x4;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;이런 코드가 문제 없이 컴파일되도록 하기 위해서는 괄호 안에서는 위와 같은 규칙이 적용되지 않도록 해야하므로 다음과 같이 예외조항을 두어야 할 것입니다.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;b id=&quot;internal-source-marker_0.8047304940409958&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;왼쪽 ‘&amp;lt;’ 이 ‘&amp;gt;’과 서로 매치가 되어 있지 않은 동안에는 &amp;gt;&amp;gt; 토큰은 오른쪽 shift 연산자가 아닌 두 개의 연속된 ‘&amp;gt;’로 인식되어야 한다. 단, 괄호쌍이나 대괄호쌍에 있는 &amp;gt;&amp;gt;는 예외이다.&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;이 규칙이 C++11에서 정하고 있는 것과 정확히 동일합니다. 이제 C++ 초심자들에게 템플릿을 가르칠 때, 중첩 템플릿 인자를 명시할 때는 반드시 한 칸을 띄어야 한다고 설명하면서 &quot;왜 띄어야 하느냐?&quot;라는 질문을 받을까봐 노심초사하는 일은 없어도 될 것 같습니다. ^^;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#000000&quot; face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 15px; line-height: normal; white-space: pre-wrap;&quot;&gt;참고문헌&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;b id=&quot;internal-source-marker_0.10289226262830198&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://occamsrazr.net/tt/172&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(17, 85, 204); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://occamsrazr.net/tt/172&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>S/W개발/C++11</category>
      <category>c++</category>
      <category>C++1</category>
      <category>right angle bracket</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/375</guid>
      <comments>https://yesarang.tistory.com/375#entry375comment</comments>
      <pubDate>Tue, 10 Apr 2012 12:30:00 +0900</pubDate>
    </item>
    <item>
      <title>C++11 기능 소개: 상속생성자(Inheriting Constructor)</title>
      <link>https://yesarang.tistory.com/374</link>
      <description>&lt;p&gt;&lt;b id=&quot;internal-source-marker_0.8169016710016876&quot; style=&quot;color: rgb(0, 0, 0); font-family: AppleGothic; line-height: normal; font-size:12pt; &quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;상속생성자란 기본클래스에 정의된 생성자를 상속받는 클래스에서 상속받을 수 있도록 하는 기능이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;상속생성자는 컴파일러가 기본생성자와 복사생성자를 생성하는 규칙 때문에 발생하는 문제점을 해결하기 위한 기능이므로 우선 이 규칙을 이해할 필요가 있다. C++ 컴파일러는 프로그래머가 생성자를 정의하지 않으면 기본 생성자 및 복사생성자를 알아서 생성한다. 예를 들어, &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int v_;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int get();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void set(int v);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;B b;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;와 같은 코드가 아무런 문제 없이 컴파일되는 이유는 컴파일러가 기본생성자를 생성해 주기 때문이다. 그런데 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;B&lt;/span&gt;를 쓰다 보면 기본생성자에 의해 초기화되지 않은 멤버 변수 값 때문에 문제가 생기는 경우가 있기 마련이다. 예를 들어, &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;void f();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;B b;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;f(b.get());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;와 같은 코드를 실행할 경우 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;b.v_&lt;/span&gt;에 담긴 쓰레기 값 때문에 문제가 발생할 수 있을 것이다. 이런 문제를 발견했을 때 상식있는 프로그래머라면 다음과 같이 생성자를 추가할 것이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int v_;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B(int v) : v_(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int get();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void set(int v);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;B b;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그러면 당장 다음과 같은 에러가 발생하게 된다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;error C2512: 'B' : 사용할 수 있는 적절한 기본 생성자가 없습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그렇다. 프로그래머가 기본생성자가 아닌 생성자를 하나라도 추가하면 컴파일러가 기본생성자를 생성하지 않는 것이다. 이제 프로그래머가 직접 기본생성자를 작성해야 한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int v_;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B() : B(0) {}&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;// C++11의 위임생성자 기능 활용&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B(int v) : v_(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int get();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void set(int v);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그런데 만약 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;B&lt;/span&gt;로부터 상속 받은 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;라는 클래스가 있었다고 생각해 보자.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void compute();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;B::B(int)&lt;/span&gt;가 추가된 이유를 이해하는 프로그래머라면 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;를 사용할 때 다음과 같이 생성시 초기값을 제대로 지정하려고 할 것이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d(10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그렇지만 위 코드는 컴파일 에러를 발생시킨다. 왜냐하면 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;는 애초에 정의되어 있지 않기 때문이다. 결국 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;를 작성한 프로그래머는 다음과 같이 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;를 추가해야 한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;D(int v) : B(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void compute();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d(10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그렇다면 다음 코드는 어떨까? &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d2;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;d2.set(10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;가 없었기 때문에 충분히 여러 차례 사용될만한 코드 패턴일 것이다. 그렇지만 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;를 작성한 프로그래머가 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;를 추가한 순간 위와 같은 코드 패턴들은 모두 컴파일 에러를 일으키게 된다. &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt; 클래스를 작성한 프로그래머와 위 코드를 작성한 프로그래머가 같다면 별 문제 없겠지만 다르다면 사무실 어느 구석에선가 “악~”하고 소리가 날 일이다. 결국 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;는 다음과 같이 작성되어야 한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;D() : B() {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;D(int v) : B(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void compute();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d(10);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d2;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;d2.set(10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;창조적 귀차니즘이 있는 프로그래머라면 이쯤에서 의문이 하나 생긴다. “왜 이렇게 불편하게 해 놓았지? 애초에 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;가 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;B&lt;/span&gt;의 생성자들을 다 물려받으면 되잖아. 상속에는 생성자 상속까지 포함되어야 하는 거 아닌가?”&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;상속생성자는 이런 의문에서 출발한 기능이다. 위 질문에 대한 해답으로 상속시에 생성자를 모두 물려받는 것으로 정하면 되지 않을까 하는 생각이 제일 먼저 들 것이다. 그렇지만 이렇게 상속의 의미를 수정할 경우 기존에 이미 존재하던 수많은 코드들이 컴파일되지 않거나 컴파일은 되는데 예상치 못한 실행시 에러가 발생할 수 있다. 언어가 발전함에 있어 이런 급작스런 변화는 거의 불가능하다고 볼 수 있다. 기존 코드를 모두 깨뜨려버린다면 누구도 새로운 기능들을 채택하려 하지 않을 것이기 때문이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;그렇다면 결국 생성자를 따로 상속받을 수 있는 방법을 고안해 내야 할 것이다. C++11 표준화 논의 중에 여러가지 방법들이 제안되었지만 최종적으로는 다음과 같이 using 선언을 이용하여 &amp;nbsp;생성자를 물려받을 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int v_;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B() : B(0) {}&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;// C++11의 위임생성자 기능 활용&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B(int v) : v_(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int get();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void set(int v);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;using B::B;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void compute();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;위와 같이 정의할 경우, &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;가 암묵적으로 정의되며, 그 의미는 다음과 동일하다고 생각하면 된다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;D(int v) : B(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;...&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;따라서 다음과 같이 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D&lt;/span&gt;를 사용할 수 있게 된다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D d1;&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// 암묵적으로 정의됨&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D d2(10);&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// 상속을 통해 암묵적으로 정의됨&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D d3(d2);&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: 'Courier New'; &quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;// 암묵적으로 정의됨&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;가 “암묵적으로” 정의된다는 것은 기본생성자인 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D()&lt;/span&gt;과 복사생성자인 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(const D&amp;amp;)&lt;/span&gt;가 암묵적으로 정의된다는 의미이다. 왜냐하면 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;를 프로그래머가 명시적으로 정의한 것은 아니기 때문에 기본생성자 및 복사생성자 생성규칙에 따라 암묵적으로 정의된 것이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;이렇게 상속생성자가 동일한 signature를 갖는 생성자를 반복해서 작성해야 하는 수고로움은 덜어 줬지만 잘못하면 다른 문제를 일으킬 수도 있다. 다음 예제를 보자.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int v_;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B() : B(0) {}&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;// C++11의 위임생성자 기능 활용&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;B(int v) : v_(v) {}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;int get();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void set(int v);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;float v2_;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; &quot;&gt;	&lt;/span&gt;// 초기화 필요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;using B::B;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void compute();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d3(25);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;언뜻 보기에는 문제가 없어 보일 수 있으나 컴파일러가 생성한 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;는 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;B::B(int)&lt;/span&gt;를 뜻하므로 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;d3.v2_&lt;/span&gt;는 초기화되지 않은 채로 사용될 것이다. 이쯤에서 우리는 다음과 같은 프로그래밍 경구를 기억할 수 밖에 없다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;“초기화되지 않은 변수를 사용하지 말라”&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;구식 방법으로 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;D::D(int)&lt;/span&gt;를 직접 작성하여 초기화할 수도 있지만, C++11에 새롭게 추가된 멤버초기화 기능을 이용하여 더 멋지게 해결할 수도 있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;class D : public B {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;float v2_{0.0};&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 멤버초기화 기능 이용&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;public:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;using B::B;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &amp;nbsp;void compute();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;D d3(25);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// v2_는 0.0으로 초기화 됨&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 15px; font-family: 'Courier New'; background-color: transparent; font-weight: normal; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;참고문헌&lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1890.pdf&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1890.pdf&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1898.pdf&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1898.pdf&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1583.pdf&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(17, 85, 204); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1583.pdf&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www2.research.att.com/~bs/C++0xFAQ.html#inheriting&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(17, 85, 204); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://www2.research.att.com/~bs/C++0xFAQ.html#inheriting&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://occamsrazr.net/tt/205&quot;&gt;&lt;span style=&quot;font-size: 15px; font-family: Arial; color: rgb(17, 85, 204); background-color: transparent; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;http://occamsrazr.net/tt/205&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>S/W개발/C++11</category>
      <category>C++11 C++ 초기화 생성자 상속생성자</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/374</guid>
      <comments>https://yesarang.tistory.com/374#entry374comment</comments>
      <pubDate>Wed, 28 Mar 2012 22:51:13 +0900</pubDate>
    </item>
    <item>
      <title>C++ 이야기: 예외 처리와 관련된 고전 글 번역</title>
      <link>https://yesarang.tistory.com/372</link>
      <description>&lt;meta charset=&quot;utf-8&quot;&gt;&lt;div&gt;
다음 글은 예외 처리 기능이 C++에 도입된지 얼마되지 않아 C++ 커뮤니티에서 예외를 사용할 때 유의해야할 점에 대해 잘 깨닫지 못하고 있을 때, 예외에 대한 새로운 통찰력을 제공해 주고, 예외 처리를 위한 다양한 기법들의 시발점이 된 고전 Tom Cargill 의 Exception handling: a false sense of security 를 번역한 것입니다. 원문은 이 &lt;a href=&quot;http://ptgmedia.pearsoncmg.com/images/020163371x/supplements/Exception_Handling_Article.html&quot; target=&quot;_blank&quot; title=&quot;[http://ptgmedia.pearsoncmg.com/images/020163371x/supplements/Exception_Handling_Article.html]로 이동합니다.&quot;&gt;링크&lt;/a&gt;에서 보실 수 있고, 원문에서 약간 코드 상 잘못된 부분들(template 키워드 뒤에 &amp;lt;class T&amp;gt;가 따라오지 않는다던지 literal string 이 &quot;&quot;...&quot;&quot; 과 같이 되어 있다던지)을 수정하고 영문과 한글을 대조하면서 보실 수 있도록 했습니다. C++ 로 프로그래밍 하시는 분이라면 필독해야 할 글이라고 할 수 있습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그렇지만 이 글만 읽지 마시고, &lt;a href=&quot;http://yesarang.tistory.com/368&quot; target=&quot;_blank&quot;&gt;2009/09/25 - [S/W개발/C++ 이야기] - C++ 이야기 서른한번째: 왜 예외를 쓰는 게 좋을까요?&lt;/a&gt;&amp;nbsp;와 비교해서 읽어 보시면 예외의 장점과 단점을 어느 정도 파악하실 수 있을 거라 생각합니다. 이 글만 읽으시면 마치 예외가 문제를 더 많이 일으키는 것 같지만, 이 글이 문제점을 제기한 이후에 많은 분들이 예외 안전성을 확보할 수 있는 프로그래밍 기법들을 알아내어 그 방법대로 프로그래밍하면 별 문제 될것이 없습니다. 다만, 이런 프로그래밍 기법을 공부하는데 어느 정도 시간이 필요한 것이 더 문제겠지요. 또 이 글만 읽고 예외는 절대 쓰면 안된다는 결론에 빠지지 않기를 바랍니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;font-size: 12pt; &quot;&gt;&lt;b&gt;EXCEPTION HANDLING:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;font-size: 12pt; &quot;&gt;&lt;b&gt;A FALSE SENSE OF SECURITY&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;font-size: 12pt; &quot;&gt;&lt;b&gt;예외 처리: 잘못된 안정감&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
Tom Cargill 저&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
김윤수 역&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
This article first appeared in C++ Report, Volume 6, Number 9, November-December 1994.&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
이 글은 C++ Report, 6권, 1994년 11월, 12월, 9번째판에 처음 게제됐습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
I suspect that most members of the C++ community vastly underestimate the skills needed to program with exceptions and therefore underestimate the true costs of their use. The popular belief is that exceptions provide a straightforward mechanism for adding reliable error handling to our programs. On the contrary, I see exceptions as a mechanism that may cause more ills than it cures. Without extraordinary care, the addition of exceptions to most software is likely to diminish overall reliability and impede the software development process.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
저는 C++ 사용자 대부분이 예외를 사용하는 프로그램을 작성하는 데 필요한 노련미를 너무 무시하고 있지 않는지, 그럼으로 인해 예외를 사용할 때, 진정 치뤄야할 대가를 무시하고 있지는 않은지 염려스럽습니다. 오히려 대부분은 예외를 사용하면 바로 신뢰성 있는 에러 처리가 가능하다고 믿는 것 같습니다. 저는, 이와는 반대로, 예외를 사용하면 해결되는 문제보다는 새롭게 발생하는 문제가 많다고 생각합니다. 정말 정말 조심하지 않고 예외를 사용하면, 소프트웨어의 전반적인 신뢰성이 훼손되고 소프트웨어 개발 과정이 지연될 가능성이 높아집니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
This &quot;extraordinary care&quot; demanded by exceptions originates in the subtle interactions among language features that can arise in exception handling. Counter-intuitively, the hard part of coding exceptions is not the explicit throws and catches. The really hard part of using exceptions is to write all the intervening code in such a way that an arbitrary exception can propagate from its throw site to its handler, arriving safely and without damaging other parts of the program along the way.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이렇게 정말 정말 조심해야 하는 이유는 예외 처리 과정에서 발생하는 언어의 다양한 특징들간 미묘한 상호 작용때문입니다. 언뜻 보기와는 달리 예외를 사용하여 코딩할 때, 가장 어려운 부분은 눈에 보이는 throw와 catch가 아닙니다. 정말 어려운 부분은 어떤 예외라도 발생 지점으로부터 처리 지점까지 프로그램 상태를 해치지 않고 안전하게 도달할 수 있도록 코딩하는 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
In the October 1993 issue of the C++ Report, David Reed argues in favor of exceptions that: &quot;Robust reusable types require a robust error handling mechanism that can be used in a consistent way across different reusable class libraries.&quot; While entirely in favor of robust error handling, I have serious doubts that exceptions will engender software that is any more robust than that achieved by other means. I am concerned that exceptions will lull programmers into a false sense of security, believing that their code is handling errors when in reality the exceptions are actually compounding errors and hindering the software.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
C++ Report 1993년 10월판에서 David Reed는 &quot;강인한 재사용 형식은 여러 클래스 라이브러리에 걸쳐 일관되게 사용할 수 있는 강인한 오류 처리 방법을 필요로 한다&quot;며 예외를 옹호하는 주장을 했습니다. 강인한 오류 처리가 필요하다는 건 십분 동의하지만, 다른 에러 처리 방법에 비해 예외가 더 강인한 소프트웨어를 만들게 한다는 건 정말 동의하기 어렵습니다. 오히려 프로그래머들이 예외를 사용하면서 내 프로그램은 오류 처리를 하고 있으니 안전할꺼야라며 안심하게 될까봐 걱정스럽습니다. 실제로는 예외가 오류를 더 복잡하게 하고, 소프트웨어 동작을 방해하게 됩니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
To illustrate my concerns concretely I will examine the code that appeared in Reed's article. The code (page 42, October 1993) is a Stack class template. To reduce the size of Reed's code for presentation purposes, I have made two changes. First, instead of throwing Exception objects, my version simply throws literal character strings. The detailed encoding of the exception object is irrelevant for my purposes, because we will see no extraction of information from an exception object. Second, to avoid having to break long lines of source text, I have abbreviated the identifier current_index to top. Reed's code follows. Spend a few minutes studying it before reading on. Pay particular attention to its exception handling. [Hint: Look for any of the classic problems associated with delete, such as too few delete operations, too many delete operations or access to memory after its delete.]&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
제가 걱정하는 바를 구체적으로 설명하기 위해 Reed의 글에 있는 코드를 한 번 살펴 보겠습니다. 1993년 10월판 42페이지에 제시된 코드는 Stack 클래스 템플릿입니다. 설명을 위해 Reed의 코드를 줄일 필요가 있어서 두 가지를 수정했습니다. 첫 번째로 Exception 객체를 던지지 않고, 그냥 문자열을 던집니다. 어차피 예외 객체러부터 어떤 정보도 꺼내지 않을 것이므로 예외 객체를 어떻게 부호화하는지는 제 논의와 별 상관이 없습니다. 두 번째로 긴 소스 줄을 끊어야 하는 불편을 피하기 위해 current_index 식별자를 top이라고 줄였습니다. 다음은 Reed의 코드입니다. 계속 읽기 전에 한 번 몇 분간 깊이 분석해 보시기 바랍니다. 특히 예외 처리에 주목해 보시기 바랍니다. [힌트: delete 연산을 필요한 만큼 호출하지 않는다던지, 필요보다 더 많이 호출한다던지, delete 한 후에 메모리를 사용한다던지하는 delete와 관련된 고전적인 문제를 찾아 보시기 바랍니다.]&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class Stack&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;unsigned nelems;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;int top;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;T* v;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;public:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;unsigned count();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;void push(T);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;T pop();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
&amp;nbsp;&amp;nbsp;Stack();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;~Stack();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;Stack(const Stack&amp;amp;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;Stack&amp;amp; operator=(const Stack&amp;amp;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;};&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack::Stack()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;top = -1;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v = new T[nelems=10];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( v == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack::Stack(const Stack&amp;amp; s)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v = new T[nelems = s.nelems];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( v == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( s.top &amp;gt; -1 ){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for(top = 0; top &amp;lt;= s.top; top++)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;v[top] = s.v[top];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;top--;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack::~Stack()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;delete [] v;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void Stack::push(T element)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;top++;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( top == nelems-1 ){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;T* new_buffer = new T[nelems+=10];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if( new_buffer == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for(int i = 0; i &amp;lt; top; i++)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;new_buffer[i] = v[i];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;delete [] v;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;v = new_buffer;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v[top] = element;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;T Stack::pop()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( top &amp;lt; 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;pop on empty stack&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;return v[top--];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;unsigned Stack::count()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;return top+1;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack&amp;amp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack::operator=(const Stack&amp;amp; s)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;delete [] v;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v = new T[nelems=s.nelems];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( v == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( s.top &amp;gt; -1 ){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for(top = 0; top &amp;lt;= s.top; top++)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;v[top] = s.v[top];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;top--;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;return *this;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
My examination of the code is in three phases. First, I study the code's behavior along its &quot;normal,&quot; exception-free execution paths, those in which no exceptions are thrown. Second, I study the consequences of exceptions thrown explicitly by the member functions of Stack. Third, I study the consequences of exceptions thrown by the T objects that are manipulated by Stack. Of these three phases, it is unquestionably the third that involves the most demanding analysis.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
저는 세 단계로 이 코드를 분석해 보려고 합니다. 우선, 정상적인, 즉, 예외가 없는 실행 경로를 따로 코드가 잘 동작하는지 분석할 것입니다. 그 다음에는 Stack의 멤버 함수가 예외를 던질 때 어떻게 되는지 분석할 것입니다. 마지막으로 Stack이 처리하는 T 객체가 예외를 던질 때 어떻게 되는지 분석할 것입니다. 당연히 이 세 단계 중 마지막 단계를 가장 철저히 분석해야겠지요.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: 10pt; &quot;&gt;Normal Execution Paths / 정상적 실행 경로&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Consider the following code, which uses assignment to make a copy of an empty stack:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
다음 코드는 비어 있는 스택 복사본을 만들기 위해 할당을 사용하고 있습니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack y;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack x = y;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;assert( y.count() == 0 );&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;printf( &quot;%u\n&quot;, x.count() );&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
17736&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The object x should be made empty, since it is copied from an empty master. However, x is not empty according to x.count(); the value 17736 appears because x.topis not set by the copy constructor when copying an empty object. The test that suppresses the copy loop for an empty object also suppresses the setting of top. The value that top assumes is determined by the contents of its memory as left by the last occupant.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
x는 비어 있는 원본에서 복사됐으니 당연히 비어 있어야 함에도 불구하고 x.count() 결과로 보면 비어 있질 않습니다; 빈 객체를 복사할 때 복사 생성자가 x.top을 설정하지 않기 때문에 17736이라는 값이 출력된 것입니다. 빈 객체에 대해서 복사 루프를 돌지 않게 하는 조건문 때문에 top 변수도 설정되지 않게 됩니다. top 변수의 값은 마지막으로 해당 메모리를 사용했던 객체가 남겨 놓은 값이겠지요.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Now consider a similar situation with respect to assignment:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
할당과 관련된 비슷한 경우을 하나 더 생각해 보겠습니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack a, b;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;a.push(0);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;a = b;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;printf( &quot;&quot;%u\n&quot;&quot;, a.count() );&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Again, the object a should be empty. Again, it isn't. The boundary condition fault seen in the copy constructor also appears in operator=, so the value of a.top is not set to the value of b.top. There is a second bug in operator=. It does nothing to protect itself against self-assignment, that is, where the left-hand and right-hand sides of the assignment are the same object. Such an assignment would cause operator= to attempt to access deleted memory, with undefined results.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
여기에서도 객체 a는 비어 있어야 하지만 그렇지 않습니다. 경계 조건을 잘못 처리했던 복사 생성자의 결함이 operator=에도 있기 때문에 a.top 변수값이 b.top 변수값으로 설정되지 않습니다. operator=에는 버그가 또 하나 있습니다. 바로 자기 할당-좌변 객체와 우변 객체가 동일한 경우를 말함-을 별도로 처리하지 않고 있습니다. 자기 할당시에는 operator=가 delete된 메모리를 접근하게 되고, 그렇게 되면 예상치 못한 결과가 초래될 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: 10pt; &quot;&gt;Exceptions Thrown by Stack / Stack 이 던지는 예외&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
There are five explicit throw sites in Stack: four report memory exhaustion from operator new, and one reports stack underflow on a pop operation. (Stack assumes that on memory exhaustion operator new returns a null pointer. However, some implementations of operator new throw an exception instead. I will probably address exceptions thrown by operator new in a later column.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Stack은 다섯 군데에서 예외를 발생시키고 있습니다. 그 중 넷은 new 연산자가 메모리 고갈을 알려준 것을 보고하는 것이고, 나머지 하나는 pop 연산을 수행할 때 언더플로가 발생했다는 것을 보고하는 것입니다.(Stack 은 new 연산자가 메모리 고갈시 널 포인터를 리턴하는 것으로 가정하고 있습니다. 그렇지만 일부 컴파일러에서는 new 연산자가 예외를 던지는 방식으로 작동합니다. 나중에 쓰게 될 칼럼에서 new 연산자가 예외를 던지는 문제를 다뤄 보겠습니다.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The throw expressions in the default constructor and copy constructor of Stack are benign, by and large. When either of these constructors throws an exception, no Stack object remains and there is little left to say. (The little that does remain is sufficiently subtle that I will defer it to a later column as well.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Stack의 기본 생성자와 복사 생성자가 던지는 예외는 대체로 별 문제가 없습니다. 이 두 생성자에서 예외가 발생하면 어차피 Stack 객체가 남아 있질 않게 되니 할 말이 거의 없습니다.(아주 조금 할 얘기가 있습니다만 이것도 다음 칼럼에서 얘기하도록 하겠습니다.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The throw from push is more interesting. Clearly, a Stack object that throws from a push operation has rejected the pushed value. However, when rejecting the operation, in what state should push leave its object? On push failure, this stack class takes its object into an inconsistent state, because the increment of top precedes a check to see that any necessary growth can be accomplished. The stack object is in an inconsistent state because the value of top indicates the presence of an element for which there is no corresponding entry in the allocated array.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
push 연산이 던지는 예외는 좀 더 흥미롭습니다. push 연산 실행 도중 예외가 발생하면 Stack 객체는 push된 값을 저장하지 않습니다. 그럴 경우 push 완료 후Stack 객체가 어떤 상태가 될까요? push가 실패하면 Stack 객체 상태가 불일치하게 됩니다. 왜냐하면 메모리 공간을 확실히 확보했는지 확인하기 전에 미리 top을 증가시켜 버리기 때문입니다. 예외가 발생하면 top 변수값이 실제로는 있지도 않은 객체를 가리키게 되므로 서로 불일치하게 됩니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Of course, the stack class might be documented to indicate that a throw from its push leaves the object in a state in which further member functions (count, push and pop) can no longer be used. However, it is simpler to correct the code. The push member function could be modified so that if an exception is thrown, the object is left in the state that it occupied before the push was attempted. Exceptions do not provide a rationale for an object to enter an inconsistent state, thus requiring clients to know which member functions may be called.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
물론 Stack 클래스 문서에 push 도중 예외가 발생하면 더 이상 다른 멤버 함수들(count, push 및 pop 등)을 사용할 수 없다고 기술할 수도 있겠지만, 그러느니 코드를 고치는 게 훨씬 간단할 것입니다. push 안에서 예외가 발생하더라도 객체 상태를 push 호출 전 상태에 머무르도록 push 멤버 함수를 수정할 수 있을 것입니다. 예외가 발생했다고 하여 불일치 상태가 되어서는 안될 것입니다. 그렇게 하면, Stack 사용자가 예외 발생 후에 일일이 어떤 멤버 함수를 호출할 수 있는지를알아야 하니까요.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
A similar problem arises in operator=, which disposes of the original array before successfully allocating a new one. If x and y are Stack objects and x=y throws the out-of-memory exception from x.operator=, the state of x is inconsistent. The value returned by x.count() does not reflect the number of elements that can be popped off the stack because the array of stacked elements no longer exists.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
operator=에도 비슷한 문제가 있습니다. 즉, 새로운 배열을 성공적으로 할당하기 전에 원래 배열을 반납해 버리고 있습니다. x와 y가 Stack 객체이고, x=y 수행 도중 메모리가 고갈되었다는 예외가 발생했다면 x의 상태는 불일치하게 됩니다. 스택에 저장된 객체 배열이 더 이상 존재하지 않으므로 x.count() 가 돌려주는 값은 실제 스택에서 꺼낼 수 있는 객체 개수를 정확히 반영하지 못하게 됩니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: 10pt; &quot;&gt;Exceptions Thrown by T / T가 던지는 예외&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The member functions of Stack create and copy arbitrary T objects. If T is a built-in type, such as int or double, then operations that copy T objects do not throw exceptions. However, if T is another class type there is no such guarantee. The default constructor, copy constructor and assignment operator of T may throw exceptions just as the corresponding members of Stack do. Even if our program contains no other classes, client code might instantiate Stack&amp;lt;Stack&amp;lt;int&amp;gt; &amp;gt;. We must therefore analyze the effect of an operation on a T object that throws an exception when called from a member function of Stack.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Stack 멤버 함수들은 T 객체를 생성하기도 하고 복사하기도 하고 있습니다. T 가 int나 double과 같은 내장 형식이라면 T 객체를 복사하는 동안 예외가 발생할 리가 없습니다. 그렇지만 T가 클래스 형식이라면 얘기가 달라집니다. T의 기본 생성자, 복사 생성자, 할당 연산자 모두가 Stack과 마찬가지로 예외를 발생시킬 수 있습니다. 우리 프로그램안에 다른 클래스를 정의하지 않았다 하더라도 Stack을 사용하는 코드가 적어도 Stack&amp;lt;Stack&amp;lt;int&amp;gt; &amp;gt;를 생성할 수도 있는 노릇입니다. 그러니 Stack 멤버 함수에서 활용하는 T 객체 연산이 예외를 발생시킬 때, 어떤 일이 벌어질지 분석해 보아야만 하겠지요.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The behavior of Stack should be &quot;exception neutral&quot; with respect to T. The Stack class must let exceptions propagate correctly through its member functions without causing a failure of Stack. This is much easier said than done.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Stack은 T 객체에 대해 &quot;예외 중립적(exception-neutral)&quot;이어야 합니다. 즉, Stack 클래스는 T 객체에서 발생한 예외가 자신을 망가뜨리지 않으면서 멤버함수들을 통과하도록 해야 한다는 것입니다. 이게 정말 말처럼 쉬운 것은 아닙니다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Consider an exception thrown by the assignment operation in the for loop of the copy constructor:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
복사 생성자에 있는 for 루프에서 할당 연산이 예외를 던지를 경우를 살펴 보겠습니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack::Stack(const Stack&amp;amp; s)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v = new T[nelems = s.nelems]; // leak&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( v == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( s.top &amp;gt; -1 ){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for(top = 0; top &amp;lt;= s.top; top++)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;v[top] = s.v[top]; // throw&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;top--;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Since the copy constructor does not catch it, the exception propagates to the context in which the Stack object is being created. Because the exception came from a constructor, the creating context assumes that no object has been constructed. The destructor for Stack does not execute. Therefore, no attempt is made to delete the array of T objects allocated by the copy constructor. This array has leaked. The memory can never be recovered. Perhaps some programs can tolerate limited memory leaks. Many others cannot. A long-lived system, one that catches and successfully recovers from this exception, may eventually be throttled by the memory leaked in the copy constructor.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
복사 생성자가 예외를 잡지 않고 있으므로 Stack 객체를 생성하려고 했던 문맥까지 예외가 전파됩니다. 예외가 생성자 내부에서 시작됐으므로 객체가 아예 생성되지 않은 것이므로 소멸자도 호출되지 않게 됩니다. 그러니 복사 생성자가 할당했던 T 객체 배열을 삭제하지 않게 되고, 결국 해당 배열은 줄줄 세게 됩니다. 해당 메모리를 회복할 수 없습니다. 몇 몇 프로그램은 어느 정도 메모리 누수를 견딜 수 있겠지만 많은 프로그램들이 그럴 수 없습니다. 오랫 동안 실행되어야 하는 시스템은 이런 예외를 잡아서 정상 상태를 회복하면서 계속 실행하려고 노력할 것이고, 복사 생성자에서 발생한 메모리 누수로 인해 결국 메모리 부족으로 허덕이게 될 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
A second memory leak can be found in push. An exception thrown from the assignment of T in the for loop in push propagates out of the function, thereby leaking the newly allocated array, to which only new_buffer. points:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
push에서도 메모리 누수가 발생합니다. push 안에 for 루프에서 T 할당시 예외가 발생하면 함수를 빠져 나가면서 new_buffer 가 가리키는 새 배열을 놓치게 됩니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void Stack::push(T element)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;top++;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( top == nelems-1 ){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;T* new_buffer = new T[nelems+=10]; // leak&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if( new_buffer == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for(int i = 0; i &amp;lt; top; i++)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;new_buffer[i] = v[i]; // throw&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;delete [] v;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;v = new_buffer;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v[top] = element;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The next operation on T we examine is the copy construction of the T object returned from pop:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
다음으로 pop 에서 T 객체를 되돌려 줄 때 호출되는 T 객체 복사 생성자를 살펴 보겠습니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;T Stack::pop()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( top &amp;lt; 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;pop on empty stack&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;return v[top--]; // throw&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
What happens if the copy construction of this object throws an exception? The pop operation fails because the object at the top of the stack cannot be copied (not because the stack is empty). Clearly, the caller does not receive a T object. But what should happen to the state of the stack object on which a pop operation fails in this way? A simple policy would be that if an operation on a stack throws an exception, the state of the stack is unchanged. A caller that removes the exception's cause can then repeat the pop operation, perhaps successfully.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
T 객체 복사 생성자가 예외를 던지면 무슨 일이 벌어질까요? 스택 꼭대기에 있는 객체가 복사될 수 없으니 pop 연산이 실패할 것입니다. 호출자는 당연히 T 객체를 못 받겠지요. pop 연산이 실패한 스택 객체의 상태는 어떻게 되어야 할까요? 스택 객체에 어떤 연산을 수행하더라도 예외가 발생한 경우, 스택 상태가 바뀌지 않아야 한다는 단순한 정책을 따를 수 있을 것입니다. 이렇게 정해 놓으면 호출자는 예외 원인을 제거하고 다시 pop 연산을 다시 호출할 수 있을 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
However, pop does change the state of the stack when the copy construction of its result fails. The post-decrement of top appears in an argument expression to the copy constructor for T. Argument expressions are fully evaluated before their function is called. So top is decremented before the copy construction. It is therefore impossible for a caller to recover from this exception and repeat the pop operation to retrieve that element off the stack.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그렇지만, Stack의 pop은 되돌려 줄 값을 복사 생성할 때 실패하더라도 스택 상태를 바꿔 놓아 버립니다. v[top--] 수식이 T 복사 생성자의 인자로 들어갈텐데 이 수식이 완전히 평가된 후에 복사 생성자가 호출되므로 top 값이 감소된 후에 복사 생성자가 호출됩니다. 그러므로 호출자가 복사 생성자에서 발생한 예외로부터 회복하여 pop 연산을 반복하더라도 스택에서 마지막에 꺼내려던 그 객체를 꺼낼 수는없습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Finally, consider an exception thrown by the default constructor for T during the creation of the dynamic array of T in operator=:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
마지막으로 operator=에서 T 배열을 생성할 때 호출되는 기본 생성자가 예외를 발생시키는 경우를 살펴 보겠습니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;template &amp;lt;class T&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack&amp;amp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Stack::operator=(const Stack&amp;amp; s)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;delete [] v; &amp;nbsp;// v undefined&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;v = new T[nelems=s.nelems]; // throw&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( v == 0 )&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;throw &quot;out of memory&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;if( s.top &amp;gt; -1 ){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for(top = 0; top &amp;lt;= s.top; top++)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;v[top] = s.v[top];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;top--;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;return *this;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
The delete expression in operator= deletes the old array for the object on the left-hand side of the assignment. The delete operator leaves the value of v undefined. Most implementations leave v dangling unchanged, still pointing to the old array that has been returned to the heap. Suppose the exception from T::T() is thrown from within this assignment:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
operator=에서 delete 수식은 할당식 좌변 객체가 사용하는 배열을 삭제해 버립니다. delete 연산자를 수행하고 나면 v 값은 어떻게 될지 알 수 없습니다. 대부분 컴파일러들은 v 가 이미 힙으로 반납된 이전 배열을 가리키도록 그대로 놓아 둡니다. 그럼 할당 연산 안에서 T::T()를 수행하는 동안 예외가 발생했다고 가정해 보겠습니다:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;Stack x, y;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp;y = x; &amp;nbsp;// throw&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;} // double delete&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
As the exception propagates out of y.operator=, y.v is left pointing to the deallocated array. When the destructor for y executes at the end of the block, y.v still points to the deallocated array. The delete in the Stack destructor therefore has undefined results - it is illegal to delete the array twice.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
y.operator= 수행 도중 예외가 발생하면 y.v 는 반납된 메모리를 가리킨 채로 남게 됩니다. 이제 블록을 벗어 나려는 순간 y 에 대해 소멸자가 호출될 것인데, y.v 는 반납된 메모리를 여전히 가리키고 있으므로 어떤 일이 벌어질지 알 수가 없습니다 - 배열을 두 번 삭제하는 건 불법이죠.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: 10pt; &quot;&gt;An Invitation / 초대&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Regular readers of this column might now expect to see a presentation of my version of Stack. In this case, I have no code to offer, at least at present. Although I can see how to correct many of the faults in Reed's Stack, I am not confident that I can produce a exception-correct version. Quite simply, I don't think that I understand all the exception related interactions against which Stack must defend itself. Rather, I invite Reed (or anyone else) to publish an exception-correct version of Stack. This task involves more than just addressing the faults I have enumerated here, because I have chosen not to identify all the problems that I found in Stack. This omission is intended to encourage others to think exhaustively about the issues, and perhaps uncover situations that I have missed. If I did offer all of my analysis, while there is no guarantee of it completeness, it might discourage others from looking further. I don't know for sure how many bugs must be corrected in Stack to make it exception-correct.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이제 독자 여러분은 제가 개선된 Stack을 제시해 주길 바라실 것 같습니다. 그렇지만 적어도 지금은 제시할만한 코드가 없습니다. Reed의 Stack에서 여러 결함을 어떻게 수정해야 할지는 알겠지만 제가 예외를 제대로 처리하는 버전을 만들 수 있을지는 확신하기 어렵습니다. 솔직히 저도 Stack이 처리해야만 하는 예외와 관련된 모든 상호 작용들을 완벽하게 이해하고 있지는 못하기 때문입니다. 그래서 Reed에게 (혹은 누구든지) 예외를 제대로 처리하는 Stack 을 공개하도록 초청하는 바입니다. 제가 이 글에서 제시했던 결함들만 해결한다고 예외를 제대로 처리하는 Stack 이라고 할 수 없습니다. 왜냐하면 제가 발견했던 모든 문제를 설명하진 않았기 때문입니다. 다른 분들도 이 문제에 대해 더 철저히 생각하여 제가 놓쳤던 문제들을 밝혀 내길 바라는 마음에 일부러 생략하였습니다. 제가 분석했던 내용이 어차피 완벽하지도 않겠지만 그걸 모두 제시해 버린다면 다른 분들이 더 깊이 보려고 하지 않을 터이니까요. Stack이 예외를 제대로 처리하게 하려면 얼마나 많은 버그를 수정해야 할지 저로서도 잘 모르겠습니다.&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <category>c++</category>
      <category>C++ 이야기</category>
      <category>예외</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/372</guid>
      <comments>https://yesarang.tistory.com/372#entry372comment</comments>
      <pubDate>Wed, 30 Jun 2010 23:14:24 +0900</pubDate>
    </item>
    <item>
      <title>C++ 이야기 서른두번째: 예외가 성능에 미치는 영향</title>
      <link>https://yesarang.tistory.com/371</link>
      <description>&lt;a href=&quot;http://yesarang.tistory.com/368&quot; target=&quot;_blank&quot;&gt;2009/09/25 - [S/W개발/C++ 이야기] - C++ 이야기 서른한번째: 왜 예외를 쓰는 게 좋을까요?&lt;/a&gt;&amp;nbsp;에서 왜 예외를 쓰는 것이 좋은지에 대해 얘기를 해 봤습니다. 정리해서 말씀드리자면 결함내성 특성(fault-tolerant)을 가진 소프트웨어를 작성하기 쉽게 해주기 때문에 예외를 쓰는 것이 좋다라고 말씀드렸습니다.&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그런데 &lt;a href=&quot;http://pullip.tistory.com/&quot; target=&quot;_blank&quot; title=&quot;[http://pullip.tistory.com/]로 이동합니다.&quot;&gt;폴리비&lt;/a&gt;님께서 다음과 같은 댓글을 남겨 주셨습니다.&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(31, 31, 31); font-family: NanumGothic, 나눔고딕, 'Malgun Gothic', Dotum, 돋움, Gulim, 굴림, Verdana, Arial, 'Trebuchet MS'; font-size: 13px; &quot;&gt;&lt;blockquote&gt;예외 처리기능이 C++에 들어가서 좋지만, 속도 저하가 약간 있어서 꺼리는 경우도 있어요.&lt;br /&gt;
스트롭 할아버지는 별로 속도 저하 없으니 꼭 쓰라고 하지만 RTTI처럼 속도 때문에 꺼려지는 점이 있긴 하죠!&lt;br /&gt;
STL도 vector에 대해 at 메소드는 예외처리를 하지만, 완전 동일한 기능인 [] 연산자에서는 예외처리를 하지만,&amp;nbsp;많은 반복 예상되는 단순한 코드같은 경우 예외 처리가 꼭 필요하지는 않으면서도 예외 처리를 할 경우 성능을 떨어뜨리는 경우도 있습니다.&lt;br /&gt;
&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
예외 처리 기능을 활용하면 성능을 떨어뜨리니 무조건 쓰는 건 좋지 않다라는 말씀이겠죠. 이 댓글을 보고 예외가 성능에 도대체 어느 정도나 영향을 미치는지 알아보고 싶어서 실험을 해 봤습니다.&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
예외 처리가 성능에 미치는 영향을 측정하기 위해서는 어떻게 실험해야할까요? 예외 처리 기능을 사용하는 프로그램과 사용하지 않는 프로그램의 실행 시간을 비교해봐야겠다는 생각이 자연스럽게 떠오릅니다. 그렇지만 이 둘만 비교해서는 예외가 성능에 미치는 영향을 정확히 파악할 수 없을 것입니다. 왜냐하면, 단순히 try/catch 문을 사용했을 경우와 실제로 예외가 발생한 경우에 발생하는 overhead가 다를 것이기 때문입니다. try/catch 문만을 사용했을 경우에는 예외 처리를 위한 준비과정만 부가적인 overhead가 되겠지만, 예외가 실제로 발생한 경우에는 예외를 처리하는 과정(대표적으로 stack unwinding)이 overhead가 될 것이기 때문입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
예외가 발생하는 경우도 호출 깊이(call depth)가 어느 정도이냐에 따라 overhead가 달라질 수 있을 것이므로 호출 깊이도 달리 하면서 실험할 필요가 있을 것입니다. 마지막으로 호출 깊이가 깊어지는 경우 중간에 예외 처리기가 여러번 중첩될 수도 있고, 이런 예외 처리기에서 예외를 재발생시키거나(rethrow) 다른 예외로 매핑하는 경우도 있을 것입니다. 따라서 이러한 경우도 분리해서 테스트할 필요가 있을 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
정리하자면 다음 네 가지 경우에 대해 호출 깊이를 달리하여 테스트하면 어느 정도 예외가 성능에 미치는 영향에 대해 윤곽을 잡을 수 있을 것 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
1. 예외 처리를 사용하지 않는 프로그램&lt;/div&gt;
&lt;div&gt;
2. 예외 처리를 사용하나 예외를 발생시키지 않는 프로그램&lt;/div&gt;
&lt;div&gt;
3. 예외 처리를 사용하고 예외를 발생시키나 재발생시키지는 않는 프로그램&lt;/div&gt;
&lt;div&gt;
4. 예외 처리를 사용하고 예외를 발생시키며 재발생시키기도 하는 프로그램&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
호출 깊이를 달리하는 것은 동일한 함수를 재귀 호출하는 회수를 달리하면 될 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이 네 가지 경우를 다음과 같이 별도의 함수로 작성하였습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
먼저, 1. 예외 처리를 사용하지 않는 프로그램입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void NoTry(long long&amp;amp; r, int&amp;amp; rcnt) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;shared_ptr&amp;lt;Foo&amp;gt; p(new Foo());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;r += (rand() % 100);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (--rcnt)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;NoTry(r, rcnt);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
Foo 라는 클래스는 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class Foo {};&lt;/span&gt; 라고 비어 있는 클래스로 정의했습니다. rcnt 는 호출 깊이를 조절하기 위한 변수로 0이 되면 더 이상 재귀적으로 호출하지 않습니다. 함수 본문에서는 shared_ptr 로 Foo 라는 객체를 할당했다가 함수에서 리턴할 때 자동해제 되도록 하였고, r 이라는 참조 변수를 rand() % 100 결과값만큼 증가시키도록 하여 혹시 있을지도 모르는 컴파일러 최적화를 피하도록 했습니다. 더불어 함수 본문에서 어느 정도 시간이 걸리도록 하여 단순 함수 호출 overhead가 실행시간의 대부분을 차지하지 않도록 해 보았습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그 다음은 2. 예외 처리를&amp;nbsp;사용하나 예외를 발생시키지 않는 프로그램입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void TryNoException(long long&amp;amp; r, int&amp;amp; rcnt) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;try {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;shared_ptr&amp;lt;Foo&amp;gt; p(new Foo());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;r += (rand() % 100);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (--rcnt)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;TryNoException(r, rcnt);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;catch (const Ex&amp;amp;) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
NoTry와 거의 동일하나 함수 본문을 try/catch로 둘러 쌓았다는 점만 다릅니다. 실제로 예외는 발생하지 않으므로 try/catch 로 인한 overhead만을 측정할 수 있을 것입니다. 예외 클래스 Ex 는 Foo와 비슷하게 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;class Ex {};&lt;/span&gt; 로 비어 있는 클래스로 정의했습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
다음은&amp;nbsp;3. 예외 처리를 사용하고 예외를 발생시키나 재발생시키지는 않는 프로그램입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void TryException(long long&amp;amp; r, int&amp;amp; rcnt) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;try {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;shared_ptr&amp;lt;Foo&amp;gt; p(new Foo());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;r += (rand() % 100);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (--rcnt)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;TryException(r, rcnt);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;else&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;throw Ex();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;catch (const Ex&amp;amp;) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
2번 프로그램과 거의 비슷하지만, 재귀적으로 계속 호출하다가 제일 마지막에 Ex() 예외를 발생시킵니다. 그리고, catch 문에서 Ex 예외를 잡고 있으니 가장 깊은 호출 스택에서 예외 처리기가 동작하여 예외를 처리한 후, 그 다음부터는 단순한 함수 리턴과정을 거치게 될 것입니다. 정리하자면, 호출 깊이가 깊어지더라도 예외 처리로 인한 overhead는 한 번만 발생하게 될 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
마지막으로&amp;nbsp;4. 예외 처리를 사용하고 예외를 발생시키며 재발생시키기도 하는 프로그램입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int rethrowCnt = 0;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
void TryRethrowException(long long&amp;amp; r, int&amp;amp; rcnt) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;try {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;shared_ptr&amp;lt;Foo&amp;gt; p(new Foo());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;r += (rand() % 100);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (--rcnt)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;TryRethrowException(r, rcnt);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;else&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;throw Ex();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;catch (const Ex&amp;amp;) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (--rethrowCnt)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;throw;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
3.번하고 거의 동일한데, 예외 처리기 안에서 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;rethrowCnt&lt;/span&gt; 값을 하나씩 감소시키면서 예외를 재발생시키고 있습니다. 이렇게 하면 호출 경로상의 가장 상위 스택에서는 예외를 처리하게 되지만 다른 스택에서는 예외를 처리하기도 하고, 재발생시키기도 하게 될 것입니다. 이렇게 할 경우 예외를 발생시키고 처리하는 overhead가 호출 깊이 만큼 발생하게 됩니다. 이를 위해서는 전역변수인 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;rethrowCnt&lt;/span&gt;가 호출 깊이와 동일한 값으로 설정되어야겠지요.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이 함수들 실행시간을 비교해야 하는데, 한 번만 수행할 경우 너무 짧은 시간에 실행이 끝나 버릴테니, 여러번 수행한 후, CPU 사용량을 측정해야 할 것입니다. 실행 시작전 시각과 실행 완료 후 시각의 차로 실행시간을 측정할 경우에는 중간에 OS가 다른 프로그램을 스케쥴링하면서 실제 이 함수들에 의한 실행시간 외에 다른 시간이 끼어들 수 있으므로 CPU 사용량을 측정해야 합니다. CPU 사용량을 측정하기 위해서 time 이라는 시스템 유틸리티를 사용했습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
위 함수들을 여러 번 수행하기 위해 다음과 같은 함수를 작성했습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;typedef void (*F)(long long&amp;amp;, int&amp;amp;);&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
long long RunLoop(long long n, F f, int recursionCnt) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;long long r = 0;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;for (; n &amp;gt;= 0; --n) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int rcnt = recursionCnt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;rethrowCnt = recursionCnt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;f(r, rcnt);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;return r;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
주어진 함수 f를&amp;nbsp;n 번만큼&amp;nbsp;수행하는 함수입니다. 원하는 재귀 호출 회수도 인자로 받아서 f 함수에 넘겨 줍니다. 그리고, 전역변수인 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;rethrowCnt&lt;/span&gt;를 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;recursionCnt&lt;/span&gt; 값으로 설정해 줍니다. 이는 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;TryRethrowException()&lt;/span&gt; 함수가 각 호출 단계에서 예외를 재발생시키고 최상위 호출 단계에서는 예외를 처리하도록 하기 위한 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이 &lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;RunLoop&lt;/span&gt;를 활용하여 각 함수를 여러번 수행해 주는 main 함수는 다음과 같이 작성했습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;void Usage() {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;cout &amp;lt;&amp;lt; &quot;Please, specify test case number and call depth&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;cout &amp;lt;&amp;lt; &quot;1 means no try/catch block&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;cout &amp;lt;&amp;lt; &quot;2 means try/catch block but no exception&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;cout &amp;lt;&amp;lt; &quot;3 means try/catch block and exception&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;cout &amp;lt;&amp;lt; &quot;4 means try/catch block and rethrow exception&quot; &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;const string noTryCase = &quot;1&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;const string tryNoExCase = &quot;2&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;const string tryExCase = &quot;3&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;const string tryRethrowCase = &quot;4&quot;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int main (int argc, char * const argv[]) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (argc != 3) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Usage();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;return -1;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;srand((unsigned)time(0));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;F f = 0;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (noTryCase == argv[1]) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;f = NoTry;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;else if (tryNoExCase == argv[1]) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;f = TryNoException;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;else if (tryExCase == argv[1]) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;f = TryException;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;else if (tryRethrowCase == argv[1]) {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;f = TryRethrowException;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;else {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Usage();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;return -1;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;int callDepth = atoi(argv[2]);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;if (callDepth &amp;lt;= 0)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;callDepth = 1;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;return RunLoop(10000000, f, callDepth);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
보시는 것처럼 명령행 인자로부터 test case 번호와 호출 깊이를 받도록 하였습니다. 이렇게 할 경우, 순수하게 함수를 수행하는 시간 외에 명령행 인자를 해석하고 필요한 변수를 초기화하는 overhead가 끼어들긴 하겠지만, 각 함수를 수행하는 회수를 충분히 크게 해주면-위 예제는 10000000번-이 overhead 가 차지하는 시간이 아주 작아지게 될 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그리고, 각 test case를 한번씩만 수행할 경우, 실행 당시 시스템 상태에 따라 실행 시간이 달라질 수 있으므로, 다음과 같은 shell script 를 이용하여 각 test case를 10번씩 수행하고 그 평균 값을 서로 비교하였습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ cat test.sh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;#!/bin/sh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;run_test() {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;test_case=$1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;test_run=$2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while [ $test_run -gt 0 ]; do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;echo&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;echo &quot;time ./extest $test_case $3&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;time ./extest $test_case $3&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;test_run=`expr $test_run - 1`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;echo&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;done&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;call_depth=1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;while [ $call_depth -le 5 ]; do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;run_test 1 10 $call_depth&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;call_depth=`expr $call_depth + 1`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;done&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;call_depth=1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;while [ $call_depth -le 5 ]; do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;run_test 2 10 $call_depth&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;call_depth=`expr $call_depth + 1`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;done&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;call_depth=1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;while [ $call_depth -le 5 ]; do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;run_test 3 10 $call_depth&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;call_depth=`expr $call_depth + 1`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;done&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;call_depth=1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;while [ $call_depth -le 5 ]; do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;run_test 4 10 $call_depth&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;call_depth=`expr $call_depth + 1`&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;done&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그럼 실제 실험 결과를 보실까요?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2063D1034C1E1D20A3&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2063D1034C1E1D20A3&quot; width=&quot;590&quot; height=&quot;504&quot; alt=&quot;&quot; filename=&quot;예외 처리 성능 비교.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
결과에서 확인하실 수 있는 것처럼 try/catch 를 사용하지 않는 함수와 try/catch를 사용하되 예외를 발생하지 않는 경우는 거의 차이가 없음을 확인할 수 있습니다. 그래프에서 보면 TryNoException이 초록색인데 NoTry 파란색에 가려 전혀 보이질 않고 있습니다. 이 결과는 저로서도 약간 의외였는데요. 아무리 최적화된 try/catch를 구현하더라도 예외 처리 준비 작업이 어느 정도 필요하기 때문에 overhead가 어느 정도는 있을 줄 알았는데 실제로는 거의 차이가 없음을 확인할 수 있었습니다. 이것은 제가 사용하고 있는 컴파일러가 상당히 최적화된 예외 처리 메커니즘을 구현하고 있기 때문인 것 같습니다. C++ 철학중 하나인 수익자 부담의 원칙을 잘 따르고 있는 컴파일러라고 생각이 됩니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
다음으로 TryException 과 NoTry, TryNoException 케이스를 비교하면 호출 깊이에 따라 실행시간이 늘어나는 비율(기울기)은 거의 비슷한데, 위 아래로 간격이 상당히 떨어져 있음을 확인할 수 있습니다. TryException의 경우 한 번 예외가 발생하여 처리된 이후에는 계속해서 TryNoException과 거의 동일한 overhead만 발생할 것이기 때문에, 이것은 한 번 발생한 예외로 인한 overhead가 상당히 크다는 것을 증명한다고 해석해야 할 것입니다. 이것은 TryRethrowException 케이스에 의해 더 확실해집니다. TryRethrowException의 경우 각 호출 단계에서 예외를 발생시키고 처리하기 때문에 호출 깊이에 비례해서 예외 발생 및 처리 overhead가 발생하기 때문입니다. 그래서 다른 세가지 케이스에 비해 기울기가 훨씬 가파른 것을 확인할 수 있습니다.
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
실제 제가 위 네 가지 경우에 대해 선형 회귀식을 구했을 때 다음과 같은 결과가 나왔습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;NoTry: y = 5.0897x - 1.9361, R^2 = 0.9984&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
TryNoException: y = 4.7766x - 1.3758, R^2 = 0.999&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
TryException: y = 5.2183x + 48.001, R^2 = 0.9971&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;
TryRethrowException: y = 130.36x - 79.22, R^2 = 09985&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
예외가 한 번 발생했을 때, 처리하는 overhead가 상당한 것을 확인할 수 있습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이상을 종합해 보면 다음과 같이 결론 내릴 수 있을 것 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;font class=&quot;Apple-style-span&quot; color=&quot;#3058D2&quot;&gt;
1. 단순히 예외 처리를 위해 try/catch 구조를 사용한다고 하여 overhead가 발생하지는 않는다.&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;font class=&quot;Apple-style-span&quot; color=&quot;#3058D2&quot;&gt;
2. 예외 발생/처리 overhead는 상당히 크다.&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이 결론은 우리에게 시사하는 바가 상당히 크다고 생각합니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
1) 예외가 성능을 많이 저하시킨다는 막연한 생각에 아예 예외를 쓰지 않는 것도 피해야 할 것이고, 2) 예외를 예외 답지 않게 사용하는 것-즉, 에러 상황이 아닌 상당히 자주 발생할 수 있는 상황을 예외로 처리하는 경우-도 피해야 할 것이고, 3) 실시간성이 중요한 프로그램에서 호출 경로상 예외가 발생했을 경우 실시간성 검증 없이 예외를 사용하는 경우도 피해야 할 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
제가 테스트한 환경은 다음과 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ uname -a&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Darwin MyMac.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ g++ --version&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;i686-apple-darwin9-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5564)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;Copyright (C) 2007 Free Software Foundation, Inc.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;This is free software; see the source for copying conditions. &amp;nbsp;There is NO&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
컴파일 할 때는 다음과 같은 옵션을 주었습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: 'Courier New'; &quot;&gt;$ g++ -O3 -o extest -I /usr/local/include/boost-1_36 main.cpp&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
여러분들도 무작정 예외 처리 기능을 쓰지 않거나 혹은 쓰는 것이 아니라 자신이 개발하는 환경에서 실제 테스트를 해 보신 후에 데이터를 기반으로 예외 처리 기능을 사용할 것인지 말 것인지를 의사결정한다면 함께 일하는 분들 간에 동일한 생각으로 일할 수 있을 것입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
여러분도 자신의 개발 환경에서 테스트해 보신 후에 결과를 트랙백으로 한 번 연결해 주시면 감사하겠습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
(테스트 함수를 구현한 소스와 shell script를 첨부합니다. 그리고 한 가지, TryRethrowException의 경우 실험 시간이 너무 오래 걸려 천만번이 아닌 백만번만 수행한 결과를 단순 10배 한 결과를 서로 비교하였다는 것을 알려 드려야 할 것 같습니다. 철저하게 하려면 실제로 천만번 수행한 후에 결과를 비교해야겠지만 블로그 글감으로 쓰기에는 이런 정도로 해도 될 것 같아서 이렇게 결과를 올립니다)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;https://t1.daumcdn.net/cfile/tistory/143D3A104C1E285F1B&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://i1.daumcdn.net/cfs.tistory/v/0/blog/image/extension/unknown.gif&quot; style=&quot;vertical-align: middle;&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;main.cpp&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;https://t1.daumcdn.net/cfile/tistory/127C5F104C1E285FAD&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://i1.daumcdn.net/cfs.tistory/v/0/blog/image/extension/unknown.gif&quot; style=&quot;vertical-align: middle;&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;test.sh&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <category>c++</category>
      <category>C++ 이야기</category>
      <category>성능</category>
      <category>예외처리</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/371</guid>
      <comments>https://yesarang.tistory.com/371#entry371comment</comments>
      <pubDate>Mon, 21 Jun 2010 00:01:54 +0900</pubDate>
    </item>
    <item>
      <title>최근 C++ 소식</title>
      <link>https://yesarang.tistory.com/370</link>
      <description>&lt;span style=&quot;LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; FONT-FAMILY: arial, sans-serif; COLOR: rgb(0,0,0); FONT-SIZE: medium&quot; class=&quot;Apple-style-span&quot;&gt;
&lt;div style=&quot;PADDING-BOTTOM: 20px; MARGIN: 5px 15px; FONT-SIZE: 13px&quot; id=&quot;:8u&quot; class=&quot;ii gt&quot;&gt;
&lt;p&gt;1. C++0x Final Committee Draft(FCD)가 릴리즈됐습니다: Draft는&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;서 다운받을 수 있습니다. 표준화 과정 중에 논의된 내용들을 더 자세히 알고 싶으시면&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/&quot; target=&quot;_blank&quot;&gt;이 링크&lt;/a&gt;를 보시면 됩니다. Draft는 무려 1310페이지에 달합니다. 읽어보실 분은 미리 각오하시고 읽어 보시는 게 나을 것 같습니다. ^^&lt;/p&gt;
&lt;p&gt;2. C++0x FCD를 읽고 comment 할 것들이 있다면&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://www.justsoftwaresolutions.co.uk/cplusplus/c++0x-now-at-fcd.html&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;에 가서 comment를 남기시면 됩니다. 이제 final draft인 상태이기 때문에 주로 wording에 관련된 comment를 받아들이겠죠? 새로운 feature 추가하자 그러면 아마 받아들이지 못하겠죠. C++에 새로운 feature 를 추가하고 싶다면&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2122.htm&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;를 한 번 보시고 페이지 관리자에게 메일 보내보시면 될 듯(저도 보내보진 않았어요).&lt;/p&gt;
&lt;p&gt;3. Visual Studio 2010에 포함된 VC++이 지원하는 C++0x feature 구현 상태는&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;에서 보시면 됩니다.&lt;/p&gt;
&lt;p&gt;4. GCC에서 지원하는 C++0x feature 구현 상태는&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://gcc.gnu.org/projects/cxx0x.html&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;에서 보시면 됩니다.&lt;/p&gt;
&lt;p&gt;5. 각 컴파일러의 C++0x feature 구현 상태는&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://www.aristeia.com/C++0x/C++0xFeatureAvailability.htm&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;에 정리되어 있네요.&lt;/p&gt;
&lt;p&gt;6.&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://cppandbeyond.com/2010/04/15/c-beyond-event-structure/&quot; target=&quot;_blank&quot;&gt;C++ &amp;amp; Beyond 2010 Event&lt;/a&gt;가 열린답니다. 유명한 C++ 책 저자인 Herb Sutter, Scott Meyers , Andrei Alexandrescu 이 세 분이 주축이 돼서 진행하는 이벤트인가 보네요. 60명만 참가할 수 있답니다. 관심있으신 분은&amp;nbsp;&lt;a style=&quot;COLOR: rgb(17,65,112)&quot; href=&quot;http://cppandbeyond.com/2010/04/17/registration-is-now-open/&quot; target=&quot;_blank&quot;&gt;여기&lt;/a&gt;서 등록하시구요. 누군가 저를 스폰서 해 주실 분이 계시다면 저도 가보고 싶은데 말입니다. ㅠ.ㅠ&lt;/p&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN: 5px 15px 15px; CLEAR: both; FONT-SIZE: 13px&quot; class=&quot;hq gt&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;BACKGROUND-IMAGE: none; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: rgb(227,233,240); MARGIN: 0px; PADDING-LEFT: 0px; WIDTH: auto; PADDING-RIGHT: 0px; PADDING-TOP: 0px; background-origin: initial; background-clip: initial; border-bottom-left-radius: 6px 6px; border-bottom-right-radius: 6px 6px&quot; class=&quot;hi&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;BACKGROUND-IMAGE: none; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: rgb(227,233,240); MARGIN: 0px; PADDING-LEFT: 0px; WIDTH: auto; PADDING-RIGHT: 0px; FONT-SIZE: 13px; PADDING-TOP: 0px; background-origin: initial; background-clip: initial; border-bottom-left-radius: 6px 6px; border-bottom-right-radius: 6px 6px&quot; class=&quot;gA gt&quot;&gt;
&lt;/div&gt;&lt;/span&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <category>c++</category>
      <category>C++0x</category>
      <category>FCD</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/370</guid>
      <comments>https://yesarang.tistory.com/370#entry370comment</comments>
      <pubDate>Thu, 29 Apr 2010 21:58:13 +0900</pubDate>
    </item>
    <item>
      <title>C++ 이야기 서른한번째: 왜 예외를 쓰는 게 좋을까요?</title>
      <link>https://yesarang.tistory.com/368</link>
      <description>&lt;p&gt;&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;If you're an English speaker, please follow &lt;a style=&quot;color: rgb(0, 0, 0);&quot; title=&quot;[http://opensw.wikidot.com/cpp-fundamentals-exception]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://opensw.wikidot.com/cpp-fundamentals-exception&quot;&gt;this link&lt;/a&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;이글의 최신본은 항상 &lt;/span&gt;&lt;a style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot; title=&quot;[http://opensw.wikidot.com/cpp-fundamentals-exception-ko]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://opensw.wikidot.com/cpp-fundamentals-exception-ko&quot;&gt;&lt;/a&gt;&lt;a style=&quot;font-weight: bold; color: rgb(0, 0, 0);&quot; title=&quot;[http://opensw.wikidot.com/cpp-fundamentals-exception-ko]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://opensw.wikidot.com/cpp-fundamentals-exception-ko&quot;&gt;여기&lt;/a&gt;&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;에 있습니다. 최신본은 코드에 syntax highlighting도 되어 있고, 철자법도 맞추고 부가정보도 계속 업데이트 하고 있습니다.&lt;/span&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;여러분은 서브루틴에 에러가 발생했다는 걸 알려주려 할 때 C++ 예외를 사용하시나요? 쓰시지 않는다면, 왠가요? 에러를
나타내는 특별한 에러 코드를 되돌려주면 되기 때문에 전혀 사용할 필요가 없다라고 답변하실지도 모르겠습니다. 사용하신다면,
왠가요? 이 질문에 대해서는 다른 방법이 있나요?라고 오히려 반문하시는 분이 있을지도 모르겠네요.&lt;/p&gt;
&lt;p&gt;C++에 예외가 도입된 이유를 밝하기 위해 이 글을 작성하게 됐습니다. 이 설명을 통해 위에 두 부류의 분들 모두 예외에 대해 더 잘 이해하게 되고, 예외를 이용하여 더 좋은 코드를 작성하는데 도움이 되시리라 생각합니다.&lt;/p&gt;
&lt;p&gt;C++에 왜 예외에 도입되었다고 생각하세요? 왜 아직도 Java나 C#같은 언어가 C++의 예외를 물려 받았다고
생각하세요? 그런데는 틀림없이 어떤 이유가 있을 것입니다. 그 이유는 바로 결함내성(fault-tolerant) 소프트웨어를
쉽게 작성하도록 하기 위한 것입니다.&lt;/p&gt;
&lt;p&gt;C/C++ 같이 상태를 갖는 프로그래밍 언어에서 에러 처리를 한 후에도 일관성있는 상태를 유지해야 한다는 건 결함내성을 달성하는데 있어 정말 까다로운 문제입니다.&lt;/p&gt;
&lt;p&gt;예를 들어, 다음과 같이 어떤 파일을 열고 데이터를 읽어들이는 짤막한 C 코드를 생각해 보기로 하겠습니다.

&lt;/p&gt;
&lt;pre&gt;char*
OpenAndRead(char* fn, char* mode)
{
  FILE* fp = fopen(fn, mode);
  char *buf = malloc(BUF_SZ);
  fgets(buf, BUF_SZ, fp);
  return buf;
}
&lt;/pre&gt;
&lt;p&gt;OpenAndRead()의 목적이 워낙 간단하고 분명하니, 그 구현도 무척이나 간단하고 읽기도 쉽고 이해하기도 쉽습니다.
위 코드는 모든 서브루틴이 잘 수행된다면 잘 작동할 것입니다. 그렇지만 'fn' 파일이 없거나 파일에 대한 접근 권한이 없다면
어떻게 될까요? malloc() 이나 fgets() 이 실패하면 어떻게 될까요? 위 코드를 결함내성이 있게 만들려면 각 서브루틴
호출 후에 에러가 발생했는지 확인해보고, 에러가 발생했다면 어떤 행동을 취해야할 것인지 결정해야 합니다. 그 취해야할 행동이
여기서는 단순히 에러 메시지를 출력하고 획득했던 자원들을 해제하고, -1 을 리턴하는 걸로 가정해 보겠습니다. 그렇다면 코드를
다음과 같이 수정할 수 있겠지요.&lt;/p&gt;
&lt;pre&gt;int
OpenAndRead(char* fn, char* mode, char** data)
{
  *data = NULL;
  char* buf = NULL;
  FILE* fp = fopen(fn, mode);
  if (!fp) {
    printf(&quot;Can't open %s\n&quot;, fn);
    return -1;
  }
 
  buf = malloc(BUF_SZ);
  if (!buf) {
    printf(&quot;Can't allocate memory for data\n&quot;);
    fclose(fp);
    return -1;
  }
 
  if (!fgets(buf, BUF_SZ, fp)) {
    printf(&quot;Can't read data from %s\n&quot;, fn);
    free(buf);
    fclose(fp);
    return -1;
  }
 
  *data = buf;
 
  return 0;
}
&lt;/pre&gt;
&lt;p&gt;두 개의 코드를 비교해 보니 느낌이 어떠세요? 두번째 버전은 주 알고리즘을 처리하는 부분과 에러를 처리하는 부분이 막 섞여 있어서 읽기도 힘들고 이해도 힘들어졌습니다. 게다가 라인수도 많아져서 일을 더 많이해야하네요.&lt;/p&gt;
&lt;p&gt;예외를 사용하면 이런 문제가 발생하지 않습니다. 한 번 fopen(), malloc(), fgets() 이
FileDoesNotExist, FileNotAccessible, MemoryExhausted, EndOfFile 라는 예외를
발생시킨다고 가정해 보겠습니다. 그렇다면 다음과 같이 코드를 변화시킬 수 있을 것입니다.&lt;/p&gt;
&lt;pre&gt;int
OpenAndRead(char* fn, char* mode, char** data)
{
  *data = NULL;
  char* buf = NULL;
  FILE* fp = NULL;
  try {
    fp = fopen(fn, mode);
    buf = malloc(BUF_SZ);
    fgets(buf, BUF_SZ, fp);
    *data = buf;
    return 0;
  }
  catch (const FileDoesNotExist&amp;amp;) {
    printf(&quot;Can't open %s\n&quot;, fn);
  }
  catch (const FileNotAccessible&amp;amp;) {
    printf(&quot;The access %s is not permissible for %s\n&quot;, mode, fn);
  }
  catch (const MemoryExhausted&amp;amp;) {
    printf(&quot;Can't allocate memory for data\n&quot;);
    fclose(fp);
  }
  catch (const EndOfFile&amp;amp;) {
    printf(&quot;Can't read data from %s\n&quot;, fn);
    fclose(fp);
    free(buf);
  }
 
  return -1;
}
&lt;/pre&gt;
&lt;p&gt;OpenAndRead() 주 제어 흐름이 이제 에러 처리와 깔끔하게 분리가 된 걸 보실 수 있겠죠?
OpenAndRead() 이 버전은 좀 더 읽기 쉽게 됐네요. 그렇지만 아직도 라인수가 좀 많은 편입니다. 실상 예외가 발생했을
때 이루어지는 &quot;스택 풀기(stack unwinding)&quot;이라는 과정을 이해하시면 더 적은 코드로 동일한 효과를 낼 수 있답니다.&lt;/p&gt;
&lt;p&gt;예외가 발생하고 나서 그 예외를 처리할 수 있는 예외 처리기를 만날 때까지 스택을 풀어나가면서, C++ 실행 환경은 try
블록부터 생성됐던 모든 자동 객체들에 대해 소멸자를 불러주게 됩니다. 이 과정을 &quot;스택 풀기&quot;라고 합니다. 자동 객체들은
생성됐던 반대 순서로 소멸됩니다.&lt;/p&gt;
&lt;p&gt;이런 원리에 따라 자원을 소유하는 객체들을 자동 객체로 정의하게 되면 예외가 발생하더라도 그런 객체들이 자동적으로 소멸되는
것이지요. 이런 프로그래밍을 가능케 하는 자원 소유 객체들이 파일이나 메모리에 대해 이미 정의되어 있습니다. 파일 자원용으로는
std::fstream을 사용할 수 있고, 메모리 자원용으로는 boost::scoped_ptr을 사용할 수 있습니다.
OpenAndRead()를 다시 한 번 아래와 같이 구현할 수 있을 것입니다.&lt;/p&gt;
&lt;pre&gt;char*
OpenAndRead(const std::string&amp;amp; fn, std::ios_base::openmode mode)
{
  try {
    std::fstream fs(fn.c_str(), mode);
    boost::scoped_ptr&lt;char&gt; buf(new char[BUF_SZ+1]);
    fs.getline(buf.get(), BUF_SZ);
    return buf.get();
  }
  catch (const std::ios_base::failure&amp;amp;) {
    std::cout &amp;lt;&amp;lt; &quot;Can't open or read data from &quot; &amp;lt;&amp;lt; fn &amp;lt;&amp;lt; std::endl;
  }
  catch (const std::bad_alloc&amp;amp;) {
    std::cout &amp;lt;&amp;lt; &quot;Can't allocate memory for data&quot; &amp;lt;&amp;lt; std::endl;
  }
 
  return 0;
}
&lt;/char&gt;&lt;/pre&gt;
&lt;p&gt;C++ 실행기(run-time)가 모든 자원 해제를 알아서 하게 됩니다. 그래서 에러 처리 코드에 자원 해제 코드를 추가할 필요가 없게 됩니다. OpenAndread() 가 상당히 간단해지고, 읽기도 쉬워졌죠?&lt;/p&gt;
&lt;p&gt;예외가 발생하게 되면 C++ 실행기가 예외 처리기를 만날 때까지 소멸자를 역순으로 호출하면서 스택 풀기를 수행할 것입니다.
위 경우에는 동일한 스택 프레임에 예외 처리기가 있고, 두 개의 자동 객체, fs와 buf가 있습니다. 예외 처리기로 제어권이
넘어가기 전에 fs와 buf의 소멸자가 호출될 것이고, 소멸자는 내부 자원을 해제하게 될 것입니다.&lt;/p&gt;
&lt;p&gt;위와 같은 방식은 예외에 대한 반응이 워낙 간단하기 때문에 만족스럽지 않을 거라 생각합니다. 위와 같은 방식으로는
OpenAndRead()의 호출자가 그저 성공 또는 실패 정도만 나타낼 수 있는 정상 포인터 또는 널 포인터를 받을 뿐이기
때문입니다. 호출자 입장에서 생각해 보면, 왜 실패했는지를 알지 못한 상태에서 널 포인터로 할 수 있는 게 없습니다.&lt;/p&gt;
&lt;p&gt;위에서 알 수 있듯이, 에러에 어떻게 반응할지를 결정하는 것이 결함 내성 소프트웨어를 작성하는 데 겪는 또 다른
어려움입니다. 에러가 발생한 상황(context)과 원인이 에러에 대한 반응을 결정하는 데 있어 필수적인 정보라 할 수
있습니다. 그런데 그런 정보들은 여기 저기 흩어져 있기 마련입니다. 에러 처리에는 보통 두가지 부분의 코드가 관련이 있습니다.
하나는 호출자이고 또 하나는 피호출자입니다. 피호출자는 에러가 발생한 원인은 알지만 상황은 잘 모를 가능성이 높고, 반대로, 호출자는 상황은 알지만 이유를 모를 가능성이 높습니다. 이런 상황을 어떻게 극복할 수 있을까요?&lt;/p&gt;
&lt;p&gt;피호출자가 충분한 상황을 알고 있는 호출자에게 최대한 정확히 에러가 발생한 원인을 알려준다면 분명한 해결책이 될 수 있을
것 같습니다. 그렇지만 호출자가 피호출자를 직접 호출한 게 아니었다면 어떻게 될까요? 충분한 상황 정보를 가지고 에러에 대한
반응을 결정할 수 있는 호출자가 에러가 발생한 원인을 정확히 알고 있는 피호출자로부터 멀리 떨어져 있다면, 중간 함수가 에러가
발생한 상세 원인을 무시해 버리고 그냥 성공 또는 실패만을 나타내는 코드를 되돌려 주는 일이 자주 발생합니다. 예제를 통해서
확인해 볼까요?&lt;/p&gt;
&lt;pre&gt;int
OpenAndRead(char* fn, char* mode, char** data)
{
  *data = NULL;
  char* buf = NULL;
  FILE* fp = fopen(fn, mode);
  if (!fp) {
    printf(&quot;Can't open %s\n&quot;, fn);
    return -1;
  }
 
  buf = malloc(BUF_SZ);
  if (!buf) {
    printf(&quot;Can't allocate memory for data\n&quot;);
    fclose(fp);
    return -2;
  }
 
  if (!fgets(buf, BUF_SZ, fp)) {
    printf(&quot;Can't read data from %s\n&quot;, fn);
    free(buf);
    fclose(fp);
    return -3;
  }
 
  *data = buf;
 
  return 0;
}
 
char* foo(char* fn, char* mode)
{
  char* data = 0;
  if (OpenAndRead(fn, mode, &amp;amp;data) &amp;gt;= 0)
    return data;
  else
    return 0;
}
 
void bar()
{
  ...... // fn과 mode를 얻어낸다
  char* data = foo(fn, mode);
  if (data) {
    ...... // 정상 처리
  }
  else {
    ...... // bar()가 뭘 할 수 있을까요?
  }
}
&lt;/pre&gt;
&lt;p&gt;OpenAndRead()는 되돌림 코드(return code)를 통해 에러를 구분하려고 하고 있습니다. 근데 foo()는
그걸 무시하고 그냥 널 포인터나 정상 포인터를 되돌려 주고 마네요. 이래서는 bar()가 진짜 무슨 일이 벌어지고 있는지 알아낼
수가 없게 되고, 널 포인터로는 뭔가 할 수 있는 게 없어집니다. 아마도 bar()가 할 수 있는 거라곤 에러 메시지를 출력하고
그냥 종료하거나 가능하다면 에러를 무시해 버리는 거겠죠. 호출 경로 상의 각 함수들은 어떻게든 에러 처리에 관여할 수 밖에 없기
때문에 예외가 없이는 이런 상황이 더 심각해 질 수 밖에 없습니다. 어떤 함수 작성자는 되돌림 코드가 뭘 의미하지 모를 수도
있고, 에러가 뭘 의미하는지 별로 상관하지 않을 수도 있고, 아니면 충분한 상황을 알지 못해 어떤 처리를 해야할지 결정을 못할
수 있습니다. 그래서 호출 경로 상의 어딘가에서 되돌림 에러 코드가 그냥 실패를 나타내는 값으로 바뀌어 버리게 되는 거죠.&lt;/p&gt;
&lt;p&gt;예외를 사용한다면 이런 문제를 해결할 수 있습니다. 호출 경로상의 어떤 함수가 예외를 처리하지 못하겠다면 그 함수는 그냥 예외를 잡지(catch) 말고 무시해 버리면 됩니다. 진짜 처리할 수 있는 예외만 처리하면 되는 것이지요.&lt;/p&gt;
&lt;p&gt;자~ 이제 마지막으로 한번 만 더 OpenAndRead()를 변형시켜 보겠습니다. 일단 OpenAndRead()와 foo()는 예외를 어떻게 처리해야 할지 모른다고 가정하고, bar()는 처리할 수 있다고 가정해 보겠습니다.&lt;/p&gt;
&lt;pre&gt;char*
OpenAndRead(const std::string&amp;amp; fn, std::ios_base::openmode mode)
{
  std::fstream fs(fn.c_str(), mode); // std::ios_base::failure() 가 발생할지 모릅니다.
  boost::scoped_ptr&lt;char&gt; buf(new char[BUF_SZ+1]);  // std::bad_alloc() 가 발생할지 모릅니다
  fs.getline(buf.get(), BUF_SZ);
  return buf.get();
}
 
char* foo(char* fn, char* mode)
{
  // 아무런 예외도 잡지 않고 있습니다
  return OpenAndRead(fn, mode);
}
 
void bar()
{
  ...... // fn과 mode를 알아냅니다
  try {
    char* data = foo(fn, mode);
  }
  catch (const std::ios_base::failure&amp;amp;) {
    std::cout &amp;lt;&amp;lt; &quot;Can't open or read data from &quot; &amp;lt;&amp;lt; fn &amp;lt;&amp;lt; std::endl;
    // 왜 fn 열어서 데이터를 읽으려고 했는지를 안다면 좀 더 정확한 진단 메시지를 출력하고,
    // 사용자에게 뭔가 조치를 취하라고 알려줄 수 있습니다
  }
  catch (const std::bad_alloc&amp;amp;) {
    std::cout &amp;lt;&amp;lt; &quot;Can't allocate memory for data&quot; &amp;lt;&amp;lt; std::endl;
    // 이런 경우를 대비해 메모리를 미리 따로 마련해 놓았다면 bad_alloc()를 
    // 좀 더 부드럽게 처리할 수도 있을 것입니다.
  }
}
&lt;/char&gt;&lt;/pre&gt;
&lt;p&gt;위 코드에서 볼 수 있듯이, OpenAndRead()와 foo()가 다시 간단해 졌고, bar()만 에러 처리에 관여하고
있습니다. 게다가 예외가 뭘 의미하는지 알고 충분한 상황 정보기 있기 때문에 예외를 정말 절 처리할 수 있게 됐습니다.&lt;/p&gt;
&lt;p&gt;예외의 또 한 가지 장점은 예외는 그 자체로서 객체라는 것입니다. 이건 예외를 발생시킬 때 될 수 있으면 많은 정보를
담아서 발생시킬 수 있다는 것입니다. 다시 말해 예외는 되돌림 코드보다 훨씬 표현력이 좋다고 할 수 있습니다. 그렇다면, 예외
처리기는 그 정보들을 접근할 수 있게 되고, 그 정보들은 어떤 일이 벌어지고 있는지를 정확히 알아내는 데 큰 도움이 될 것입니다.&lt;/p&gt;
&lt;p&gt;이제 여러분에게 &quot;C++ 예외를 사용하고 싶으세요&quot;라고 묻고 싶군요. 뭐라고 답변하시겠어요? &quot;당연히 써야죠&quot;라는 답변을 들었으면 하네요.&lt;/p&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/368</guid>
      <comments>https://yesarang.tistory.com/368#entry368comment</comments>
      <pubDate>Fri, 25 Sep 2009 23:59:16 +0900</pubDate>
    </item>
    <item>
      <title>위키 업데이트 상황</title>
      <link>https://yesarang.tistory.com/367</link>
      <description>얼마전에 제가 &lt;a title=&quot;[http://yesarang.tistory.com/365]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://yesarang.tistory.com/365&quot;&gt;블로그 글들 옮깁니다&lt;/a&gt;라는 글에서 소프트웨어 개발 관련 글들을 위키로&amp;nbsp; 차례 차례 옮길 것이라고 공지를 드렸습니다. 그 이후에 짬이 나는 대로 옮기고 있는데, 블로그와 위키와의 차이점 때문에 그것도 그리 쉬운 것만은 아니네요. 일일이 하나씩 옮겨야 하니... 암튼 지금까지는 13개의 글을 옮겼습니다.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-stl-auto-ptr-1&quot;&gt;auto_ptr 템플릿 클래스 소개(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-stl-auto-ptr-2&quot;&gt;auto_ptr 의 두 얼굴(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-stl-auto-ptr-3&quot;&gt;auto_ptr을 표준 컨테이너에 담지 말라(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-new-delete&quot;&gt;new와 delete(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-bool&quot;&gt;기본기 다지기, bool type에 관하여(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-explicit&quot;&gt;기본기 다지기, explicit 키워드(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-this&quot;&gt;객체 자신을 가리키는 변수가 this 포인터인 이유는?(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-temporaries-1&quot;&gt;임시 객체는 임시 객체일 뿐 No.1(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-temporaries-2&quot;&gt;임시 객체는 임시 객체일 뿐 No.2(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-temporaries-3&quot;&gt;임시 객체가 충분히 임시스럽기 위하여(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-do-not-copy&quot;&gt;내 객체 복사하지마!(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-tr1-history&quot;&gt;TR1 History(Korean)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
어떻게 옮기고 있는지 궁금하신 분들은 한 번 들러보시기 바랍니다.&lt;br /&gt;
&lt;br /&gt;
글 옮기는 거 외에도 한번 &lt;a title=&quot;[http://opensw.wikidot.com/cpp-fundamentals-exception]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://opensw.wikidot.com/cpp-fundamentals-exception&quot;&gt;Why Exceptions?&lt;/a&gt;라는 제목으로 C++ exception을 쓰면 어떤 점이 좋은지에 대해 영어로 글을 써 봤습니다. 영어 잘 한다고 자랑하려는 건 아니구요(어차피 잘하지도 못하지만), 국내에만 머무르는 사람이 되지 않기 위해 영어로 작성해 보고 있습니다.  영어에 자신 있으신 분들은 여기에 한글 번역된 것을 올리기 전에 먼저 읽어 보시고 Comment 주시면 감사하겠습니다.&lt;br /&gt;
&lt;br /&gt;
위키 주소는 &lt;a title=&quot;[http://opensw.wikidot.com]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://opensw.wikidot.com&quot;&gt;http://opensw.wikidot.com&lt;/a&gt; 입니다. 많은 관심과 격려 부탁드립니다. ^^&lt;br /&gt;
&lt;br /&gt;</description>
      <category>기타</category>
      <category>영어</category>
      <category>위키</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/367</guid>
      <comments>https://yesarang.tistory.com/367#entry367comment</comments>
      <pubDate>Tue, 22 Sep 2009 23:27:56 +0900</pubDate>
    </item>
    <item>
      <title>미투데이 대 트위터</title>
      <link>https://yesarang.tistory.com/366</link>
      <description>&lt;DIV class=me2day_daily_digest&gt;
&lt;UL&gt;
&lt;LI&gt;미투데이와 트위터의 차이점: 미투데이는 초기부터 API를 써서 3rd party 응용을 위한 환경을 조성하긴 했지만 twitter 만큼은 open 하지 못했다. 왜냐면 traffic을 외부로 잘 넘겨주지 않는 내부완결형 구조 특성이 있다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:12:35&quot; rel=bookmark&gt;2009-09-13 11:12:35&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://me2day.net/yesarang/2009/09/13#11:12:35&quot;&gt;트위터는&lt;/A&gt; 140자 제한마저 외부 서비스를 활성화하는데 사용하고 있으나 미투데이는 링크를 표현하기 위한 별도의 방법을 정의했다. 이 때문에 미투데이가 풍부한 내용을 담을 수 있다는 장점이 있지만 에코시스템 창출에는 트위터가 나은 것 같다&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:15:58&quot; rel=bookmark&gt;2009-09-13 11:15:58&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://me2day.net/yesarang/2009/09/13#11:15:58&quot;&gt;물론 미투데이가 훨씬 우리나라 사람들 스타일에 맞는 것 같긴 하다.&lt;/A&gt;&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:16:59&quot; rel=bookmark&gt;2009-09-13 11:16:59&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;그리고, 사진이랑 비디오를 flickr, youtube에 upload 하긴 하지만 in place로 보여주는 점 등이 그 예이다. 3rd party service가 활성화되기 위한 필요 조건이 traffic 분산이 아닐까 생각해 본다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:23:23&quot; rel=bookmark&gt;2009-09-13 11:23:23&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;미투데이는 이제 인기를 끌기 시작했고, 트위터는 이미 사용자가 폭발한 상태이니 지금 시점에서 직접 비교하긴 힘들지만 나중에 어떻게 될까 상당히 궁금해지는 대목이다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:30:06&quot; rel=bookmark&gt;2009-09-13 11:30:06&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;미투데이가 훌륭한 점 중에 하나는 태그가 따로 있다는 것이다. 짧은 글들이라도 모이면 상당히 중요한 정보가 될 수 있는 것인데, 태그가 그 역할을 충실히 해주고 있다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:32:24&quot; rel=bookmark&gt;2009-09-13 11:32:24&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;트위터도 해쉬태그가 있지만 해쉬태그는 영어밖에 안된다는 문제가 있고, 해쉬태그 여러개 주면 글 쓸 공간이 금방 부족해져 버린다. 다른 사람 글에 대해 핑백으로 링크를 달 수 있는 것도 좋은 점 중의 하나이다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:35:02&quot; rel=bookmark&gt;2009-09-13 11:35:02&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;트위터에서는 다른 사람 글도 보이고 자기 생각도 보이고 싶더라도 공간이 부족해서 그렇게 하질 못한다. 결국 원문을 편집하거나 자기 생각은 거의 없이 그냥 RT를 하게 되는 경우가 종종 있다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:36:43&quot; rel=bookmark&gt;2009-09-13 11:36:43&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;다분히 유명인 위주로 다른 사람들은 그저 정보를 확산시키는 매개체로 작용할 가능성이 충분히 있다는 얘기다. 각 개개인의 개성은 몰살되고, 마케팅을 위한 채널 정도로만 악용될 가능성이 충분히 있다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:38:16&quot; rel=bookmark&gt;2009-09-13 11:38:16&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;트위터에서는 친구라는 개념이 없고 팔로워라는 개념이 있는데, 팔로워는 미투데이의 구독개념과 비슷하다고 볼 수 있다. 친구만큼 깊은 관계를 맺고 싶진 않지만, 그 사람이 생성하는 정보에 대해서는 관심이 있다라는 정도라고 할 수 있다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:44:24&quot; rel=bookmark&gt;2009-09-13 11:44:24&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;물론 때에 따라서는 팔로워가 친구만큼 가까운 관계인 경우도 있지만, 아주 실리적으로 관계를 맺는 약한 관계라고 할 수 있다. 미투데이 친구는 상호간에 관계를 맺지만, 트위터는 한쪽에서 일방적으로 팔로우하면 된다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:46:40&quot; rel=bookmark&gt;2009-09-13 11:46:40&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;그래서 그런지 트위터 내에서는 하루에도 수많은 사람들이 팔로우를 했다가 얼마있다가 언팔로우를 했다가 하는 일이 비일비재하다. 그렇게 별 이유없이 팔로우는 하는 사람들은 대부분 자기를 팔로우하기를 바라는 마음에서 팔로우를 한다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:48:04&quot; rel=bookmark&gt;2009-09-13 11:48:04&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;트위터 내에서는 팔로워의 수가 기본적인 영향력의 지수가 될 수 있고, 영향력이 높다는 얘기는 마케팅 효과가 크다는 얘기가 될 수 있다. 그래서 트위터 내에서는 매일 매일 자신의 팔로워 수를 높이려는 사람들이 무차별적으로 팔로우를 한다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:50:07&quot; rel=bookmark&gt;2009-09-13 11:50:07&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;물론 기존에 이미 유명했던 사람들은 굳이 팔로우를 하지 않지만 유명하지 않았던 사람들이 자신의 영향력을 높이기 위해 그렇게 하고 있다는 것이다. 그렇게 되면 아마도 기업 마케팅 부서에서 연락을 해 올 가능성이 높을 것이기 때문이다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:52:39&quot; rel=bookmark&gt;2009-09-13 11:52:39&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;이런 무차별적이고 실용적인 관계가 과연 요즘과 같은 주목경제에서 효과를 발휘할 수 있을지는 의문이다. 정보의 홍수 속에서 차라리 기존보다 가까운 지인들의 영향력이 커질 수 있는데, 약한 관계를 바탕으로 한 마케팅이 효과를 볼 수 있을지 의문이다.&lt;SPAN class=me2_tags&gt;(2tw 미투데이 트위터 차이점)&lt;/SPAN&gt;&lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2009/09/13#11:54:46&quot; rel=bookmark&gt;2009-09-13 11:54:46&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style=&quot;TEXT-ALIGN: right; PADDING-RIGHT: 25px; BACKGROUND: url(http://me2day.net/images/me2day_icon.gif) no-repeat right top; FONT-SIZE: 0.9em&quot;&gt;이 글은 &lt;A href=&quot;http://me2day.net/yesarang&quot; target=_blank&gt;김윤수&lt;/A&gt;님의 &lt;A href=&quot;http://me2day.net/yesarang/2009/09/13#11:12:35&quot;&gt;2009년 9월 13일&lt;/A&gt;의 미투데이 내용입니다.&lt;/P&gt;&lt;/DIV&gt;</description>
      <category>인터넷오늘은</category>
      <category>미투데이</category>
      <category>차이점</category>
      <category>트위터</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/366</guid>
      <comments>https://yesarang.tistory.com/366#entry366comment</comments>
      <pubDate>Sun, 13 Sep 2009 12:12:30 +0900</pubDate>
    </item>
    <item>
      <title>블로그 글들 옮깁니다.</title>
      <link>https://yesarang.tistory.com/365</link>
      <description>안녕하세요. 제 블로그를 아껴주시는 독자여러분.&lt;br /&gt;
&lt;br /&gt;아주 오랫동안 블로그를 버려 두다 시피하여 이젠 많은 분들이 관심을 잊어 버렸을 것 같기도 합니다만, 그럼에도 불구하고 여전히 구독해지 않고 기다려 주신분들께 우선 감사의 말씀드립니다.&lt;br /&gt;
&lt;br /&gt;제 글의 성격상 블로그라는 미디어의 형식에 어울리지 않는 것 같아 앞으로는 개발 관련 글들은 블로그에 작성하지 않고 위키 서비스에 올릴 생각입니다. 위키 서비스를 검색하던 차에 wikidot.com 이라는 괜찮은 서비스를 찾아서 여기 있는 글들을 차츰 차츰 옮길 생각입니다. 물론 여기에도 그대로 놔두긴 하겠지만 글들을 검토하면서 좀 더 다듬고 하는 것은 위키에서만 하게 될 것 같습니다.&lt;br /&gt;
&lt;br /&gt;아직은 이제 막 싸이트를 개설하고 위키 문법 공부하고 있는 중이라 글을 본격적으로 옮기진 못했구요. 앞으로 짬 날때마다 옮길 생각입니다.&lt;br /&gt;
&lt;br /&gt;위키 싸이트는 전 세계의 좀 더 많은 분들 소통하기 위해 한글과 영문 두 언어로 작성할 생각입니다.&lt;br /&gt;
&lt;br /&gt;위키 사이트 주소는&amp;nbsp;&amp;nbsp;&lt;A href=&quot;http://opensw.wikidot.com/&quot;&gt;http://opensw.wikidot.com&lt;/A&gt; 입니다. 많은 관심 부탁드립니다.&lt;br /&gt;
&lt;br /&gt;어느 정도 글들을 옮긴 이후에 다시 공지드리도록 하겠습니다.&lt;br /&gt;</description>
      <category>기타</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/365</guid>
      <comments>https://yesarang.tistory.com/365#entry365comment</comments>
      <pubDate>Sun, 6 Sep 2009 18:00:01 +0900</pubDate>
    </item>
    <item>
      <title>C++ 이야기 서른번째: boost::shared_ptr performance</title>
      <link>https://yesarang.tistory.com/364</link>
      <description>최근 제가 진행하던 프로젝트에서 boost::shared_ptr를 상당히 많이 사용해 왔었는데, 성능이 좋게 나오질 않아서 혹시나 해서 오늘 성능을 간단하게 측정해 봤더니 속도 차이가 상당히 많이 나는군요. 성능이 &lt;span style=&quot;font-weight: bold; color: rgb(25, 61, 169);&quot;&gt;좀&lt;/span&gt; 느리겠거니 했는데 상상 이상이었습니다.(실은 이 문제 때문에 한바탕 홍역을 치뤘죠. ㅠ.ㅠ)&lt;br /&gt;
&lt;br /&gt;
다음은 테스트 프로그램입니다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;$ cat shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#include &amp;lt;boost/shared_ptr.hpp&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;using namespace std;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;using namespace boost;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;class AClass&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;public:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Op() const &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ++i;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int Get() const&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return i;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;private:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mutable int i;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#ifdef SHARED_PTR&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;void Foo(const shared_ptr&amp;lt;AClass&amp;gt;&amp;amp; p)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p-&amp;gt;Op();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#elif defined(SHARED_PTR_COPY)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;void Foo(shared_ptr&amp;lt;AClass&amp;gt; p)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p-&amp;gt;Op();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#else&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;void Foo(AClass* p)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p-&amp;gt;Op();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#endif&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;int&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;main(int argc, char* argv[])&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#if defined(SHARED_PTR) || defined(SHARED_PTR_COPY)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; shared_ptr&amp;lt;AClass&amp;gt; p(new AClass());&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#else&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AClass* p = new AClass();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#endif&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int maxCnt = 1000000000;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (argc &amp;gt;= 2)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; maxCnt = atoi(argv[1]);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; maxCnt; ++i)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Foo(p);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; p-&amp;gt;Get() &amp;lt;&amp;lt; endl;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
이 테스트 프로그램은 세 가지 경우를 테스트하기 위한 것입니다.&lt;br /&gt;
&lt;br /&gt;
1. raw pointer를 사용하는 경우: SHARED_PTR&amp;nbsp; 또는 SHARED_PTR_COPY 가 정의되지 않은 경우입니다.&lt;br /&gt;
2. shared_ptr을 사용하는 경우: SHARED_PTR 이 정의된 경우입니다. Foo()를 호출할 때, const shared_ptr reference를 넘기기 때문에 복사가 일어나질 않습니다.&lt;br /&gt;
3. shared_ptr을 쓰면서 복사를 하는 경우: SHARED_PTR_COPY가 정의된 경우입니다. Foo()를 호출할 때, shared_ptr 객체를 넘기기 때문에 복사가 한 번 발생하고 이때, shared_ptr의 복사 생성자가 수행되면서 내부적으로 reference count를 증가시키고, 다시 함수에서 리턴될 때, reference count를 감소시키게 됩니다. 그리고 reference count 증가 및 감소는 보통 atomic operation으로 수행되기 때문에 보통의 증가/감소보다는 속도가 느린 걸로 알고 있습니다.&lt;br /&gt;
&lt;br /&gt;
이 세가지에 대해 컴파일러 최적화 옵션 및 BOOST 옵션을 약간 달리 하면서 실행을 해 보았습니다. 다음은 테스트를 위한 Makefile 입니다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;$ cat Makefile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;all: shared1 shared2 shared3 shared_copy1 shared_copy2 shared_copy3 plain1 plain2 plain3&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#CFLAGS=-pg -g&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;#LDFLAGS=-pg -g&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;# CASE #1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;CFLAGS1=&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;# CASE #2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;CFLAGS2=-O3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;# CASE #3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;CFLAGS3=-O3 -DBOOST_SP_DISABLE_THREADS&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;LDFLAGS=&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared1: shared1.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o shared1 shared1.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared_copy1: shared_copy1.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o shared_copy1 shared_copy1.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain1: plain1.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o plain1 plain1.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared1.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS1) -c -o shared1.o -DSHARED_PTR shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared_copy1.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS1) -c -o shared_copy1.o -DSHARED_PTR_COPY shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain1.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS1) -c -o plain1.o -DPLAIN shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared2: shared2.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o shared2 shared2.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared_copy2: shared_copy2.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o shared_copy2 shared_copy2.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain2: plain2.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o plain2 plain2.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared2.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS2) -c -o shared2.o -DSHARED_PTR shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared_copy2.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS2) -c -o shared_copy2.o -DSHARED_PTR_COPY shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain2.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS2) -c -o plain2.o -DPLAIN shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared3: shared3.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o shared3 shared3.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared_copy3: shared_copy3.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o shared_copy3 shared_copy3.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain3: plain3.o&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(LDFLAGS) -o plain3 plain3.o&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared3.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS3) -c -o shared3.o -DSHARED_PTR shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared_copy3.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS3) -c -o shared_copy3.o -DSHARED_PTR_COPY shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain3.o: shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g++ $(CFLAGS3) -c -o plain3.o -DPLAIN shared.cpp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;test: test1 test2 test3&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;test1: shared1_test shared1_copy_test plain1_test&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared1_test: shared1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./shared1 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared1_copy_test: shared_copy1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./shared_copy1 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain1_test: plain1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./plain1 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;test2: shared2_test shared2_copy_test plain2_test&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared2_test: shared2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./shared2 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared2_copy_test: shared_copy2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./shared_copy2 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain2_test: plain2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./plain2 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;test3: shared3_test shared3_copy_test plain3_test&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared3_test: shared3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./shared3 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;shared3_copy_test: shared_copy3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./shared_copy3 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;plain3_test: plain3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; time ./plain3 $(CNT)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;clean:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rm -rf *.o *.dSYM shared1 shared2 shared3 shared_copy1 shared_copy2 shared_copy3 plain1 plain2 plain3 core* gmon.*&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
1. 테스트 케이스 1: 컴파일러 옵션으로 아무것도 주지 않을 경우 --&amp;gt; CFLGAS1 사용&lt;br /&gt;
2. 테스트 케이스 2: 컴파일러 옵션으로 -O3 를 준 경우 --&amp;gt; CFLAGS2 사용&lt;br /&gt;
3. 테스트 케이스 3: 컴파일러 옵션으로 -O3 -DBOOST_SP_DISABLE_THREADS 사용. BOOST_SP_DISABLE_THREADS를 켜면 reference count 값을 변경시킬 때, atomic operation을 사용하지 않게 됩니다.&lt;br /&gt;
&lt;br /&gt;
이렇게 테스트 프로그램을 작성하고, 테스트를 해 봤더니 다음과 같은 결과가 나오더군요.&lt;br /&gt;
&lt;br /&gt;
$ make&lt;br /&gt;
$ make test&lt;br /&gt;
time ./shared1 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15.66 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15.52 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.04 sys&lt;br /&gt;
time ./shared_copy1 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 93.33 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 92.58 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.24 sys&lt;br /&gt;
time ./plain1 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8.54 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8.48 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.02 sys&lt;br /&gt;
time ./shared2 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.81 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.79 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.00 sys&lt;br /&gt;
time ./shared_copy2 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 37.86 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 37.62 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.08 sys&lt;br /&gt;
time ./plain2 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.66 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.66 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.00 sys&lt;br /&gt;
time ./shared3 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.84 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.79 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.00 sys&lt;br /&gt;
time ./shared_copy3 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.74 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.70 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.01 sys&lt;br /&gt;
time ./plain3 1000000000&lt;br /&gt;
1000000000&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.66 real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.66 user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.00 sys&lt;br /&gt;
&lt;br /&gt;
(위 테스트는 looping overhead, function call overhead 를 정확히 측정하지 않았기 때문에 아주 정확한 수치라고는 주장할 수 없음을 미리 밝힙니다. 정확한 수치를 알아내기 위해서는 좀 더 잘 설계된 테스트 케이스를 사용해야 할 것입니다. 다만 위 테스트 결과를 사용하더라도 이 글에서 주장하고자 하는 바를 위한 충분한 근거가 되리라고 생각합니다.)&lt;br /&gt;
&lt;br /&gt;
우선 테스트 케이스1와 테스트 케이스2, 테스트 케이스 3에서 공히 shared_copy &amp;gt; shared &amp;gt; plain 결과가 나온다는 걸 확인할 수 있습니다. BOOST_SP_DISABLE_THREADS 를 켜게 되면 shared_copy에만 영향을 미친다는 걸 알 수 있습니다. 이건 아까 말씀드린 대로 atomic operation이 disable되기 때문인 것으로 추측됩니다. 이상 결과로 보건대 shared_ptr을 쓰실 때는 다음과 같은 점에 유의하셔야 할 것 같습니다.&lt;br /&gt;
&lt;br /&gt;
1.&amp;nbsp; No free lunch. 좋은 게 있으면 그에 대한 비용이 있기 마련이라는 것이죠. shared_ptr는 일반 포인터에 비해 overhead가 있다는 점을 염두해 두셔야겠습니다.&lt;br /&gt;
2. 단순 접근하는 overhead도 2.81/0.66(테스트 케이스 2)으로 상당합니다.&lt;br /&gt;
3. 복사 생성자 overhead는 37.86/0.66(테스트 케이스 2)으로 더 크다는 것을 확인할 수 있습니다. BOOST_SP_DISABLE_THREADS를 켜더라도 5.74/0.66으로 여전히 크다는 것을 알 수 있습니다. 따라서 될 수 있으면 복사를 shared_ptr도 복사는 피하셔야 하겠습니다.&lt;br /&gt;
&lt;br /&gt;
제가 테스트한 환경은 다음과 같습니다.&lt;br /&gt;
&lt;br /&gt;
$ uname -a&lt;br /&gt;
Darwin MyMac.local 9.7.0 Darwin Kernel Version 9.7.0: Tue Mar 31 22:52:17 PDT 2009; root:xnu-1228.12.14~1/RELEASE_I386 i386&lt;br /&gt;
$ g++ --version&lt;br /&gt;
i686-apple-darwin9-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5564)&lt;br /&gt;
&lt;br /&gt;
여러분 환경에서는 어떤 결과가 나오는지 실험해 보시고, 트랙백 한 번 남겨 주시면 감사하겠습니다. ^^&lt;br /&gt;
&lt;br /&gt;
소스 코드 첨부합니다(looping overhead를 측정하기 위해 본문 소스에서 약간 더 수정했습니다).&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;https://t1.daumcdn.net/cfile/tistory/124D160C4A462A3E54&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://i1.daumcdn.net/cfs.tistory/v/0/blog/image/extension/gz.gif&quot; style=&quot;vertical-align: middle;&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;shared.tar.gz&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <category>boost shared_ptr performance</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/364</guid>
      <comments>https://yesarang.tistory.com/364#entry364comment</comments>
      <pubDate>Sun, 28 Jun 2009 13:44:49 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2009년 1월 22일</title>
      <link>https://yesarang.tistory.com/363</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://me2day.net/kss/2009/01/22#17:07:15'&gt;개발자를 위한 글꼴! 나눔고딕_코딩 글꼴 공개!&lt;/a&gt; 우왕 멋집니다. 감동입니다. 바로 &lt;a href='http://dev.naver.com/projects/nanumfont/download'&gt;다운로드&lt;/a&gt; 들어가야 함다.&lt;span class=&quot;me2_tags&quot;&gt;(네이버 폰트공개 나눔고딕코딩)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2009/01/22#17:41:04&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2009-01-22 17:41:04&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2009/01/22#17:41:04&quot;&gt;2009년 1월 22일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>나눔고딕코딩</category>
      <category>네이버</category>
      <category>폰트공개</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/363</guid>
      <comments>https://yesarang.tistory.com/363#entry363comment</comments>
      <pubDate>Fri, 23 Jan 2009 04:33:07 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2009년 1월 4일</title>
      <link>https://yesarang.tistory.com/362</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;I'm back!&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2009/01/04#01:08:35&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2009-01-04 01:08:35&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2009/01/04#01:08:35&quot;&gt;2009년 1월 4일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/362</guid>
      <comments>https://yesarang.tistory.com/362#entry362comment</comments>
      <pubDate>Tue, 6 Jan 2009 04:34:55 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 12월 24일</title>
      <link>https://yesarang.tistory.com/361</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;Merry Christmas &amp; Happy New Year! 전 11일 장기 휴가 돌입합니다. 저 없는 동안 잘 지내세요~ 인터넷 접속 안하기 한 번 실천해 봐야겠습니다.&lt;span class=&quot;me2_tags&quot;&gt;(인터넷생활)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/24#18:09:36&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-24 18:09:36&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/24#18:09:36&quot;&gt;2008년 12월 24일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>인터넷생활</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/361</guid>
      <comments>https://yesarang.tistory.com/361#entry361comment</comments>
      <pubDate>Thu, 25 Dec 2008 04:32:32 +0900</pubDate>
    </item>
    <item>
      <title>C++이야기 스물아홉번째: Portable C++ Timer Class #2</title>
      <link>https://yesarang.tistory.com/360</link>
      <description>If you are an English speaker, then follow this link.&lt;br /&gt;
&lt;a target=&quot;_blank&quot; href=&quot;http://codeguru.textcube.com/3&quot; title=&quot;Permalink&quot;&gt;C++ Tips 29th: Portable C++ Timer Class #2&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;이번에는 timer 관련 클래스들에 어떤 멤버 함수와 멤버 변수를 정의해야할지에 대해 자세히 알아보겠습니다. 사용자가 가장 많이 사용하게될 클래스는 TimerDriver일테니 이것부터 시작해 보도록 하겠습니다.&lt;br /&gt;
&lt;br /&gt;
저번글에서 말씀드렸던 것처럼 TimerDriver는 &lt;strong&gt;&lt;font color=&quot;#3058d2&quot;&gt;등록된 &lt;/font&gt;&lt;/strong&gt;타이머들이 정확한 시간에 expire되도록 해주는 클래스입니다. 이점을 고려하면 타이머 인스턴스들을 등록하고 등록해제하는 멤버 함수는 누가 봐도 필요할 것 같습니다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver {&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;public:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; TimerId RegisterTimer(const Timer&amp;amp; t);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void UnregisterTimer(TimerId tid);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
이 인터페이스를 정의하고 나면 등록된 타이머 인스턴스들을 저장해 놓을 저장 공간이 필요하다는 걸 금방 알게 됩니다. 그럼 어떤 데이터 구조가 저장 공간으로 적당할까요? 가장 적당한 데이터 구조를 택하려면 아무래도 사용자가 TimerDriver를 사용하는 패턴을 먼저 알아야 할 것 같습니다.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;지금까지 정의한 멤버 함수는 RegisterTimer(), UnregisterTimer() 두 개가 있고, 이 둘은 결국 &lt;span style=&quot;color: rgb(48, 88, 210); font-weight: bold;&quot;&gt;삽입과 삭제&lt;/span&gt;에 해당합니다. 그리고 타이머 인스턴스들 &lt;span style=&quot;color: rgb(48, 88, 210); font-weight: bold;&quot;&gt;하나 하나를 건드리면서&lt;/span&gt; 드라이브 할 수 있습니다. 그렇지만 사용자가 정렬된 타이머 리스트를 필요로 하거나, 타이머 인스턴스를 직접 접근하거나, 타이머 인스턴스를 상당히 빠르게 검색해야할 필요성은 없을 것입니다.&lt;/p&gt;
&lt;p&gt;그래서 저는 std::list가 등록된 타이머 인스턴스 저장 데이터 구조로 가장 적당하다고 생각합니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-weight: bold; color: rgb(0, 47, 255); font-family: courier new,courier,monospace;&quot;&gt;#include &amp;lt;list&amp;gt;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class Timer;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver {&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;public:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; TimerId RegisterTimer(const Timer&amp;amp; t);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void UnregisterTimer(TimerId tid);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;private:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: rgb(0, 47, 255); font-family: courier new,courier,monospace;&quot;&gt;std::list&amp;lt;Timer&amp;gt; timer_list_;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;다음으로 RegisterTimer() 와 UnregisterTimer()의 입력 인자와 리턴값에 대해 생각해 보겠습니다.&lt;/p&gt;
&lt;p&gt;제가 RegisterTimer()의 리턴값과 UnregisterTimer()의 입력인자로 TimerId라는 타입을 도입했습니다. 'TimerId' 타입의 필요성은 분명해 보이는데... 어떤식으로 'TimerId' 타입을 정의해야할까요? TimerDriver가 내부적으로 식별자 풀(identifier pool)을 관리해야할까요 아니면 TimerId가 그냥 Timer*이면 될까요? 식별자 풀을 관리한다면 각 타이머 인스턴스에 할당된 식별자는 어디에 저장해야할까요? timer_list_는 list&amp;lt;Timer&amp;gt;라고 선언해도 무방할까요 아니면 다른 뭔가로 선언해야할까요? 예를 들어, list&amp;lt;Timer*&amp;gt;와 같이 말이죠. 우리가 결론에 도달할 때까지는 이런 수 많은 질문들이 머리속을 맴돌게 됩니다. 혼란 그 자체죠? 이런 간단한 클래스를 설계하는데도 말입니다.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;그렇지만, 소프트웨어 개발자로서 선택에 대한 분명한 이유를 찾아가며 이런 혼란스러움을 해결해 가야 합니다. 삶이란 게 문제로 가득차 있고, 산다는 것 자체가 해답을 찾아가는 과정 아닐까요? 그러니 너무 괴로워하지 마시고 맘을 가다듬어 보시죠. 사실 이 모든 문제들이 서로 연결되어 있습니다. 한 문제에 대한 해결책을 찾게 되면... 짠! 하고 다른 모든 문제들에 대한 해결책도 찾을 수 있게 될테니까요.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;그럼 문제점을 하나씩 해결해 보시죠. 숨을 기~~~~~~~~~~~~~피 들이 쉬시고~~~&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;TimerId! TimerDriver가 식별자 풀을 관리해야할까요? 가능한 해결책이죠. 사용자가 RegisterTimer()를 호출하여 타이머 인스턴스를 등록해달라고 하면 TimerDriver가 식별자 풀에서 할당되지 않은 ID를 새로 등록할 타이머 인스턴스에 할당할 수 있을 것입니다. 그리고, 나중에 UnregisterTimer()를 호출했을 때, 삭제하려면 할당된 그 ID를 어딘가에 저장해야 합니다.&lt;/p&gt;
&lt;p&gt;그런데 저는 정말 식별자 풀을 관리하고 싶지는 않네요. 현재 요구사항에 비해 너무 복잡한 해결책이거든요. 저는 간단한 해결책을 훨씬 선호합니다. 그렇게 하면 코드량도 적어지고, 버그고 적어질 테니까요. 그래서 식별자 풀은 설계 대안에서 제외하기로 했습니다. 그럼 다른 대안이 있을까요? TimerId를 그냥 Timer*로 선언하면 어떨까요?&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;#include &amp;lt;list&amp;gt;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class Timer;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;color: rgb(0, 47, 255); font-weight: bold; font-family: courier new,courier,monospace;&quot;&gt;typedef Timer* TimerId;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver {&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;public:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;font-weight: bold; color: rgb(0, 47, 255);&quot; class=&quot;copyAngel_codeguru_LinkUp&quot; original=&quot;http://codeguru.textcube.com/3&quot; entryid=&quot;3&quot;&gt;TimerId&lt;span class=&quot;copyAngel_codeguru_LinkUp_local&quot; style=&quot;display: none;&quot;&gt;TimerId&lt;/span&gt;&lt;/span&gt;

 RegisterTimer(const Timer&amp;amp; t);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void UnregisterTimer(TimerId tid);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;private:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; std::list&amp;lt;Timer&amp;gt; timer_list_;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이렇게 하면 식별자 풀을 관리하지 않아도 되고, RegisterTimer() 는 리턴값으로 &amp;amp;t를 리턴하면 되니 구현이 간단해 질 것입니다. 그럼, 거의 완벽한 해결책을 찾은 거네요. 그죠? 워!워!워! 그렇게 쉽게 해결될 리가 있나요. 조금만 더 깊이 생각해 보시죠.&lt;/p&gt;
&lt;p&gt;그냥 TimerId를 Timer*로 선언하게 되면 타이머 인스턴스의 내부 표현 방식을 사용자가 직접 다루게 되고, 결국 이것은 encapsulation rule을 위배하게 됩니다. 그렇게 할 경우, TimerDriver가 타이머 인스턴스 내부 표현 방식을 바꾸게 되면 TimerId가 Timer*라는 거를 가정하고 짠 사용자 코드는 다 작동하지 않게 될 것입니다. 그래서 저는 TimerId를 그냥 void*로 선언하려고 합니다. 그럼 사용자는 타미어 인스턴스 내부 표현 방식이 어떻게 되는지 전혀 알 수가 없겠지요.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;#include &amp;lt;list&amp;gt;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class Timer;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;color: rgb(0, 47, 255); font-weight: bold; font-family: courier new,courier,monospace;&quot;&gt;typedef void* TimerId;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver {&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;public:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; TimerId RegisterTimer(const Timer&amp;amp; t);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void UnregisterTimer(TimerId tid);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;private:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; std::list&amp;lt;Timer&amp;gt; timer_list_;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;다음으로는 timer_list_ 멤버 변수에 대해 생각해 보겠습니다. 저번 글에서 밝혔다시피 저는 Timer에서 상속받은 PeriodicTimer와 OneShotTimer를 정의하려고 합니다. Timer에는 공통의 인터페이스만 정의하고 PeriodicTimer 와 OneShotTimer에서 그걸 구현하여 &lt;span style=&quot;color: rgb(48, 88, 210); font-weight: bold;&quot;&gt;다형성&lt;/span&gt;을 보이게 하려는 것이지요. 그렇다면 timer_list_를 list&amp;lt;Timer*&amp;gt;로 선언해야 할 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;#include &amp;lt;list&amp;gt;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class Timer;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;typedef void* TimerId;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver {&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;public:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; TimerId RegisterTimer(const Timer&amp;amp; t);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void UnregisterTimer(TimerId tid);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;private:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 47, 255); font-weight: bold; font-family: courier new,courier,monospace;&quot;&gt;std::list&amp;lt;Timer*&amp;gt; timer_list_;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;현재 TimerDriver 인터페이스에는 한 가지 멤버 함수가 빠진 것 같습니다. 보통 사용자는 먼저 타이머들을 등록한 후에 타이머들을 돌리기 시작하겠죠? 그래서 다음과 같이 Run() 멤버 함수를 추가했습니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;#include &amp;lt;list&amp;gt;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class Timer;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;typedef void* TimerId;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver {&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;public:&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;copyAngel_codeguru_LinkUp&quot; original=&quot;http://codeguru.textcube.com/3&quot; entryid=&quot;3&quot;&gt;TimerId&lt;span class=&quot;copyAngel_codeguru_LinkUp_local&quot; style=&quot;display: none;&quot;&gt;TimerId&lt;/span&gt;&lt;/span&gt;

 RegisterTimer(const Timer&amp;amp; t);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void UnregisterTimer(TimerId tid);&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 47, 255); font-weight: bold; font-family: courier new,courier,monospace;&quot;&gt;void Run();&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span class=&quot;copyAngel_codeguru_LinkUp&quot; original=&quot;http://codeguru.textcube.com/3&quot; entryid=&quot;3&quot;&gt;private:&lt;span class=&quot;copyAngel_codeguru_LinkUp_local&quot; style=&quot;display: none;&quot;&gt;private:&lt;/span&gt;&lt;/span&gt;

&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; std::list&amp;lt;Timer*&amp;gt; timer_list_;&lt;/span&gt;&lt;br style=&quot;font-family: courier new,courier,monospace;&quot;&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이제, 이 정도면 TimerDriver의 인터페이스는 거의 완벽하다고 느껴지네요. 다음글에서 TimerDriver의 구현에 대해 다뤄보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/360</guid>
      <comments>https://yesarang.tistory.com/360#entry360comment</comments>
      <pubDate>Mon, 22 Dec 2008 22:35:29 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 12월 20일</title>
      <link>https://yesarang.tistory.com/359</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;영문 블로그 세번째 글: &lt;a href='http://codeguru.textcube.com/3'&gt;C++ Tips 29th: Portable C++ Timer Class #2&lt;/a&gt;, &lt;a href='http://codeguru.textcube.com/3'&gt;지난 글&lt;/a&gt;을 안 보신 분은 먼저 읽어보시는 센스를 발휘해 주세요&lt;span class=&quot;me2_tags&quot;&gt;(블로그 영문)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/20#22:20:11&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-20 22:20:11&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/20#22:20:11&quot;&gt;2008년 12월 20일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>블로그</category>
      <category>영문</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/359</guid>
      <comments>https://yesarang.tistory.com/359#entry359comment</comments>
      <pubDate>Sun, 21 Dec 2008 05:18:08 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 12월 18일</title>
      <link>https://yesarang.tistory.com/358</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;한 동안 블로그에 글 못 올릴 것 같습니다. 양해 바랍니다.&lt;span class=&quot;me2_tags&quot;&gt;(블로그 휴업)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/18#22:33:52&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-18 22:33:52&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/18#22:33:52&quot;&gt;2008년 12월 18일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>블로그</category>
      <category>휴업</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/358</guid>
      <comments>https://yesarang.tistory.com/358#entry358comment</comments>
      <pubDate>Fri, 19 Dec 2008 04:32:33 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 12월 9일</title>
      <link>https://yesarang.tistory.com/357</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.ddj.com/hpc-high-performance-computing/212201163'&gt;Measuring Parallel Performance: Optimizing a Concurrent Queue&lt;/a&gt;: 나중에 꼭 읽어 봐야 겠습니다.&lt;span class=&quot;me2_tags&quot;&gt;(인터넷오늘은 북마크 SW개발 hpc thread)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/09#00:19:02&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-09 00:19:02&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/09#00:19:02&quot;&gt;2008년 12월 9일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>HPC</category>
      <category>sw개발</category>
      <category>thread</category>
      <category>북마크</category>
      <category>인터넷오늘은</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/357</guid>
      <comments>https://yesarang.tistory.com/357#entry357comment</comments>
      <pubDate>Tue, 9 Dec 2008 04:32:30 +0900</pubDate>
    </item>
    <item>
      <title>C++이야기 스물아홉번째: Portable C++ Timer Class #1</title>
      <link>https://yesarang.tistory.com/356</link>
      <description>If you are an English speaker, then follow this link.&lt;br /&gt;
&lt;a target=&quot;_blank&quot; href=&quot;http://codeguru.textcube.com/2&quot; title=&quot;Permalink&quot;&gt;C++ Tips 29th: Portable C++ Timer Class #1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
우리네 생활이 온통 시간에 둘러쌓여 있듯이, 응용프로그램부터 펌웨어에 이르는 프로그램도 시간에 둘러쌓여 있지요. 예를 들자면, 달력 프로그램은 시간과 연관되어 있는 약속과 할일들을 처리하고, 검색 로봇은 주기적으로 페이지를 긁어 오고, 멀티미디어 재생기는 제 시간에 맞춰서 데이터 저장소로부터 열심히 데이터를 끌어 오고, TCP/IP 위에서 동작하는 통신 미들웨어는 데이터 교환이나 요청한 연산에 대해 타임아웃을 처리하고, 디바이스 드라이버는 주기적으로 디바이스에 상태 체크 요청을 보냅니다.
이렇게 시간은 워낙 근본적인 개념이라 아주 작은 프로그램을 개발하는 경우를 제외한다면 대부분 타임아웃이나 주기적인 이벤트를 처리할 수 있는 라이브러리가 필요하게 됩니다.&lt;br /&gt;
&lt;br /&gt;
그래서 이번과 앞으로 몇 번에 걸쳐 boost 라이브러리를 활용하여 타임아웃이나 주기적인 이벤트를 처리할 수 있는 타이머 클래스를 구현하는 방법에 대해 얘기하려고 합니다.&lt;br /&gt;
&lt;br /&gt;
타이머와 연관된 기본적인 개념을 먼저 한 번 생각해 보죠.
&lt;ol&gt;
&lt;li&gt;타이밍 이벤트는 주기적으로 발생하거나 딱 한 번만 발생한다.&lt;/li&gt;
&lt;li&gt;타이밍 이벤트가 발생하면 특정 작업을 처리해야 한다.&lt;/li&gt;
&lt;li&gt;정확한 시간에 타이밍 이벤트가 발생하도록 해주는 일종의 구동기가 존재한다.&lt;/li&gt;
&lt;/ol&gt;
저는 이 정도 개념이 우선 떠오르네요.&lt;br /&gt;
&lt;br /&gt;
그럼 먼저 첫번째 개념에서 어떤 클래스를 정의해야 하는지부터 시작해 볼까요? 다음과 같이 enum 값들로 두 가지 타입을 다 지원하는 클래스 하나를 정의할 수도 있을 겁니다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;
class Timer {&lt;br /&gt;
public:&lt;br /&gt;
&amp;nbsp; typedef enum {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; PERIODIC_TIMER,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ONE_SHOT_TIMER&lt;br /&gt;
&amp;nbsp; } Type;&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
&amp;nbsp; Type m_type;&lt;br /&gt;
};&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
서로 다른 두 개념을 클래스 하나로 묶어 놓은 설계가 과연 좋은 설계일까요? 좀 더 주의깊게 생각해 보시죠. 이 설계대로 하면 생성자는 어떻게 작성해야 할까요?

&lt;p&gt;&lt;span style=&quot;font-family: courier new,courier,monospace;&quot;&gt;#include &amp;lt;boost/date_time.hpp&amp;gt; // for time_duration&lt;br /&gt;
&lt;br /&gt;
class Timer {&lt;br /&gt;
public:&lt;br /&gt;
&amp;nbsp; typedef enum {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; PERIODIC_TIMER,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ONE_SHOT_TIMER&lt;br /&gt;
&amp;nbsp; } Type;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;font-weight: bold; color: rgb(0, 30, 161);&quot;&gt;Timer(Type type, const boost::posix_time::time_duration&amp;amp; td);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
&amp;nbsp; Type m_type;&lt;br /&gt;
};&lt;/span&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;'type' 인자의 의미는 분명하지만, 'td' 인자는 어떤 것을 뜻할까요? 보통 주기적인 이벤트는 주기(== 'td')라는 게 필요하고, 타임아웃 이벤트는 그 이벤트가 발생할 시간(== 현재 시간 + 'td')을 필요로 할테니... 'td' 인자가 뜻하는 바는 'type'에 따라 달라지겠죠? 그렇다면,&amp;nbsp; Timer::Timer() 을 구현한 코드가 아무래도 다음 코드에서 보시는 것처럼 'type' 값에 의존적인 코드가 될 것 같군요.&lt;/p&gt;
&lt;p style=&quot;font-family: courier new,courier,monospace;&quot;&gt;Timer::Timer(Type type, const boost::posix_time::time_duration&amp;amp; td)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; switch (type)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp; case PERIODIC_TIMER:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ......&lt;br /&gt;
&amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; case ONE_SHOT_TIMER:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ......&lt;br /&gt;
&amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; default:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;이렇게 되면 새로운 타입의 타이머를 추가할 때마다 이 생성자를 수정해야할 필요가 있다는 건 쉽게 눈치 채실 수 있으시겠죠? 상당히 심각한 유지보수 문제네요. 이것 말고도 다른 문제점들도 있습니다. 세번째 개념에서 드라이버 클래스를 정의할 필요성이 있다는 걸 알 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;font-family: courier new,courier,monospace;&quot;&gt;class TimerDriver { ...... };&lt;/p&gt;
&lt;p&gt;TimerDriver가 서로 다른 타입의 타이머 인스턴스들을 제대로 처리하려면 타이머의 타입을 알아야할 것입니다. 그러니 TimerDriver의 구동 멤버 함수는 당연히 타이머의 타입 정보를 필요로 하게 됩니다. 생각이 여기에 이르면 새로운 타입의 타이머를 추가할 때마다 TimerDriver의 구동 멤버 함수도 수정해야 한다는 걸 알 수 있게 됩니다.&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;마지막 문제점으로 주기적인 이벤트는 주기를 저장해야 할테고, 타임아웃 이벤트는 이벤트가 발생해야할 시간을 저장해야 한다는 점이 떠오르네요. 이걸 저장하기 위해 하나의 클래스에 두 개의 멤버 변수를 정의한다면 타이머 인스턴스의 타입에 따라서 낭비되는 공간이 생길 것입니다.&lt;/p&gt;

&lt;p&gt;이상의 문제점을 고려해 보건데, 주기적인 이벤트와 타임아웃 이벤트를 위해 따로 클래스를 정의하는 게 더 좋은 설계라는 게 명백해 보입니다. 그렇지만 한편으로는 TimerDriver는 여전히 이 클래스들을 일관되게 처리할 필요가 있을 것입니다. 따라서 저는 공통의 부모 클래스로 Timer를 두고, 파생 클래스로 PeriodicTimer와 OneShotTimer를 두려고 합니다.&lt;/p&gt;

&lt;p style=&quot;font-family: courier new,courier,monospace; font-weight: bold; color: rgb(0, 30, 161);&quot;&gt;class Timer { ...... };&lt;/p&gt;

&lt;p style=&quot;font-family: courier new,courier,monospace; font-weight: bold; color: rgb(0, 30, 161);&quot;&gt;class PeriodicTimer : public Timer { ...... };&lt;/p&gt;
&lt;p style=&quot;font-family: courier new,courier,monospace; font-weight: bold; color: rgb(0, 30, 161);&quot;&gt;class OneShotTimer : public Timer { ...... };&lt;/p&gt;

그럼 이제 Timer, PeriodicTimer, OneShotTimer 각각 클래스에는 어떤 것들을 정의해야 할까요? 이 문제는 다음 글에서 알아보도록 하겠습니다. ^^&lt;br /&gt;
&lt;br /&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/356</guid>
      <comments>https://yesarang.tistory.com/356#entry356comment</comments>
      <pubDate>Mon, 8 Dec 2008 22:37:17 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 12월 7일</title>
      <link>https://yesarang.tistory.com/355</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://codeguru.textcube.com/2'&gt;C++ Tips 29th: Portable C++ Timer Class #1&lt;/a&gt;: 영어 블로그 두번째 글입니다. Wordpress가 너무 꼬져서 textcube.com 으로 옮겨 봤습니다. 일단 tistory랑 비슷해서 편하네요. 이번에는 영문으로 먼저 작성했습니다.&lt;span class=&quot;me2_tags&quot;&gt;(블로그 영문)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/07#22:47:34&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-07 22:47:34&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/07#22:47:34&quot;&gt;2008년 12월 7일&lt;/a&gt;의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>블로그</category>
      <category>영문</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/355</guid>
      <comments>https://yesarang.tistory.com/355#entry355comment</comments>
      <pubDate>Mon, 8 Dec 2008 04:32:09 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 12월 3일</title>
      <link>https://yesarang.tistory.com/354</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=OCl3M5grVF4'&gt;샴페인-박준규-흑인영어&lt;/a&gt;: ㅋㅋㅋ 배꼽 빠져&lt;span class=&quot;me2_tags&quot;&gt;(me2gag)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/02#15:35:41&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-02 15:35:41&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='http://kr.finance.yahoo.com/news/view?aid=2008120213091740180'&gt;이 기사&lt;/a&gt; 말이 되는 듯… 뭐 꼭 근거가 있는 건 아니고 그냥 느낌이 그렇다는 얘기&lt;span class=&quot;me2_tags&quot;&gt;(투자생활 그나저나 예상대로 얼마전 반등은 단기 반등이었을 뿐 언론들은 제발 호들갑 떨지 말아라)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/03#00:35:04&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-03 00:35:04&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;제가 요즘 관심을 두는 주식들: &lt;a href='http://kr.stock.yahoo.com/sise/st01.html?code=005490'&gt;POSCO&lt;/a&gt;, &lt;a href='http://kr.stock.yahoo.com/sise/st01.html?code=072870'&gt;메가스터디&lt;/a&gt;, &lt;a href='http://kr.stock.yahoo.com/sise/st01.html?code=046890'&gt;서울반도체&lt;/a&gt;, &lt;a href='http://kr.stock.yahoo.com/sise/st01.html?code=066570'&gt;LG전자&lt;/a&gt; 등 입니다.&lt;span class=&quot;me2_tags&quot;&gt;(투자생활)&lt;/span&gt;&lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/12/03#00:47:23&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-12-03 00:47:23&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/02#15:35:41&quot;&gt;2008년 12월 2일&lt;/a&gt;에서 &lt;a href=&quot;http://me2day.net/yesarang/2008/12/03#00:47:23&quot;&gt;2008년 12월 3일&lt;/a&gt;까지의 미투데이 내용입니다.&lt;/p&gt;&lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>me2gag</category>
      <category>그나저나</category>
      <category>단기</category>
      <category>떨지</category>
      <category>말아라</category>
      <category>반등은</category>
      <category>반등이었을</category>
      <category>뿐</category>
      <category>언론들은</category>
      <category>얼마전</category>
      <category>예상대로</category>
      <category>제발</category>
      <category>투자생활</category>
      <category>호들갑</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/354</guid>
      <comments>https://yesarang.tistory.com/354#entry354comment</comments>
      <pubDate>Wed, 3 Dec 2008 04:32:31 +0900</pubDate>
    </item>
    <item>
      <title>티스토리 달력 공모전 응모</title>
      <link>https://yesarang.tistory.com/353</link>
      <description>음... 올해 있었던 추억을 담아 응모해 봅니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs13/6_tistory_2008_12_03_01_25_4935618a1164e?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs13%2F6_tistory_2008_12_03_01_25_4935618a1164e%3Foriginal&quot; width=&quot;510&quot; height=&quot;383&quot; alt=&quot;&quot; filename=&quot;IMG_6180.JPG&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
여름에 아이들과 함께 동네 야외 수영장 갔을 때 찍었던 사진입니다. 오빠와 동생이 함께 노는 모습이 보기 좋아서 선정해 봤습니다. 7월 사진으로 적당할 것 같네요.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs12/1_tistory_2008_12_03_01_32_4935631b65928?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs12%2F1_tistory_2008_12_03_01_32_4935631b65928%3Foriginal&quot; width=&quot;510&quot; height=&quot;383&quot; alt=&quot;&quot; filename=&quot;IMG_6381.JPG&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
위 사진은 대관령 양떼 목장에 갔을 때 찍은 하늘 사진입니다. 날씨가 아주 맑은 날이어서 하늘이 너무 멋있어 보이더군요. 9월 사진으로 적당할 것 같네요.&lt;br /&gt;
&lt;br /&gt;
그리고 하늘의 구름과 땅의 양떼가 어우러진 이 사진도 좋은 것 같습니다. 마찬가지로 9월이 적당할 것 같네요.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs14/33_tistory_2008_12_03_01_35_493563de84443?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs14%2F33_tistory_2008_12_03_01_35_493563de84443%3Foriginal&quot; width=&quot;510&quot; height=&quot;301&quot; alt=&quot;&quot; filename=&quot;IMG_6409.JPG&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;</description>
      <category>기타</category>
      <category>7월</category>
      <category>9월</category>
      <category>사진</category>
      <category>티스토리달력</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/353</guid>
      <comments>https://yesarang.tistory.com/353#entry353comment</comments>
      <pubDate>Wed, 3 Dec 2008 01:36:57 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 11월 30일</title>
      <link>https://yesarang.tistory.com/352</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;
    &lt;ul&gt; 
      &lt;li&gt;
        &lt;a href='http://yesarang.wordpress.com/2008/11/24/cpp-tips-28/'&gt;C++ Tips 28th: Applying STL Algorithms to a Map Container&lt;/a&gt;: It's not that easy to translate a post in Korean to English.
        &lt;span class=&quot;me2_tags&quot;&gt;(블로그 영문 첫글)&lt;/span&gt;
        &lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/11/30#20:22:15&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-11-30 20:22:15&lt;/a&gt;&lt;/span&gt;
        
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;
      이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 
      &lt;a href=&quot;http://me2day.net/yesarang/2008/11/30#20:22:15&quot;&gt;2008년 11월 30일&lt;/a&gt;의 
      미투데이 내용입니다.
    &lt;/p&gt;
  &lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>블로그</category>
      <category>영문</category>
      <category>첫글</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/352</guid>
      <comments>https://yesarang.tistory.com/352#entry352comment</comments>
      <pubDate>Mon, 1 Dec 2008 04:32:18 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 11월 28일</title>
      <link>https://yesarang.tistory.com/351</link>
      <description>&lt;DIV class=me2day_daily_digest&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.etnews.co.kr/news/detail.html?id=200811170181&amp;amp;mc=m_012_00005&quot;&gt;스마트폰이 노트북 밀어낸다&lt;/A&gt;: 스마트폰 세상이 오고 있군요. 무선 인터넷 세상도 같이 와야 할텐데 말이죠. &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 스마트폰)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/27#23:15:03&quot; rel=bookmark&gt;2008-11-27 23:15:03&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.ktwb.co.kr/sub04_u2000.htm&quot;&gt;맥용 와이브로 USB 모뎀&lt;/A&gt;이 있었군요 &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 와이브로 맥)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/27#23:28:43&quot; rel=bookmark&gt;2008-11-27 23:28:43&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://kr.finance.yahoo.com/news/view?aid=2008112716291490525&quot;&gt;다음, 부동산정보도 네이버 제쳤다&lt;/A&gt;: 다음이 만년 2등에서 벗어날 수 있을까요? 지금은 너무 많이 차이가 나서… 다음이 좀 더 잘해준다면 선의의 경쟁이 될 수 있을텐데요 &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 다음 전 네이버와 다음의 주주예요 ^^)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/27#23:38:11&quot; rel=bookmark&gt;2008-11-27 23:38:11&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://kr.finance.yahoo.com/news/view?aid=2008112715261127914&quot;&gt;상장사 3분기 누적수출 224조, 25.5%↑&lt;/A&gt;: 환율의 영향이 크긴 컷었나 보군요. 예상되는 바였습니다. 좀 더 지나면 환율 영향은 사라지고 글로벌 경기 침체 영향으로 수출이 줄어들지 않을까 걱정되네요. &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 수출 경제)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/27#23:43:17&quot; rel=bookmark&gt;2008-11-27 23:43:17&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://kr.finance.yahoo.com/news/view?aid=2008112717052232014&amp;amp;cate=1000&quot;&gt;[내일의전략]산타랠리 기대해도 좋다&lt;/A&gt;: 단기 랠리에 그칠 것 같은데, 언론사들 항상 김치국부터 마신다 &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 경제 주식시장)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/27#23:51:20&quot; rel=bookmark&gt;2008-11-27 23:51:20&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://media.daum.net/digital/view.html?cateid=1008&amp;amp;newsid=20081127083313615&amp;amp;p=etimesi&quot;&gt;삼성서버엔 삼성SSD가 없다&lt;/A&gt;: 이 기사는 삼성전자 내부 사정을 모르는 기자가 작성한 듯. 작년에도 삼성전자 반도체 사업부가 자사 휴대폰 사업부보다 애플에 더 싼 값에 플래스 메모리를 공급했다는 걸 아시는지 모르시는지… &lt;SPAN class=me2_tags&gt;(인터넷오늘은 뉴스 삼성전자)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/28#00:00:18&quot; rel=bookmark&gt;2008-11-28 00:00:18&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://media.daum.net/digital/others/view.html?cateid=100031&amp;amp;newsid=20081127111805296&amp;amp;p=inews24&quot;&gt;'마이너리티 리포트' 컴퓨터 기술, 현실화된다&lt;/A&gt;: 이거 제품으로 나오면 꼭 사고 싶네요. 2~3년내 상품화 목표래요. &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 뉴스 HCI)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/28#00:08:49&quot; rel=bookmark&gt;2008-11-28 00:08:49&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.zdnet.co.kr/news/internet/search/0,39031339,39175637,00.htm&quot;&gt;한국판 '구글맵스' 흥행 성공할까?&lt;/A&gt;: 이런 소식을 이제서야 접하다니… 쩝~ 옛날에 구글이 한국 관련 데이터가 너무 부족하다고 1년전에 글을 썼었는데… 이제서야 데이터를 확보한건지 아니면 규제문제 때문이었는지… 아무튼 환영~ &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 뉴스 구글맵스 한국)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/28#00:17:07&quot; rel=bookmark&gt;2008-11-28 00:17:07&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.zdnet.co.kr/news/enterprise/0,39031021,39175741,00.htm&quot;&gt;DB도 토종 오픈소스 가능한가?…큐브리드의 대담한 도전&lt;/A&gt;: 다른 건 몰라도 License는 정말 잘 정했다. GPL과 BSD의 절묘한 조합이라고 해야겠네. 기술과 법을 다 잘 이해해야만 정할 수 있는 정책이다. &lt;SPAN class=me2_tags&gt;(인터넷오늘은 북마크 뉴스 오픈소스)&lt;/SPAN&gt; &lt;SPAN class=datetime&gt;&lt;A class=datetime title=퍼머링크 href=&quot;http://me2day.net/yesarang/2008/11/28#00:31:33&quot; rel=bookmark&gt;2008-11-28 00:31:33&lt;/A&gt;&lt;/SPAN&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P style=&quot;PADDING-RIGHT: 25px; FONT-SIZE: 0.9em; BACKGROUND: url(http://me2day.net/images/me2day_icon.gif) no-repeat right top; TEXT-ALIGN: right&quot;&gt;이 글은 &lt;A href=&quot;http://me2day.net/yesarang&quot; target=_blank&gt;김윤수&lt;/A&gt;님의 &lt;A href=&quot;http://me2day.net/yesarang/2008/11/27#23:15:03&quot;&gt;2008년 11월 27일&lt;/A&gt;에서 &lt;A href=&quot;http://me2day.net/yesarang/2008/11/28#00:31:33&quot;&gt;2008년 11월 28일&lt;/A&gt;까지의 미투데이 내용입니다. &lt;/P&gt;&lt;/DIV&gt;</description>
      <category>인터넷오늘은</category>
      <category>HCI</category>
      <category>경제</category>
      <category>구글맵스</category>
      <category>네이버와</category>
      <category>뉴스</category>
      <category>다음</category>
      <category>다음의</category>
      <category>맥</category>
      <category>북마크</category>
      <category>삼성전자</category>
      <category>수출</category>
      <category>스마트폰</category>
      <category>오픈소스</category>
      <category>와이브로</category>
      <category>인터넷오늘은</category>
      <category>전</category>
      <category>주식시장</category>
      <category>주주예요</category>
      <category>한국</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/351</guid>
      <comments>https://yesarang.tistory.com/351#entry351comment</comments>
      <pubDate>Fri, 28 Nov 2008 04:32:27 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 11월 27일</title>
      <link>https://yesarang.tistory.com/350</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;
    &lt;ul&gt; 
      &lt;li&gt;
        &lt;a href='http://dev.naver.com/'&gt;Naver Developer Center&lt;/a&gt; 오픈했었군요. 이런 때 늦은 소식 접수라니… 쩝~
        &lt;span class=&quot;me2_tags&quot;&gt;(네이버 개발자 센터 미투뉴스)&lt;/span&gt;
        &lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/11/27#02:00:41&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-11-27 02:00:41&lt;/a&gt;&lt;/span&gt;
        
      &lt;/li&gt;
      &lt;li&gt;
        &lt;a href='http://www.zeroboard.com/'&gt;제로보드 XE&lt;/a&gt;: 나도 내 홈페이지 함 만들어 볼까…
        &lt;span class=&quot;me2_tags&quot;&gt;(인터넷생활 제로보드XE)&lt;/span&gt;
        &lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/11/27#02:32:26&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-11-27 02:32:26&lt;/a&gt;&lt;/span&gt;
        
      &lt;/li&gt;
      &lt;li&gt;
        우선 맥북에 제로보드랑 &lt;a href='http://www.apachefriends.org/en/xampp-macosx.html'&gt;맥용 APM 패키지&lt;/a&gt; 설치해서 써 본 후에 호스팅으로 옮겨 가야지
        &lt;span class=&quot;me2_tags&quot;&gt;(인터넷생활 맥용APM)&lt;/span&gt;
        &lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/11/27#02:34:19&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-11-27 02:34:19&lt;/a&gt;&lt;/span&gt;
        
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;
      이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 
      &lt;a href=&quot;http://me2day.net/yesarang/2008/11/27#02:00:41&quot;&gt;2008년 11월 27일&lt;/a&gt;의 
      미투데이 내용입니다.
    &lt;/p&gt;
  &lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>개발자</category>
      <category>네이버</category>
      <category>맥용apm</category>
      <category>미투뉴스</category>
      <category>센터</category>
      <category>인터넷생활</category>
      <category>제로보드XE</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/350</guid>
      <comments>https://yesarang.tistory.com/350#entry350comment</comments>
      <pubDate>Thu, 27 Nov 2008 04:33:04 +0900</pubDate>
    </item>
    <item>
      <title>다음 모바일 서비스 블로거 간담회에 다녀오다</title>
      <link>https://yesarang.tistory.com/349</link>
      <description>11월 26일 저녁 7시 &lt;a title=&quot;[http://info.daum.net/Daum/info/comingWay.do]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://info.daum.net/Daum/info/comingWay.do&quot;&gt;다음 양재 사옥&lt;/a&gt; 3층에서 개최된 &quot;&lt;a title=&quot;[http://daummobile.tistory.com/38]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://daummobile.tistory.com/38&quot;&gt;다음 모바일 서비스 블로거 간담회&lt;/a&gt;&quot;에 다녀왔습니다. 저로서는 아주 오랜만의 서울 나들이였습니다. 워낙 회사일도 바쁘고, 집안 가장으로서 해야할 일도 많고 해도 시간 내기가 여간 어렵지 않더군요. 그런 만큼 이번에는 머리도 식힐 겸 요즘 모바일 인터넷이 어떻게 돌아가는지도 알아볼 겸 해서 기대하는 마음으로 참석했습니다.&lt;br /&gt;
&lt;br /&gt;
행사장에 늦게 도착하지 않기 위해 급하게 나섰던지 너무 일찍 도착해서 주변에서 살짝 방황 좀 하다가 6:30분 쯤에 행사장에 들어갔습니다. &lt;a title=&quot;[http://me2day.net/jdpapa7]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/jdpapa7&quot;&gt;지동아빠&lt;/a&gt;님(첨엔 몰랐는데 나중에 알았다는...)께서 식사는 6:50분에 제공되고, 행사는 식사후에 시작하게 된다고 하시더군요. 그래서 잠시 기다리는 동안 인터넷에 접속하려고 했으나... 헉! 무선랜이 안되더군요. ㅠ.ㅠ 순간 당황해서 패닉 상태에 빠질 뻔 했습니다. 혼미해지던 정신을 부여잡고 뭘해야하나 고민하던 중 &lt;a title=&quot;[http://me2day.net/goigoi]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/goigoi&quot;&gt;고이고이&lt;/a&gt;님께서 아는체를 하셔서 겨우 정신 수습했습니다. 이 자리를 빌어서 고이고이님께 감사 ^^&lt;br /&gt;
&lt;br /&gt;
식사할 때는 같은 테이블에 &lt;a title=&quot;[http://me2day.net/sukhyun]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/sukhyun&quot;&gt;빨판&lt;/a&gt;님, &lt;a title=&quot;[http://me2day.net/harmjang]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/harmjang&quot;&gt;함장&lt;/a&gt;님, &lt;a title=&quot;[http://me2day.net/goigoi]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/goigoi&quot;&gt;고이고이&lt;/a&gt;님, &lt;a title=&quot;[http://me2day.net/bigenius]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/bigenius&quot;&gt;미소챨스&lt;/a&gt;님과 합석했습니다.&lt;br /&gt;
&lt;br /&gt;
행사 첫 오프닝은 oojoo라는 id로도 유명하신 김지현님(회사내 직책은 본부장이신가 보더군요)께서 하셨고, 기업이 블로그를 운영하는 것은 공개할 수 있는 정보와 공개해서는 안되는 정보 사이를 잘 조절해야 해서 어려움이 많지만 서비스를 혼자 만드는 거이 아니라 사용자와 같이 만든다고 생각하기 때문에 외부와 소통하기 위해 블로그를 운영하고 있고, 이번 간담회도 같은 맥락에서 1차로 준비한 서비스에 대한 의견을 듣고 싶어서 개최한 것이라고 배경 설명을 해 주셨습니다.&lt;br /&gt;
&lt;br /&gt;
그리고 이어서 지도 위에서 무궁 무진한 서비스가 펼쳐질 수 있다고 생각하고, 모바일 서비스의 킬러앱을 맵으로 보고 있다고 설명하시면서, 다음이 맵에 어떤 투자를 하고 있는지 실제 시연 장면을 통해 보여주셨습니다. 이 대목에서 기밀사항이라 사진 촬영은 금지! 저야 카메라가 없으니 말하지 않아도 찍을 수 없는 상황이었죠 ^^ 언뜻 보기에 맵 해상도가 상당히 고화질로 보이더군요. 스트릿뷰, 스카이뷰도 지원되고 요즘은 대부분 포털들이 고화질 맵 서비스를 제공하고 있어서 크게 달라 보이진 않았습니다. (여기서 아마 다음의 고민이 시작되겠지요? 어떻게 타사와 차별화 시킬 것인가?)&lt;br /&gt;
&lt;br /&gt;
이런 맵을 별도의 어플리케이션을 통해 모바일 폰에 올리려나 보더군요. 이런 맵 위에서 지명 검색, UCC 검색, 드라마 촬영지 검색, 경로 검색(버스, 지하철, 버스&amp;amp;지하철, 최적 경로, 최단 경로) 등도 가능하다고 합니다. 나중에 &lt;a title=&quot;[http://me2day.net/jdpapa7]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/jdpapa7&quot;&gt;지동아빠&lt;/a&gt;님(모바일 애플리케이션 담당이시랍니다)께서 직접 테이블에 오셔서 시연도 해주셨습니다. 내년 쯤에서(내년 초라고 했는지 말이라고 했는지 기억이 나질 않네요 ㅠ.ㅠ) 모바일 맵 서비스가 가능하다고 하니 아직은 많이 기다려야 할 듯 합니다.&lt;br /&gt;
&lt;br /&gt;
이어서 풀브라우징 서비스와 모바일 애플리케이션에 대한 설명이 이어졌습니다. 풀브라우징 서비스 기획 담당하신 분은 금동우님이고 모바일 애플리케이션을 담당하신 분은 &lt;a title=&quot;[http://me2day.net/jdpapa7]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://me2day.net/jdpapa7&quot;&gt;지동아빠&lt;/a&gt;님이시더군요. 전 두 분 다 초면이었습니다.&lt;br /&gt;
&lt;br /&gt;
풀브라우징 서비스는 현재로서는 아르고폰에 맞춰서 개발이 되었다고 하더군요. 아무리 모바일 폰이 UI가 좋다고 하더라도 단말 자체에 익숙해지는 것이 힘들다고 판단하여 &quot;가독성&quot;, &quot;편리한 스크롤&quot;, &quot;가로/세로 대응&quot;, &quot;PC화면 전환&quot; 에 주안점을 두고 서비스를 개발했다고 합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;가독성&lt;/span&gt;이야 화면이 많이 좁으니 폰트 크기를 적당히 맞춰져야 하므로 당연히 신경써야 하는 속성이었을 것 같구요(제 생각입니다), &lt;span style=&quot;font-weight: bold;&quot;&gt;편리한 스크롤&lt;/span&gt;은 아직 국내에 출시된 스마트폰들이 아이폰만큼 부드러운 터치감과 스크롤을 제공해 주지 못하기 때문에 서비스 제공자 입장에서 그런 것들 보완할 수 있는 방안을 고민했다고 하더군요.&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;가로/세로 대응&lt;/span&gt;도 기존 왑 사용자의 경우 세로로 정보가 나열되는데 이미 익숙해져 있기 때문에 다른 모바일 서비스(모바일 파란을 예로 들었습니다)처럼 가로만 브라우징되도록 하는 것 좋지 않은 것이라 판단되어 가로/세로 모두 대응되도록 개발했다고 합니다.&lt;br /&gt;
마지막으로 &lt;span style=&quot;font-weight: bold;&quot;&gt;&quot;PC화면 전환&quot;&lt;/span&gt;은 모바일 서비스에 최적화된 형태로 모든 정보를 변환하기는 상당히 시일이 소요될 것으로 예상되므로 더 상세한 정보를 얻고자 하는 사용자의 요구사항을 만족시키기 위해 &quot;PC화면 전환&quot;이라는 버튼을 매 페이지에 두었다고 합니다.&lt;br /&gt;
&lt;br /&gt;
현재 풀브라우징 외 모바일 애플리케이션으로 준비한 것은 TV팟과 지도 애플리케이션이라고 하더군요. TV팟 애플리케이션은 직접 사용도 해 봤는데 상당히 빠르게 응답하는 걸 봐서는 1차 버전임에도 상당히 최적화에 신경을 쓴 흔적이 보였습니다. 다만 시연시 사용했던 iPod Touch의 문제인지 아니면 동영상 자체 품질의 문제인지 화면에 잔상이 많이 남더군요. TV팟은 Hot, Best, Themes, Movies, Games 탭을 제공하고 있고, 아직 검색 기능은 제공하지 않습니다. &lt;a title=&quot;[http://www.futurewalker.kr/446]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://www.futurewalker.kr/446&quot;&gt;퓨처워커&lt;/a&gt;님께서 왜 검색기능을 제공하지 않느냐는 질문을 주셨고 이에 대해 검색 기능을 제공하려면 모든 동영상을 TV팟 모바일 애플리케이션에 볼 수 있도록 인코딩을 해 놓아야 하는데, 아직 그렇게는 준비가 안되어 있다고 답변을 하시더군요. ROI때문에라도 모든 동영상은 모바일에 맞게 인코딩할 수는 없기 때문에 사용자들의 강력한 요구가 있을때에나 검색 기능을 추가할 수 있을 것이라며 검색 기능을 더 강력히 요청하라고 부추기시더군요. ^^&lt;br /&gt;
&lt;br /&gt;
저는 개인적으로 맵 정보를 바탕으로 풍부한 지역 정보 서비스가 제공되면 좋겠습니다. 그런 지역 정보 서비스가 &lt;a href=&quot;http://me2day.net&quot; target=&quot;_blank&quot; title=&quot;[http://me2day.net]로 이동합니다.&quot;&gt;미투데이&lt;/a&gt; 같은 마이크로 블로그 SNS와 연동이 되면 더욱 좋을 것 같구요. 정보가 맵에 집중되기도 하지만 각자의 마이크로 블로그에 분산되기도 하면서 그 안에서 관계를 맺는 것도 자연스러운 그런 서비스가 제공되면 좋겠습니다. 이런 서비스를 어떻게 구체적인 모습으로 만들지는 별 생각이 떠오르지 않지만요.&lt;br /&gt;
&lt;br /&gt;
이후 각 테이블에 아이팟 터치와 아르고폰을 나눠 주셔서 직접 조작하면서 풀브라우징 서비스와 TV팟 서비스를 사용해 볼 수 있었습니다. 풀브라우징 서비스 화면은 폰카로는 화질이 도저히 나오질 않아서 제 맥북의 내장 카메라로 어떻게 억지로 찍었는데 화질이 그닥 좋지 않습니다. OTL 그래도 글만 있으면 너무 심심할까봐 그림 첨부합니다. ^^&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs11/12_tistory_2008_11_26_00_53_492c1f66a8e0b?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs11%2F12_tistory_2008_11_26_00_53_492c1f66a8e0b%3Foriginal&quot; width=&quot;510&quot; height=&quot;383&quot; alt=&quot;&quot; filename=&quot;사진4.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
풀브라우징 초기화면은 &lt;a title=&quot;[http://daummobile.tistory.com/44]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://daummobile.tistory.com/44&quot;&gt;이글&lt;/a&gt;을 보시면 더 정확히 알 수 있습니다.&lt;br /&gt;
&lt;br /&gt;
저는 개인적으로 체험시간에 금동우님께 다음과 같은 질문을 했습니다.&lt;br /&gt;
&lt;br /&gt;
질문: 어떤 서비스가 모바일 풀브라우징 서비스가 되게 할 계획인지요?&lt;br /&gt;
답변: 현재 개발된 풀브라우징 서비스는 모두 소위 &quot;노가다&quot; 방식으로 개발한 것들이다. 이런 방법외에 구글과 같은 완전 자동 트랜스 코딩 방식, 오리가미 같은 준 트랜스코딩 방식이 있으나, 기술적인 한계 또는 비용 문제로 인해 보류했다. 그렇지만 소위 &quot;노가다&quot; 방식으로는 오래가지 못할 것이고 향후 보류했던 방식을 다시 시도해볼 수 있을 것이다.&lt;br /&gt;
다시질문: (질문의 의도를 파악하지 못하신 것 같아서) 그렇다고 하더라도 나중에 발표를 하실 때, 우리 서비스 중에 이런 이런 서비스들은 모바일 서비스가 제공된다라고 발표를 하실 거 아녜요? 어떤 서비스들을 계획하고 계신가요?&lt;br /&gt;
답변: 우선 메일, 검색, 뉴스는 1차로 개발되었고, 향후 증권, 티스토리, 부동산, 맵서비스도 준비중입니다.&lt;br /&gt;
질문: 모바일 폰에는 자신의 개인적인 정보도 많이 담기는데 모바일 폰 싱크 서비스는 계획하지 않고 계신가요?&lt;br /&gt;
답변: 모바일 폰 싱크 서비스도 준비 중이다.&lt;br /&gt;
&lt;br /&gt;
저는 솔직히 모바일 폰 싱크 서비스가 나오기를 바라는 사람이라서요. 제일 마지막 답변을 듣고 싶어서 저런 장황한 대화를 나눴었지요. ^^&lt;br /&gt;
&lt;br /&gt;
이외에 나중에 토론 시간에 BM에 대한 질문, 모바일 데이터 요금제 대책에 대한 질문, 모바일 사용자들의 사용 패턴 조사 여부에 대한 질문, 모바일 서비스에서 포털의 역할이 무엇이라고 생각하는지에 대한 질문 등 매우 까다로운 질문들이 오고 갔습니다. 이런 질문에 대한 답변은 참석하신 분들이 어딘가에 따로 포스팅하실 것을 기대하면서 저는 이만 줄여야 겠습니다. 벌써 새벽 1시가 넘어가네요.&lt;br /&gt;
&lt;br /&gt;
까다로운 질문으로 공격을 받으시던 김지현님께서 오히려 참석한 블로거들에게 질문을 하나 던지시더군요.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&quot;이렇게 모바일 서비스를 하는 게 어려운데 다음이 뛰어든게 답일까요?&quot;&lt;/span&gt;&lt;br style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&quot;저희들은 뛰어든게 답이라고 생각해서 이렇게 열심히 하고 있습니다. 모바일 서비스는 누구 하나의 노력으로 되지 않고 업계가 함께 노력해야 한다고 생각해서 타사와 협력해서 시장의 파이를 키우려고 노력중입니다. 앞으로 다음의 노력을 주목해 주십시오&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
라는 말로 마무리를 지으시더군요.&lt;br /&gt;
&lt;br /&gt;
다음의 모바일 서비스 기대하고 있겠습니다. 쾌적하고, 즐겁고, 유용한 무선 인터넷을 만드시는데 노력해 주시기를 당부 드립니다. ^^&lt;br /&gt;
&lt;br /&gt;
(To 다음 모바일 TFT 관계자 분들께: 이 정도면 밥값은 한 건가요? 그리고 다음에는 무선랜 좀 되게 해주세요. ^^)&lt;br /&gt;</description>
      <category>IT동향</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/349</guid>
      <comments>https://yesarang.tistory.com/349#entry349comment</comments>
      <pubDate>Wed, 26 Nov 2008 07:00:00 +0900</pubDate>
    </item>
    <item>
      <title>C++이야기 스물여덟번째: map container에 STL algorithm적용하기</title>
      <link>https://yesarang.tistory.com/348</link>
      <description>If you are more familiar with English, then follow this link.&lt;br /&gt;
&lt;a href=&quot;http://yesarang.wordpress.com/2008/11/24/cpp-tips-28/&quot; title=&quot;Permalink&quot;&gt;C++ Tips 28th: Applying STL Algorithms to a Map&amp;nbsp;Container&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
여러분은 map container에 STL algorithm을 적용해 보신 적 있으신가요? map은 key=value pair를 저장해 두는 container라서 다른 container에 비해 STL algorithm을 적용하기가 쉽지 않더군요. map은 key 보다는 value에 관심이 있는 container라서 STL algorithm을 수행할 때도 key-value pair에 대해서 특정 작업을 수행하기 보다는 value에 대해서 어떤 작업을 수행하기를 원하는 경우가 많은데, STL algorithm 및 표준 함수 객체들이 map에 맞춰져 작성되어 있질 않아서 이걸 하기가 쉽지 않더군요. 그래서 별도의 Adaptor class를 정의하는 경우가 많습니다. 한 번 예를 들어 보겠습니다. 다음과 같은 클래스가 정의되어 있다고 가정해 보시죠.&lt;br /&gt;
&lt;br /&gt;
class Elem {&lt;br /&gt;
public:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Elem() : m_name(), m_val() {}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Elem(const string&amp;amp; name, int val) : m_name(name), m_val(val) {}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; const string&amp;amp; GetName() const&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return m_name;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int GetValue() const&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return m_val;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; void SetValue(int val)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_val = val;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; void Print() const&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cout &amp;lt;&amp;lt; GetName() &amp;lt;&amp;lt; &quot;'s value ==&amp;gt; &quot; &amp;lt;&amp;lt; GetValue() &amp;lt;&amp;lt; endl;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
private:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string m_name;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int m_val;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
이 Elem 를 담는 map을 다음과 같이 정의해서 몇 개를 집어 넣어 보도록 하겠습니다.&lt;br /&gt;
&lt;br /&gt;
// 앞으로 설명에서 나오는 m container는 이걸 뜻합니다&lt;br /&gt;
map&amp;lt;string, Elem&amp;gt; m;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
m[&quot;1&quot;] = Elem(&quot;1&quot;, 1);&lt;br /&gt;
m[&quot;2&quot;] = Elem(&quot;2&quot;, 2);&lt;br /&gt;
m[&quot;3&quot;] = Elem(&quot;3&quot;, 3);&lt;br /&gt;
m[&quot;4&quot;] = Elem(&quot;4&quot;, 4);&lt;br /&gt;
m[&quot;5&quot;] = Elem(&quot;5&quot;, 5);&lt;br /&gt;
&lt;br /&gt;
이 map에 담긴 모든 Elem 들의 값을 얻어내고 싶은 경우를 생각해 보겠습니다. 그렇다면 다음과 같이 for 루프를 작성할 수 있습니다.&lt;br /&gt;
&lt;br /&gt;
// 먼저 값을 담을 vector를 정의합니다&lt;br /&gt;
vector&amp;lt;int&amp;gt; vi(m.size());&lt;br /&gt;
// 그리고 for 루프를 돌립니다&lt;br /&gt;
for (map&amp;lt;string, Elem&amp;gt;::iterator it = m.begin(); it != m.end(); ++it)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; vi.push_back(it-&amp;gt;second.GetValue());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
소위 STL 좀 쓴다하는 여러분이 위와 같은 코드를 그냥 둘리 만무합니다. 어떻게 하면 저 for 루프를 STL 알고리즘으로 바꿀 수 없을까를 고민하시겠지요. 그리고 transform을 쓰면 되겠구나라고 맘을 먹습니다.&lt;br /&gt;
&lt;br /&gt;
// 먼저 algorithm header 파일을 포함해야죠&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;functional&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; vi(m.size());&lt;br /&gt;
// m 에 들어가 있는 것은 포인터가 아니라 값이 들어가 있으므로 mem_fun이 아닌&lt;br /&gt;
// mem_fun_ref를 사용하여 멤버 함수 객체를 만듭니다&lt;br /&gt;
transform(m.begin(), m.end(), vi.begin(), mem_fun_ref(&amp;amp;Elem::GetValue));&lt;br /&gt;
&lt;br /&gt;
이 코드가 문제 없이 컴파일 돼서 실행될까요? 안타깝게도 그렇지 않습니다. transform이 기대하는 건 Elem 객체가 아닌 pair&amp;lt;string, Elem&amp;gt; 객체이기 때문에 컴파일 에러가 발생하지요. 여기서 잠깐 transform 알고리즘 속을 들여다 보면 왜 컴파일 에러가 발생하는지 좀 저 정확히 알 수 있습니다.&lt;br /&gt;
&lt;br /&gt;
// 설명을 편하게 하기 위해 핵심 부분만 발췌했습니다.&lt;br /&gt;
template&amp;lt;typename _InputIterator, typename _OutputIterator,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; typename _UnaryOperation&amp;gt;&lt;br /&gt;
_OutputIterator&lt;br /&gt;
transform(_InputIterator __first, _InputIterator __last,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _OutputIterator __result, _UnaryOperation __unary_op)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; for ( ; __first != __last; ++__first, ++__result)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;*__result = __unary_op(*__first);&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; return __result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
파랗게 표시한 부분을 보시면 first iterator를 dereference하고 있습니다. first iterator를 dereference하면 당연히 Elem 객체가 아닌 pair&amp;lt;string, Elem&amp;gt; 객체가 되는 것이지요.&lt;br /&gt;
&lt;br /&gt;
그렇다면 뭔가 Elem의 GetValue()를 호출해 줄 Adaptor가 필요하겠군요. 다음과 같이 Adaptor를 정의하면 될까요?&lt;br /&gt;
&lt;br /&gt;
struct ElemGetValueAdaptor {&lt;br /&gt;
&amp;nbsp; int operator()(const pair&amp;lt;string, Elem&amp;gt;&amp;amp; p) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return p.second.GetValue();&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
이런 클래스를 정의하고 나서 transform을 다음과 같이 호출하면 되겠습니다.&lt;br /&gt;
&lt;br /&gt;
transform(m.begin(), m.end(), vi.begin(), ElemGetValueAdaptor());&lt;br /&gt;
&lt;br /&gt;
뭐 여기까지는 할만합니다. 여기에 덧붙여 이번에는 m container에 있는 Elem 객체의 값을 출력해야 해서 Elem::Print()를 호출해야 하게 됐습니다. 그래서 Adaptor를 하나 더 정의합니다.&lt;br /&gt;
&lt;br /&gt;
struct ElemPrintAdaptor {&lt;br /&gt;
&amp;nbsp; void operator()(const pair&amp;lt;string, Elem&amp;gt;&amp;amp; p) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; p.second.Print();&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
그리고 나서 for_each를 다음과 같이 호출하면 되겠지요.&lt;br /&gt;
&lt;br /&gt;
for_each(m.begin(), m.end(), vi.begin(), ElemPrintAdaptor());&lt;br /&gt;
&lt;br /&gt;
이렇게 매번 멤버 함수를 호출하려고 할 때마다 Adaptor를 정의하면 얼마 있지 않아 코드에 온갖 Adaptor들이 난무하게 될 것입니다. 그리고, Adaptor들의 모양새라는 것도 거의 반복되는 코드이구요. 반복되는 코드를 보다보면 당연히 어떻게 하면 반복되는 코드를 없앨까를 생각하게 되죠. 그래서 이걸 템플릿으로 할 수 없을까를 생각하시게 될 것입니다.&lt;br /&gt;
&lt;br /&gt;
template &amp;lt;typename R&amp;gt;&lt;br /&gt;
struct ElemAdaptor {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // GetValue()와 Print()가 모두 상수 멤버 함수라서 끝에 const를 붙임&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; typedef R (Elem::*MemFunType)() const;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ElemAdaptor(MemFunType mf) : m_mf(mf) {}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; R operator()(const pair&amp;lt;string, Elem&amp;gt;&amp;amp; p) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (p.second.*m_mf)();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
private:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MemFunType m_mf;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
그리고, transform과 for_each는 다음과 같이 호출하면 되겠지요.&lt;br /&gt;
&lt;br /&gt;
transform(m.begin(), m.end(), vi2.begin(), ElemAdaptor&amp;lt;int&amp;gt;(&amp;amp;Elem::GetValue));&lt;br /&gt;
 for_each(m.begin(), m.end(), ElemAdaptor&amp;lt;void&amp;gt;(&amp;amp;Elem::Print));&lt;br /&gt;
&lt;br /&gt;
이렇게 하면 GetValue()와 Print()는 커버할 수 있겠지만 SetValue(int)는 처리할 수 없습니다. Argument가 있기 때문입니다. 게다가 상수 멤버 함수도 아니구요. 이런 다양한 멤버함수를 처리할 수 있는 일반적인 멤버 함수 Adaptor를 만드는 건 보통 어려운 일이 아닙니다.&lt;br /&gt;
만약 m container가 Elem 객체의 container가 아니라 Elem* 의 container 거나 Elem&amp;amp;의 container이면 상황이 더 복잡해 질 것입니다. const나 volatile이 붙을 수도 있는 거구요. 이 모든 것들을 처리할 수 있는 일반적인 Adaptor를 만드는 건 무척이나 어려운 일이지요.&lt;br /&gt;
&lt;br /&gt;
이럴 때 써먹을 수 있는 게 boost::bind 와 placeholder입니다. boost::bind는 앞에서 제가 언급한 다양한 차이들을 모두 극복하고 하나의 함수로 모든 것을 수용할 수 있습니다. 위에서 제가 직접 만들었던 Adaptor를 쓰지 않고 bind를 쓰는 방식으로 바꾼다면 다음과 같이 작성하시면 됩니다.&lt;br /&gt;
&lt;br /&gt;
// boost::bind&lt;br /&gt;
#include &amp;lt;boost/bind.hpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
using namespace boost;&lt;br /&gt;
......&lt;br /&gt;
transform(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; m.begin(), m.end(), vi2.begin(), &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;bind(&amp;amp;Elem::GetValue, bind(&amp;amp;map&amp;lt;string, Elem&amp;gt;::value_type::second, _1))&lt;/span&gt;&lt;br /&gt;
);&lt;br /&gt;
for_each(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; m.begin(), m.end(),&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;bind(&amp;amp;Elem::Print, bind(&amp;amp;map&amp;lt;string, Elem&amp;gt;::value_type::second, _1))&lt;/span&gt;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
inner bind() 즉 bind(&amp;amp;map&amp;lt;string, Elem&amp;gt;::value_type::second, _1) 이렇게 된 부분을 먼저 설명드리면, _1은 placeholder라고 하여 _1이라고 표시된 부분에 인자를 받을 수 있는 함수자(functor)를 만들어주게 됩니다. transform과 for_each는 각각 pair&amp;lt;string, Elem&amp;gt;를 입력인자로 하여 해당 알고리즘의 마지막 인자로 주어진 함수자를 호출할 것이므로 _1 placeholder를 써서 인자를 받을 수 있도록 한 것입니다. 그리고 inner bind의 첫번째 인자로 멤버 변수에 대한 포인터를 주게 되면, 두번째 인자로 주어진 객체(이 경우 _1)에 대해 멤버로 참조할 수 있도록 만들어 줍니다. &amp;amp;map&amp;lt;string, Elem&amp;gt;::value_type::second 라고 한 부분은 당연히 map 에서 Elem 객체를 참조할 수 있도록 하기 위한 것입니다. 이 설명을 종합하자면 inner bind는 pair&amp;lt;string, Elem&amp;gt; 객체에서 Elem 객체를 선택하는 부분이라고 생각하시면 되겠습니다. 즉, ElemAdaptor::operator(p) 의 구현에서 p.second 에 해당하는 부분이라고 생각하시면 되겠습니다.&lt;br /&gt;
&lt;br /&gt;
이걸 바탕으로 outer bind를 좀 더 쉽게 표현해 보자면 bind(Elem_mem_func_ptr, Elem_obj), 이런 의미가 되겠습니다. bind는 첫번째 인자가 멤버 포인터(멤버 변수에 대한 포인터이건 멤버 함수에 대한 포인터이건 상관 없이)이면 두번째 인자를 객체(또는 객체 참조자 또는 객체 포인터)로 해석하고 해당 객체에 대해 멤버 변수나 멤버 함수를 접근 또는 호출해주는 함수자를 만들어 줍니다. 그래서 결국은 (Elem_obj.*Elem_mem_func_ptr)() 또는 (Elem_obj-&amp;gt;*Elem_mem_func_ptr)() 의 효과가 있게 됩니다.&lt;br /&gt;
&lt;br /&gt;
bind는 꼭 인자가 없는 멤버 함수에만 쓸 수 있는 건 아닙니다. 실은 인자를 9개까지 지원해 줍니다. 예를 들어, m container를 각 Elem 객체에 대해 Elem::SetValue(10) 를 호출하고 싶다면 다음과 같이 하시면 됩니다.&lt;br /&gt;
&lt;br /&gt;
for_each(&lt;br /&gt;
&amp;nbsp; m.begin(), m.end(),&lt;br /&gt;
&amp;nbsp; bind(&amp;amp;Elem::SetValue, bind(&amp;amp;map&amp;lt;string, Elem&amp;gt;::value_type::second, _1), 10)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
bind의 세번째 인자로 SetValue()의 인자값을 bind 하면 되는 것이지요.&lt;br /&gt;
&lt;br /&gt;
정리하자면 map container에 STL algorithm을 적용하고 싶을 때는 boost::bind와 placeholder를 다음과 같은 패턴으로 사용하시면 되겠습니다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;#include &amp;lt;boost/bind.hpp&amp;gt;&lt;/span&gt;&lt;br style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&lt;br style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;using namespace boost;&lt;/span&gt;&lt;br style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&lt;br style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;&lt;span style=&quot;color: rgb(25, 61, 169); font-weight: bold;&quot;&gt;bind(&amp;amp;ClassName::mem_func_name, bind(&amp;amp;map&amp;lt;keytype,&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClassName&amp;gt;::value_type::second, _1), arg1, arg2, ..., arg9)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
그럼 여러분의 C++ 프로그래밍에 조금이라도 도움이 되길 바라면서 이만 줄여야겠네요.&lt;br /&gt;
&lt;br /&gt;</description>
      <category>S/W개발/C++ 이야기</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/348</guid>
      <comments>https://yesarang.tistory.com/348#entry348comment</comments>
      <pubDate>Mon, 24 Nov 2008 07:00:00 +0900</pubDate>
    </item>
    <item>
      <title>김윤수의 인터넷 오늘은 - 2008년 11월 21일</title>
      <link>https://yesarang.tistory.com/347</link>
      <description>&lt;div class=&quot;me2day_daily_digest&quot;&gt;
    &lt;ul&gt; 
      &lt;li&gt;
        &lt;a href='http://msdn.microsoft.com/ko-kr/magazine/cc164244.aspx'&gt;F# Primer&lt;/a&gt;: F# 소개 기사네요. 이제는 함수형 언어에도 관심을 많이 가져 봐야 겠어요
        &lt;span class=&quot;me2_tags&quot;&gt;(SW개발 프로그래밍언어 fsharp F#)&lt;/span&gt;
        &lt;span class=&quot;datetime&quot;&gt;&lt;a href=&quot;http://me2day.net/yesarang/2008/11/21#22:57:30&quot; rel=&quot;bookmark&quot; title=&quot;퍼머링크&quot; class=&quot;datetime&quot;&gt;2008-11-21 22:57:30&lt;/a&gt;&lt;/span&gt;
        
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p style=&quot;background:url(http://me2day.net/images/me2day_icon.gif) no-repeat right top;padding-right:25px;text-align:right; font-size: 0.9em;&quot;&gt;
      이 글은 &lt;a href=&quot;http://me2day.net/yesarang&quot; target=&quot;_blank&quot;&gt;김윤수&lt;/a&gt;님의 
      &lt;a href=&quot;http://me2day.net/yesarang/2008/11/21#22:57:30&quot;&gt;2008년 11월 21일&lt;/a&gt;의 
      미투데이 내용입니다.
    &lt;/p&gt;
  &lt;/div&gt;</description>
      <category>인터넷오늘은</category>
      <category>f</category>
      <category>fsharp</category>
      <category>sw개발</category>
      <category>프로그래밍언어</category>
      <author>김윤수</author>
      <guid isPermaLink="true">https://yesarang.tistory.com/347</guid>
      <comments>https://yesarang.tistory.com/347#entry347comment</comments>
      <pubDate>Sat, 22 Nov 2008 04:33:01 +0900</pubDate>
    </item>
  </channel>
</rss>