<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://fsfoundry.org/codefreak/wp-atom.php">
	<title type="text">COdE fr3@K</title>
	<subtitle type="text">Weblog of a lively geek.</subtitle>

	<updated>2008-05-12T06:06:09Z</updated>
	<generator uri="http://wordpress.org/" version="2.3.3">WordPress</generator>

	<link rel="alternate" type="text/html" href="http://fsfoundry.org/codefreak" />
	<id>http://fsfoundry.org/codefreak/feed/atom/</id>
	

			<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.5/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><link rel="self" href="http://feeds.feedburner.com/codefreak" type="application/atom+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Richard Stallman 來台演講]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/282808444/" />
		<id>http://fsfoundry.org/codefreak/2008/05/04/richard-stallman-talks-in-taiwan/</id>
		<updated>2008-05-08T16:35:00Z</updated>
		<published>2008-05-03T16:04:59Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Report" />		<summary type="html"><![CDATA[活動網頁上表示暫定 5/14 在台北 5/14 上午在淡江大學及 5/15 在新竹傍晚在清華大學各一場. 台北那場我已 email 去報名了.



OpenMoko 活動網頁
Linux 台灣 新聞網頁
]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/05/04/richard-stallman-talks-in-taiwan/"><![CDATA[<p>活動網頁上表示<s>暫定 5/14 在台北</s> 5/14 上午在淡江大學及 5/15 <s>在新竹</s>傍晚在清華大學各一場. 台北那場我已 email 去報名了.</p>
<p><span id="more-251"></span><br />
<a href="http://wiki.openmoko.org/images/2/26/Richard_speech_tku.jpg" rel="lightbox"><img src="http://wiki.openmoko.org/images/2/26/Richard_speech_tku.jpg" width="500" /></a></p>
<p><a href="http://wiki.openmoko.org/images/0/01/Richard_speech_nthu.jpg" rel="lightbox"><img src="http://wiki.openmoko.org/images/0/01/Richard_speech_nthu.jpg" width="500" /></a></p>
<p>OpenMoko <a href="http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw">活動網頁</a><br />
Linux 台灣 <a href="http://www.linux.org.tw/node/548">新聞網頁</a></p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/05/04/richard-stallman-talks-in-taiwan/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Strong Guarantee using Transaction]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/280153929/" />
		<id>http://fsfoundry.org/codefreak/2008/04/29/strong-guarantee-using-transaction/</id>
		<updated>2008-05-12T06:06:09Z</updated>
		<published>2008-04-29T15:24:05Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Boost" /><category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="C++0x" /><category scheme="http://fsfoundry.org/codefreak" term="Coding" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Tutorial" />		<summary type="html"><![CDATA[Abrahams Guarantees
在 C++ 的世界裡, 正確的 exception handling 是專業的 C++ programmer 不可或缺的技巧. 雖然它的概念並不困難, 但實作起來卻常不見得那麼容易.
要做到正確的 exception handling, 首先必須要了解什麼是 exception safety. 一個需要與 exception 打交道的 component 可在其介面實作人稱 Abrahams guarantees 的三種 exception safety 保證之一:

The basic guarantee
允許操作失敗時改變物件的狀態, 但不能有 resource leak. 且該物件的狀態必須是可靠的仍然可以被解構, 操作失敗後該物件的狀態可以是不完全能被預測的.
The strong guarantee
操作後的狀態只能是成功完成, 或是將該物件回復到操作之前的狀態並拋出一個 exception.
The no-throw guarantee
操作不會拋出 exception.


接下來, 我要用下面這個 class definition 來嘗試實作上述三種 exception safety:



Listing 1



class contact_entry
{
public:
  void update_name(
  [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/29/strong-guarantee-using-transaction/"><![CDATA[<h4 id="abrahams_guarantees">Abrahams Guarantees</h4>
<p>在 C++ 的世界裡, 正確的 exception handling 是專業的 C++ programmer 不可或缺的技巧. 雖然它的概念並不困難, 但實作起來卻常不見得那麼容易.</p>
<p>要做到正確的 exception handling, 首先必須要了解什麼是 exception safety. 一個需要與 exception 打交道的 component 可在其介面實作人稱 <a href="http://en.wikipedia.org/wiki/Abrahams_guarantees">Abrahams guarantees</a> 的三種 exception safety 保證之一:</p>
<ol>
<li>The basic guarantee</li>
<p>允許操作失敗時改變物件的狀態, 但不能有 resource leak. 且該物件的狀態必須是可靠的仍然可以被解構, 操作失敗後該物件的狀態可以是不完全能被預測的.</p>
<li>The strong guarantee</li>
<p>操作後的狀態只能是成功完成, 或是將該物件回復到操作之前的狀態並拋出一個 exception.</p>
<li>The no-throw guarantee</li>
<p>操作不會拋出 exception.
</ol>
<p><span id="more-247"></span><br />
接下來, 我要用下面這個 class definition 來嘗試實作上述三種 exception safety:</p>
<ul id="listing-1">
<table>
<tr>
Listing 1<br />
</tr>
<tr>
<pre>
class contact_entry
{
public:
  void update_name(
    const string&#038; first_name,
    const string&#038; last_name);

  const string&#038; get_first_name() const;
  const string&#038; get_last_name() const;

  // Other member functions omitted...

private:
  string first_name_;
  string last_name_;

  // Other member data omitted...
  // Email email_;
  // PhoneNumber phone_number_;
};
</pre>
</tr>
</table>
</ul>
<p>先實作 basic guarantee:</p>
<ul id="listing-2">
<table>
<tr>
Listing 2<br />
</tr>
<tr>
<pre>
void contact_entry::update_name(
  const string&#038; first_name,
  const string&#038; last_name)
{
  first_name_ = first_name; // a1, may throw
  last_name_ = last_name;   // a2, may throw
}
</pre>
</tr>
</table>
</ul>
<p>若 a1 拋出個 exception, <code>last_name_</code> 還保持著操作前的狀態, 而 <code>first_name_</code> 會處於一個有效但不確定的狀態.<sup><a href="#footnote-1-247" id="footnote-link-1-247" class="footnote-link footnote-identifier-link" title="說白了就是一個除了可以被正常解構, 其他操作都沒實質意義的狀態">1</a></sup> 若 exception 是在 a2 處拋出, <code>first_name_</code> 已經被修改了, 這次換到 <code>last_name_</code> 處於一個有效但不確定的狀態.  這兩種狀況都沒有 resource 被 leak 掉, 因此符合 basic guarantee 的條件.<sup><a href="#footnote-2-247" id="footnote-link-2-247" class="footnote-link footnote-identifier-link" title="string 的 operator= 保障的正好也是 basic guarantee">2</a></sup></p>
<p>再來實作 strong guarantee:</p>
<ul id="listing-3">
<table>
<tr>
Listing 3<br />
</tr>
<tr>
<pre>
void contact_entry::update_name(
  const string&#038; first_name,
  const string&#038; last_name)
{
  string tmp1 = first_name; // b1, may throw
  string tmp2 = last_name;  // b2, may throw
  swap(first_name_, tmp1);  // b3, no-throw
  swap(last_name_, tmp2);   // b4, no-throw
}
</pre>
</tr>
</table>
</ul>
<p>不論 exception 在 b1 或 b2 處拋出,  <code>first_name_</code> 與 <code>last_name_</code> 都處於原本的狀態. 若 b1 與 b2 都成功了, 只要利用不會拋出 exception 的 <code>swap</code> 讓 <code>first_name_</code>/<code>last_name_</code> 與 <code>tmp1</code>/<code>tmp2</code> 交換所管理的資源與狀態, 同時也利用在 <code>contact_entry::update_name</code> 這個 function 結束時 <code>tmp1</code>/<code>tmp2</code> 自動解構的機制來釋放原本屬於 <code>first_name_</code>/<code>last_name_</code> 的資源.</p>
<p>於是在任意地方失敗時, <code>first_name_</code> 與 <code>last_name_</code> 都將處於操作前的狀態. 若操作成功, <code>first_name_</code> 與 <code>last_name_</code> 都會被改變到新的狀態. 因此符合  strong guarantee 的條件.</p>
<p>最後是 no-throw guarantee:</p>
<ul id="listing-4">
<table>
<tr>
Listing 4<br />
</tr>
<tr>
<pre>
void contact_entry::update_name(
  string first_name,
  string last_name)
{
  swap(first_name_, first_name); // no-throw
  swap(last_name_, last_name);   // no-throw
}
</pre>
</tr>
</table>
</ul>
<p>這個例子其實有偷吃步. 把 <code>contact_entry::update_name</code> 的 interface 改變了一點. 把原本型別為 <code>const string&#038;</code> 的兩個參數改為 <code>string</code>. 使得我們可以在 <code>contact_entry::update_name</code> 的 function body 裏面直接以 <code>swap</code> 與 function parameter 交換資源與狀態, 而躲掉了上一個例子中可能會拋出 exception 的操作 (b1 and b2). 這樣的改變/實作是否滿足了 no-throw guarantee 的要求?</p>
<p>這個實作看似達成的 no-throw guarantee 是個假象. 它不過是把前面一個例子裡可能會拋出 exception 的 b1 與 b2 的操作移出 function body. 但可別忘了當 <code>contact_entry::update_name</code> 被呼叫, 在進入 function body 之前, 兩個型別為 <code>string</code> 的參數還是需要先被建構以供 function body 使用. Exception 依然可能在這時候被拋出. 所以這個例子並不符合 no-throw guarantee 的條件. 呼嚨一下倒是可以.</p>
<p>No-throw guarantee 嘗試失敗.<sup><a href="#footnote-3-247" id="footnote-link-3-247" class="footnote-link footnote-identifier-link" title="不論是直接或間接, 只要某 code path 有可能會失敗的 resource allocation, 最多就只能做到 strong guarantee, 達不到 no-throw guarantee">3</a></sup></p>
<h4 id="the_strong_guarantee">The Strong Guarantee</h4>
<p>從上面的解釋與例子可以看出來 basic guarantee 實在是很陽春.<sup><a href="#footnote-4-247" id="footnote-link-4-247" class="footnote-link footnote-identifier-link" title="陽春歸陽春, 總是比沒有 exception safety 來得強的多">4</a></sup> 實際上只要如文中的例子一樣, 所依賴的 component 都保證了 basic guarantee (or higher), 上層的應用就自動擁有 basic guarantee.</p>
<p>要做到 strong guarantee 是要付出些代價的. 如第二個例子中的 temporary objects. 但只要做到 strong guarantee 就能給 user 狀態的可預測性. 一個操作不是成功就是失敗, 不會處於一個不上不下的狀態. 將具有 strong guarantee 的操作想像為 database 的 trasaction 就可以清楚知道它的好處. 麻煩的是 strong guarantee 並不總是像文中所舉的例子這麼容易實現, 例如當一個 module 的狀態完整性是基於多個成功的操作時.</p>
<p>想像一下如果有個 <code>class contact_manager</code>, 提供了管理連絡人的介面與多種查詢的方法. 為了讓這個例子簡單些, 請容許我忽略連絡人的姓氏與名字重複的問題. 它的 interface 像下面這樣:</p>
<ul id="listing-5">
<table>
<tr>
Listing 5<br />
</tr>
<tr>
<pre>
class contact_manager
{
public:
  const contact_entry* find_contact_by_first_name(
    const string&#038; first_name);
  const contact_entry* find_contact_by_last_name(
    const string&#038; first_name);
  void add_contact(const contact_entry&#038; contact);

  // Other member functions omitted...
private:
  typedef list&lt;contact_entry&gt; contact_list_t;
  contact_list_t contact_list_;

  typedef map&lt;string, contact_list_t::iterator&gt; first_name_map_t;
  typedef map&lt;string, contact_list_t::iterator&gt; last_name_map_t;
  first_name_map_t first_name_map_;
  last_name_map_t last_name_map_;

  // Other member data omitted...
};
</pre>
</tr>
</table>
</ul>
<p>連絡人都儲存在 <code>contact_manager::contact_list_</code>. 而 <code>contact_manager::first_name_map_</code> 與 <code>contact_manager::last_name_map_</code> 則是用來加速查詢. 它的實作可能是這樣:</p>
<ul id="listing-6">
<table>
<tr>
Listing 6<br />
</tr>
<tr>
<pre>
const contact_entry* contact_manager::find_contact_by_first_name(
  const string&#038; first_name)
{
  contact_list_t::iterator iter = first_name_map_.find(first_name);
  if(iter == first_name_map_.end())
  {
    return NULL;
  }
  return &#038;(*iter->second);
}
const contact_entry* contact_manager::find_contact_by_last_name(
  const string&#038; last_name)
{
  contact_list_t::iterator iter = last_name_map_.find(last_name);
  if(iter == last_name_map_.end())
  {
    return NULL;
  }
  return &#038;(*iter->second);
}
void contact_manager::add_contact(const contact_entry&#038; contact)
{
  contact_list_t::iterator contact_iter =
    contact_list_.insert(contact_list_.end(), contact);
  first_name_map_.insert(
    make_pair(contact.get_first_name(), contact_iter));
  last_name_map_.insert(
    make_pair(contact.get_last_name(), contact_iter));
}
</pre>
</tr>
</table>
</ul>
<p>兩個用來查詢的 member function 以一樣手法實作, 裏面的操作都是 no-throw, 也就是說它們提供的 exception safety 也都是 no-throw. 用來加入連絡人的 <code>contact_manager::add_contact</code> 裏面的三個 statement 雖然即便失敗也不會造成 resource leak,<sup><a href="#footnote-5-247" id="footnote-link-5-247" class="footnote-link footnote-identifier-link" title="因此符合 basic guarantee">5</a></sup> 卻都可能會因為後面兩個 statement 在 memory allocation 失敗而拋出 exception 時, 導致正在被加入的連絡人無法以某 (些) 欄位查詢.<sup><a href="#footnote-6-247" id="footnote-link-6-247" class="footnote-link footnote-identifier-link" title="contact_manager::add_contact 的 funciton body 總共有五個地方可能會拋出 exception, 你都看到了嗎? ">6</a></sup> <code>contact_manager</code> 的 instance 也因此喪失其狀態的完整性. 這個時候可以以巢狀 try-catch 將原本為 basic guarantee 的 exception safety 提升為 strong guarantee:</p>
<ul id="listing-7">
<table>
<tr>
Listing 7<br />
</tr>
<tr>
<pre>
void contact_manager::add_contact(const contact_entry&#038; contact)
{
  contact_list_t::iterator contact_iter =
    contact_list_.insert(contact_list_.end(), contact); // d1, work1

  try
  {
    first_name_map_t::iterator first_name_iter =
      first_name_map_.insert(
        make_pair(contact.get_first_name(), contact_iter)); // d2, work2

    try
    {
      last_name_map_.insert(
        make_pair(contact.get_last_name(), contact_iter)); // d3, work3
    }
    catch(...)
    {
      first_name_map_.erase(first_name_iter); // d4, work2 rollback
      throw;
    }
  }
  catch(...)
  {
    contact_list_.erase(contact_iter); // d5, work1 rollback
    throw;
  }
}
</pre>
</tr>
</table>
</ul>
<p>先不論巢狀 try-catch 可能造成的效能傷害. 明明是順序的 code 卻需要以巢狀的方式表現, 愈前面 (外層) 的 work (如 d1) 距離 rollback (如 d5) 愈遠, 更是讓可維護性與可讀性大大地打了一個折扣. 接下來我要提出一個作法, 可以解決前述幾個問題. 讓順序的 code 依然是順序的, 同時讓針對某 work 的 rollback 緊接在 work 的後面.</p>
<h4 id="class_transaction">Class Transaction</h4>
<p>下面是一個模擬 database trasaction 在失敗時會自動 rollback 的 C++ component. 介面與實作如下:</p>
<ul id="listing-8">
<table>
<tr>
Listing 8<br />
</tr>
<tr>
<pre>
class trasaction
{
public:
  trasaction()
  :   rollback_needed_(false)
  {}
  ~trasaction()
  {
    if(rollback_needed_ == true)
    {
      while(rollback_stack_.empty() == false)
      {
          rollback_stack_.back()();
          rollback_stack_.pop_back();
      }
    }
  }

  template &lt;
    class WorkFunctor,
    class RollbackFunctor&gt;
  void execute(
    WorkFunctor work,
    RollbackFunctor rollback /*no-throw*/)
  {
    rollback_needed_ = true;
    rollback_stack_.push_back(rollback);
    work();
    rollback_needed_ = false;
  }

  template &lt;
    class WorkFunctor&gt;
  void execute(
    WorkFunctor work)
  {
    rollback_needed_ = true;
    work();
    rollback_needed_ = false;
  }

private:
  typedef <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=functio2.html#function">function</a>&lt;void ()&gt; rollback_function_t;
  typedef deque&lt;rollback_function_t&gt; rollback_stack_t;

  rollback_stack_t rollback_stack_;
  bool rollback_needed_;
};
</pre>
</tr>
</table>
</ul>
<p>搭配上 <a href="http://fsfoundry.org/codefreak/2008/04/11/five-ways-to-write-for-loops/#cpp0x_lambda">C++0x 的 lambda expressions and clousres</a>, <code>contact_manager::add_contact</code> 可以以下面的方式實作, 達到 strong guarantee:</p>
<ul id="listing-9">
<table>
<tr>
Listing 9<br />
</tr>
<tr>
<pre>
void contact_manager::add_contact(const contact_entry&#038; contact)
{
  contact_list_t::iterator contact_iter;
  first_name_map_t::iterator first_name_iter;

  // It is critical to define instances of class trasaction
  // after definitions of all references referenced in
  // lambda expressions.
  trasaction trx;

  trx.execute(
    // work1
    [&#038;]()
    {
      contact_iter = contact_list_.insert(
        contact_list_.end(), contact);
    },
    // work1 rollback
    [&#038;]()
    {
      contact_list_.erase(contact_iter);
    });

  trx.execute(
    // work2
    [&#038;]()
    {
      first_name_iter = first_name_map_.insert(
        make_pair(
          contact.get_first_name(), contact_iter));
    },
    // work2 rollback
    [&#038;]()
    {
      first_name_map_.erase(first_name_iter);
    });
  );

  trx.execute(
    // work3
    [&#038;]()
    {
      last_name_map_.insert(
        make_pair(
          contact.get_last_name(), contact_iter));
    });
}
</pre>
</tr>
</table>
</ul>
<p>這樣是不是容易閱讀與維護許多了呢?<sup><a href="#footnote-7-247" id="footnote-link-7-247" class="footnote-link footnote-identifier-link" title="當然, 前題是先得把 C++0x 的 Lambda Expressions and Closures 弄熟">7</a></sup></p>
<h4 id="cpp98_unnamed_functors">C++98 Unnamed Functors</h4>
<p>只可惜 C++0x 的時代還沒到來. 如果不想手工寫那些很可能只被使用一次的 functor, 另外一個選擇是用 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=functio2.html#bind">tr1::bind</a> 來產生匿名 functor.<sup><a href="#footnote-8-247" id="footnote-link-8-247" class="footnote-link footnote-identifier-link" title="在本文的例子中, 使用 tr1::bind, Boost.Bind 或 Boost.Lambda 的結果是完全一樣的">8</a></sup> 例如將:</p>
<ul id="listing-10">
<table>
<tr>
Listing 10<br />
</tr>
<tr>
<pre>
// work1
[&#038;]()
{
  contact_iter = contact_list_.insert(
    contact_list_.end(),
    contact);
}
</pre>
</tr>
</table>
</ul>
<p>變成:</p>
<ul id="listing-11">
<table>
<tr>
Listing 11<br />
</tr>
<tr>
<pre>
// work1
bind(
  &#038;contact_list_t::insert,
  &#038;contact_list_,
  contact_list_.end(),
  contact)
</pre>
</tr>
</table>
</ul>
<p>這個方案有兩個問題. 首先是它不能 compile. <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=list.html#list::insert"><code>list::insert</code></a> 是一個有兩個版本的 overloaded 的 member function, 一個是插入一個值, 另一個是插入一個 range.<sup><a href="#footnote-9-247" id="footnote-link-9-247" class="footnote-link footnote-identifier-link" title="所有標準 container 的 insert 與 erase 都有 overloaded 的設計">9</a></sup> 當 C++ 在遇到 overloaded 的 function 的時候, 沒辦法單以 function 的名稱來決議要參考的實體. 因此會有 ambiguous 的錯誤. 再來是 <code>bind</code> 無法如我們需要的接到 return value (<code>contact_iter</code>). 因此我們需要先準備幾個 forwarder function:</p>
<ul id="listing-12">
<table>
<tr>
Listing 12<br />
</tr>
<tr>
<pre>
template &lt;class Container&gt;
void insert_value_at(
  Container&#038; cont,
  typename Container::iterator where,
  const typename Container::value_type&#038; value,
  typename Container::iterator&#038; ret)
{
  ret = cont.insert(where, value);
}

template &lt;class Container&gt;
void insert_value(
  Container&#038; cont,
  const typename Container::value_type&#038; value)
{
  cont.insert(value);
}

template &lt;class Container&gt;
void erase_at(
  Container&#038; cont,
  typename Container::iterator where)
{
  cont.erase(where);
}
</pre>
</tr>
</table>
</ul>
<p>於是就可以將 <code>contact_manager::add_contact</code> 如此實作:</p>
<ul id="listing-13">
<table>
<tr>
Listing 13<br />
</tr>
<tr>
<pre>
void contact_manager::add_contact(const contact_entry&#038; contact)
{
  contact_list_t::iterator contact_iter;
  first_name_map_t::iterator first_name_iter;

  // It is critical to define instances of class trasaction
  // after definitions of all references referenced in
  // lambda expressions.
  trasaction trx;

  trx.execute(
    // work1
    bind(
      &#038;insert_value_at,
      <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=functio2.html#ref">ref</a>(contact_list_), // pass-by-reference
      contact_list_.end(),
      contact,
      ref(contact_iter)), // pass-by-reference
    // work1 rollback
    bind(
      &#038;erase_at,
      ref(contact_list_), // pass-by-reference
      contact_iter)
  );

  trx.execute(
    // work2
    bind(
      &#038;insert_value,
      ref(first_name_map_), // pass-by-reference
      make_pair(contact.get_first_name(), contact_iter)),
    // work2 rollback
    bind(
      &#038;erase_at,
      ref(first_name_map_), // pass-by-reference
      first_name_iter)
  );

  trx.execute(
    // work3
    bind(
      &#038;insert_value,
      ref(last_name_map_), // pass-by-reference
      make_pair(contact.get_last_name(), contact_iter))
  );
}
</pre>
</tr>
</table>
</ul>
<p>這個版本閱讀起來比 <a href="#listing-9">listing 9</a> 的實作困難. 跟 <a href="#listing-7">listing 7</a> 比較起來可說是各有其優缺點.</p>
<h4 id="conclusion">Conclusion</h4>
<p>IMO, 在 C++0x 的標準下使用文中的 <a href="#class_transaction"><code>class trasaction</code></a> 以達成 strong guarantee 可大幅增加 source code 的可讀性與可維護性. 這個方式增加了 memory allocation 的動作,<sup><a href="#footnote-10-247" id="footnote-link-10-247" class="footnote-link footnote-identifier-link" title="在 transaction::perform 把 rollback 推進 transaction::rollback_stack_ 時">10</a></sup> 卻也免去了多重 try-catch 的 overhead. 一加一減之下整體表現還需 benchmark 後才能見真章. 好消息是 optimize 標準 container 的 memory allocation 不是一件難事, 就把這個題目留到下一次吧.</p>
<ol start="1" class="footnotes"><li id="footnote-1-247" class="footnote">說白了就是一個除了可以被正常解構, 其他操作都沒實質意義的狀態 [<a href="#footnote-link-1-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-247" class="footnote"><code>string</code> 的 <code>operator=</code> 保障的正好也是 basic guarantee [<a href="#footnote-link-2-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-3-247" class="footnote">不論是直接或間接, 只要某 code path 有可能會失敗的 resource allocation, 最多就只能做到 strong guarantee, 達不到 no-throw guarantee [<a href="#footnote-link-3-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-4-247" class="footnote">陽春歸陽春, 總是比沒有 exception safety 來得強的多 [<a href="#footnote-link-4-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-5-247" class="footnote">因此符合 basic guarantee [<a href="#footnote-link-5-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-6-247" class="footnote"><code>contact_manager::add_contact</code> 的 funciton body 總共有五個地方可能會拋出 exception, 你都看到了嗎?  [<a href="#footnote-link-6-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-7-247" class="footnote">當然, 前題是先得把 C++0x 的 Lambda Expressions and Closures 弄熟 [<a href="#footnote-link-7-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-8-247" class="footnote">在本文的例子中, 使用 tr1::bind, Boost.Bind 或 Boost.Lambda 的結果是完全一樣的 [<a href="#footnote-link-8-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-9-247" class="footnote">所有標準 container 的 insert 與 erase 都有 overloaded 的設計 [<a href="#footnote-link-9-247" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-10-247" class="footnote">在 <code>transaction::perform</code> 把 <code>rollback</code> 推進 <code>transaction::rollback_stack_</code> 時 [<a href="#footnote-link-10-247" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/29/strong-guarantee-using-transaction/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[re: Socket Programming in C 常犯的錯誤]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/275138638/" />
		<id>http://fsfoundry.org/codefreak/2008/04/22/re-socket-programming-in-c-%e5%b8%b8%e7%8a%af%e7%9a%84%e9%8c%af%e8%aa%a4/</id>
		<updated>2008-04-24T09:41:29Z</updated>
		<published>2008-04-22T04:25:05Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C" /><category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Cited" /><category scheme="http://fsfoundry.org/codefreak" term="Coding" /><category scheme="http://fsfoundry.org/codefreak" term="Commentary" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[昨天在網上閒逛, 在樂多上看到篇名為 &#8220;Socket Programming in C 常犯的錯誤&#8221; 的短文.  這短文作者的動機很好, 指出常見到的錯誤並提供個人看法與可能較好的作法. 這樣的行為很值得鼓勵. 但極可惜的是, 結果卻是很不理想的. 容我說句重話, 如果是考試的話該文是得不到我的分數的.

本想直接在該文回應作者, 但考慮到文中的兩個問題其實是很多不夠老練的 programmer 容易犯的毛病, 因此決定把我的評論寫在這裡, 自己留個紀錄, 也希望能供更多人參考.
原文照貼:

在一個簡單的網路程式，似乎有滿多人都會這樣寫：
char tmp[32];
memset( tmp, &#8216;\0&#8242;, sizeof(tmp));
int ret = recv( sock, tmp, sizeof(tmp), 0 );
把 buffer 填滿固然是一件好事，但是字串填滿之後，結果沒有\0了
就會發生意想不到的事情，可能會出現程式記憶體區段錯誤的問題
( 字元陣列的結尾正常結束都要有個 \0 才是正確的 )
假設我們不看 ret 回傳收到多大的資料，考慮使用 strcat 來把回傳的 buffer
串到更大的 buffer 字元陣列，應該要扣掉1來使用，避免發生記憶體區段錯誤！
char tmp[32];
memset( tmp, &#8216;\0&#8242;, sizeof(tmp));
int ret = recv( sock, [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/22/re-socket-programming-in-c-%e5%b8%b8%e7%8a%af%e7%9a%84%e9%8c%af%e8%aa%a4/"><![CDATA[<p>昨天在網上閒逛, 在樂多上看到篇名為 &#8220;<a href="http://blog.roodo.com/kenwu/archives/4392251.html">Socket Programming in C 常犯的錯誤</a>&#8221; 的短文.  這短文作者的動機很好, 指出常見到的錯誤並提供個人看法與可能較好的作法. 這樣的行為很值得鼓勵. 但極可惜的是, 結果卻是很不理想的. 容我說句重話, 如果是考試的話該文是得不到我的分數的.<br />
<span id="more-246"></span><br />
本想直接在該文回應作者, 但考慮到文中的兩個問題其實是很多不夠老練的 programmer 容易犯的毛病, 因此決定把我的評論寫在這裡, 自己留個紀錄, 也希望能供更多人參考.</p>
<p>原文照貼:</p>
<blockquote><p>
在一個簡單的網路程式，似乎有滿多人都會這樣寫：</p>
<p>char tmp[32];<br />
memset( tmp, &#8216;\0&#8242;, sizeof(tmp));<br />
int ret = recv( sock, tmp, sizeof(tmp), 0 );</p>
<p>把 buffer 填滿固然是一件好事，但是字串填滿之後，結果沒有\0了<br />
就會發生意想不到的事情，可能會出現程式記憶體區段錯誤的問題<br />
( 字元陣列的結尾正常結束都要有個 \0 才是正確的 )</p>
<p>假設我們不看 ret 回傳收到多大的資料，考慮使用 strcat 來把回傳的 buffer<br />
串到更大的 buffer 字元陣列，應該要扣掉1來使用，避免發生記憶體區段錯誤！</p>
<p>char tmp[32];<br />
memset( tmp, &#8216;\0&#8242;, sizeof(tmp));<br />
int ret = recv( sock, tmp, sizeof(tmp) - 1, 0 );
</p></blockquote>
<p>首先是作者在文中指出需要在 buffer 最後保留一個 <code>0x00</code>, 以利後續字串操作. 這原則上是對的, 只是文中舉的例子是 <a href="http://www.opengroup.org/onlinepubs/009695399/functions/recv.html"><code>recv</code></a>, 以 <code>recv</code>/<a href="http://www.opengroup.org/onlinepubs/000095399/functions/send.html"><code>send</code></a>/<a href="http://www.opengroup.org/onlinepubs/007908799/xsh/read.html"><code>read</code></a>/<a href="http://opengroup.org/onlinepubs/007908775/xsh/write.html"><code>write</code></a> 等 API 作 I/O 的時候讀寫的內容是 binary data 而不是 null-terminated string.<sup><a href="#footnote-1-246" id="footnote-link-1-246" class="footnote-link footnote-identifier-link" title="當然, binary data 本身也可以是 null-terminated string">1</a></sup> 以 socket I/O 來說, 除非 protocol 是如 HTTP 等的文本協議, 否則讀上來的有效 data 很可能中間就有值為 <code>0x00</code> 的 byte.<sup><a href="#footnote-2-246" id="footnote-link-2-246" class="footnote-link footnote-identifier-link" title="印象中, 即便是 HTTP, message 的 content 中間也可能出現值為 0x00 的 byte">2</a></sup> 而將最後有個 <code>0x00</code> 的 binary data 拿來當作 null-terminated string 操作, 後果可是很難設想的. 雖不至於造成記憶體錯誤, 功能上卻不是正確的. 又由於這樣的 bug 不總是容易重現, 造成的傷害反而可能更大. 所有讀上來的 data 應當要搭配上 <code>recv</code> 的非錯誤 return value (也就是讀出的 byte 數) 才能加以操作, 而不能將它視為字串, 拿來餵給 <a href="http://www.opengroup.org/onlinepubs/000095399/functions/strlen.html"><code>strlen</code></a>/<a href="http://www.opengroup.org/onlinepubs/009695399/functions/strcat.html"><code>strcat</code></a> 等 API .</p>
<p>另外作者說到, 在使用前先以 <code>0x00</code> 填滿 (fill) 整個 buffer 是好事. 但其實這是沒有任何意義的. 若 <code>recv</code> 失敗, buffer 指向的 memory 根本不會被拿來參考. 要是 <code>recv</code> 成功了, buffer 會被參考的部份則已經被覆蓋掉了. 如果 protocol 是文本協議, 只需如作者所說的在 <code>recv</code> 時先保留一個 byte, 並在成功時在最後補上個 null 就足夠了:</p>
<pre>
char tmp[32];
int ret = recv( sock, tmp, sizeof(tmp) - 1, 0 );
//if(ret != -1)
//{
//  tmp[ret] = 0;
//}
if(ret > 0)
{
  tmp[ret] = 0;
  // tmp is ready to be manipulated as string
}
else
{
  // handle error/EOF here
}
</pre>
<ol start="1" class="footnotes"><li id="footnote-1-246" class="footnote">當然, binary data 本身也可以是 null-terminated string [<a href="#footnote-link-1-246" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-246" class="footnote">印象中, 即便是 HTTP, message 的 content 中間也可能出現值為 <code>0x00</code> 的 byte [<a href="#footnote-link-2-246" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/22/re-socket-programming-in-c-%e5%b8%b8%e7%8a%af%e7%9a%84%e9%8c%af%e8%aa%a4/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Video made for Microsoft&#8217;s sales team]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/274211352/" />
		<id>http://fsfoundry.org/codefreak/2008/04/21/video-made-for-microsofts-sales-team/</id>
		<updated>2008-04-20T18:53:21Z</updated>
		<published>2008-04-20T18:53:21Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Cited" /><category scheme="http://fsfoundry.org/codefreak" term="Funny" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Video" />		<summary type="html"><![CDATA[很好笑的一段影片, 在 news.com 的 Microsoft 1, blogosphere 0 看到的.



]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/21/video-made-for-microsofts-sales-team/"><![CDATA[<p>很好笑的一段影片, 在 news.com 的 <a href="http://www.news.com/8301-10787_3-9920713-60.html">Microsoft 1, blogosphere 0</a> 看到的.</p>
<p><object width="425" height="355">
<param name="movie" value="http://www.youtube.com/v/sPv8PPl7ANU&#038;hl=en"></param>
<param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/sPv8PPl7ANU&#038;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/21/video-made-for-microsofts-sales-team/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Virtualization != 虛擬作業系統]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/272257555/" />
		<id>http://fsfoundry.org/codefreak/2008/04/18/virtualization-does-not-equal-to-virtual-operating-system/</id>
		<updated>2008-04-18T02:07:12Z</updated>
		<published>2008-04-17T16:01:34Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Cited" /><category scheme="http://fsfoundry.org/codefreak" term="Commentary" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Whining" />		<summary type="html"><![CDATA[首先我得說清楚我對 virtualization 這個題目沒有研究, 單純是個享福的使用者. 從很久 (8/9 年?) 以前在 MacOS 7.x (or 8.x?) 上用 Virtual PC 跑 Win95, 到近幾年的主要在 GNU/Linux 上用 QEMU 跑 Win2K 與 Minix 3.
一個不懂 virtualization 確切定義與技術細節的人, 一個使用過 Virtual PC, VMWare (player/workstation), QEMU, VirtaulBox 等 virtualization application 的人如我. 在使用過上述任何一種 virtualization application 後很容易就會知道, 把 virtual machine 開啟後首先會看到 POST (Power-on self-test) 畫面. 如果沒有其他如 boot image 等的設置, [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/18/virtualization-does-not-equal-to-virtual-operating-system/"><![CDATA[<p>首先我得說清楚我對 <a href="http://en.wikipedia.org/wiki/Virtualization#Processing_virtualization">virtualization</a> 這個題目沒有研究, 單純是個享福的使用者. 從很久 (8/9 年?) 以前在 MacOS 7.x (or 8.x?) 上用 Virtual PC 跑 Win95, 到近幾年的主要在 GNU/Linux 上用 QEMU 跑 Win2K 與 <a href="http://www.minix3.org/">Minix 3</a>.</p>
<p>一個不懂 virtualization 確切定義與技術細節的人, 一個使用過 Virtual PC, VMWare (player/workstation), QEMU, VirtaulBox 等 virtualization application 的人如我. 在使用過上述任何一種 virtualization application 後很容易就會知道, 把 virtual machine 開啟後首先會看到 POST (Power-on self-test) 畫面. 如果沒有其他如 boot image 等的設置, 接下來什麼也不會發生. 不會看到屬於某個 OS 的 shell 或是 desktop manager 的提示畫面, 使用者什麼事都做不了.<br />
<span id="more-244"></span><br />
這說明了什麼? 前面的提到的 virtualization application 所 virtualize 的都不是作業系統. 它們 virtualize 的基本上是硬體平台, 主要是 CPU, 再加上 BIOS, I/O, memory 等子系統.</p>
<p>好了, 我對 virtualization 的了解差不多就這麼多 (事實上是就這麼少); 我用過的 virtualization application 都不會蹦出個作業系統給我用. 都需要我手動掛個 bootable image 或是把 OS 灌在某個 disk image. 之後, 我才能在 virtual machine 上做有意義的事.</p>
<hr/>
<p>話說前年在黑米的一個群組書簽, 第一次看到<a href="http://fsfoundry.org/codefreak/2006/10/02/bad-temper/">有人把 QEMU 說成是免費的作業系統模擬器</a>.  畢竟該書簽主人不是個技術人, 把 QEMU/virtualization 描述錯誤並不特別讓人意外.<sup><a href="#footnote-1-244" id="footnote-link-1-244" class="footnote-link footnote-identifier-link" title="該書簽的描述是從 toget 上亂抄來的 , 不願更正就罷了, 可是事後又酸我一下倒是令我挺不爽快">1</a></sup></p>
<p>而後又好幾次在不同的地方看到幾乎是一模一樣的錯誤, 我也屢次雞婆地留言對作者提示. 只是最近兩次看到的類似錯誤是在 <a href="http://julian14632.wordpress.com/2008/03/27/qemu-%e7%9a%84%e5%a5%bd%e5%b9%ab%e6%89%8bqemu-manager%ef%bc%8c%e8%ae%93%e4%bd%a0%e5%b0%87%e8%99%9b%e6%93%ac%e7%b3%bb%e7%b5%b1%e7%a8%8b%e5%bc%8f%e5%b8%b6%e8%91%97%e8%b5%b0%ef%bc%81-%e4%bd%9c%e6%a5%ad/">多多與我的部落格</a> 以及 <a href="http://go-linux.blogspot.com/2008/04/os.html">瘋狂帽客&#8217;s Blog</a> 兩位 (半?) 技術人的博客上. 讓我忍不住要在這裡再一次多嘴嘮叨一下: &#8220;<strong>Virtualization 不等於虛擬作業系統</strong>&#8220;.</p>
<ol start="1" class="footnotes"><li id="footnote-1-244" class="footnote">該書簽的描述是從 toget 上亂抄來的 , 不願更正就罷了, 可是事後又<a href="http://fsfoundry.org/codefreak/2006/10/05/sneered/">酸我一下</a>倒是令我挺不爽快 [<a href="#footnote-link-1-244" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/18/virtualization-does-not-equal-to-virtual-operating-system/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[The Free Launch is Back]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/270568292/" />
		<id>http://fsfoundry.org/codefreak/2008/04/15/free-lauch-is-back/</id>
		<updated>2008-04-15T10:21:53Z</updated>
		<published>2008-04-15T08:08:03Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Report" />		<summary type="html"><![CDATA[From the main page of MCSTL:

The Multi-Core Standard Template Library (MCSTL) is a parallel implementation of the standard C++ library. It makes use of multiple processors and/or multiple cores of a processor with shared memory. It blends in transparently and there is in principle no change necessary in the program itself.


根據該網站的介紹, MCSTL 是一套與 Standard C++ [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/15/the-free-launch-is-back/"><![CDATA[<p>From the main page of <a href="http://algo2.iti.uni-karlsruhe.de/singler/mcstl/">MCSTL</a>:</p>
<blockquote><p>
The Multi-Core Standard Template Library (MCSTL) is a parallel implementation of the standard C++ library. It makes use of multiple processors and/or multiple cores of a processor with shared memory. It blends in transparently and there is in principle no change necessary in the program itself.
</p></blockquote>
<p><span id="more-243"></span><br />
根據該網站的介紹, MCSTL 是一套與 Standard C++ Library 相容的實作.<sup><a href="#footnote-1-243" id="footnote-link-1-243" class="footnote-link footnote-identifier-link" title="不過從它的文件看來, MCSTL 不是一套 generic 的 Standard C++ Library 實作, 而像是 patch 過的 libstdc++">1</a></sup> 使用 MCSTL, 將可在 client code 使用到 <code>sort</code>, <code>random_shuffle</code>, <code>partition</code>, <code>merge</code>, <code>find</code>, <code>nth_element</code>, <code>partial_sum</code> 以及 <code>for_each</code> 等 STL algorithm 的時候, 得到多核/CPU 平行運算的加速. 可說是多核時代的免費午餐.<sup><a href="#footnote-2-243" id="footnote-link-2-243" class="footnote-link footnote-identifier-link" title="關於免費午餐將盡的故事請見 Sutter 的 The Free Lunch Is Over">2</a></sup> 目前 MCSTL 正在被整合進入 GCC 4.3 的 &#8220;libstdc++ parallel mode&#8221;. </p>
<p>又多了一個使用 STL algorithm 的好理由.</p>
<ol start="1" class="footnotes"><li id="footnote-1-243" class="footnote">不過從它的<a href="http://algo2.iti.uni-karlsruhe.de/singler/mcstl/documentation/0.8.0-beta/files.html">文件</a>看來, MCSTL 不是一套 generic 的 Standard C++ Library 實作, 而像是 patch 過的 libstdc++ [<a href="#footnote-link-1-243" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-243" class="footnote">關於免費午餐將盡的故事請見 Sutter 的 <a href="http://www.gotw.ca/publications/concurrency-ddj.htm">The Free Lunch Is Over</a> [<a href="#footnote-link-2-243" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/15/the-free-launch-is-back/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[不是李白也能 C++]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/269087869/" />
		<id>http://fsfoundry.org/codefreak/2008/04/13/cpp-is-not-privileged-to-language-lawyers/</id>
		<updated>2008-04-14T14:31:49Z</updated>
		<published>2008-04-12T19:16:29Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="不客觀觀點" />		<summary type="html"><![CDATA[除了語法上的困難, 另一個 C++ 常被人嫌的特性就是不如 C#(.Net)/Java/Python 之流般擁有大量標準的 library1 或針對特定功能的準標準 library.2 寫上一篇 (五種寫 For Loop 的方法) 時, 突然體會到這樣的現象似乎是源自 C++ 的設計與演化, 很可能是難以避免的結果.

在 FOSS 社群裡, 有能力並願意貢獻的人看到能改進的實作時, 常會送 patch 給原做/維護者. 但若一個這個有改進空間的 library 的 interface 令人不滿意時, 很容易會讓這群貢獻者放棄這樣的行為, 因為 interface 有問題的 library 根本就不實用. (至少不好用) 而增加自認有個幾兩重的人轉而去另闢山頭重來一次的可能性.
以 C (或任何一個相對於 C++ 顯著較為簡單的語言) 為例, 針對一組特定功能定出讓大家滿意的 interface 已經不是件容易的事情. 而 C++ 不但擁有多種 progamming paradigm,3 連簡單的 for loop 都能用至少五種有顯著差異的方法來寫. [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/13/cpp-is-not-privileged-to-language-lawyers/"><![CDATA[<p>除了語法上的困難, 另一個 C++ 常被人嫌的特性就是不如 C#(.Net)/Java/Python 之流般擁有大量標準的 library<sup><a href="#footnote-1-242" id="footnote-link-1-242" class="footnote-link footnote-identifier-link" title="先不論 C++ 的定位是 general purpose programming language, 本來就不願意把相對特殊非必須的 library 納入標準">1</a></sup> 或針對特定功能的準標準 library.<sup><a href="#footnote-2-242" id="footnote-link-2-242" class="footnote-link footnote-identifier-link" title="這裡所謂的準標準 library 是如 Pthreads, OpenSSL, BSD socket 等非語言標準但被廣泛支援/使用的 library/interface/API">2</a></sup> 寫上一篇 (<a href="http://fsfoundry.org/codefreak/2008/04/11/five-ways-to-write-for-loops/">五種寫 For Loop 的方法</a>) 時, 突然體會到這樣的現象似乎是源自 C++ 的設計與演化, 很可能是難以避免的結果.<br />
<span id="more-242"></span><br />
在 FOSS 社群裡, 有能力並願意貢獻的人看到能改進的<strong>實作</strong>時, 常會送 patch 給原做/維護者. 但若一個這個有改進空間的 library 的 interface 令人不滿意時, 很容易會讓這群貢獻者放棄這樣的行為, 因為 interface 有問題的 library 根本就不實用. (至少不好用) 而增加自認有個幾兩重的人轉而去另闢山頭重來一次的可能性.</p>
<p>以 C (或任何一個相對於 C++ 顯著較為簡單的語言) 為例, 針對一組特定功能定出讓大家滿意的 interface 已經不是件容易的事情. 而 C++ 不但擁有多種 progamming paradigm,<sup><a href="#footnote-3-242" id="footnote-link-3-242" class="footnote-link footnote-identifier-link" title="有自 C 繼承過來的 procedural programming, 與一開始就有的 object-oriented programming. 有催生出 STL/Boost/Loki 等的 metaprogramming (templates). 以及 C++0x 將加入的 functional programming (Lambda Expressions and Closures) ">3</a></sup> 連簡單的 for loop 都能用至少五種有顯著差異的方法來寫. 用它來定出一個好用被肯定 (或至少被接受) 的 interface 更是需要經歷更久的時間數倍的力氣.  結果就是會同時存在多套功能類似但 interface 截然不同的 C++ library.<sup><a href="#footnote-4-242" id="footnote-link-4-242" class="footnote-link footnote-identifier-link" title="例如 Boost.Thread vs CWinThread">4</a></sup> 因此 library 被標準化或成為準標準的可能又更是小了. 這不是完全沒有好處的, 從另一個角度來說這造成了更多樣化的競爭.</p>
<p>C++ 之父 <a href="http://www.research.att.com/~bs/">Bjarne Stroustrup</a> 多次說過, 他不願意發明一種他可以預見將如何被使用者運用的語言. 在他將 template 引進 C++ 時他更沒有預想到如 STL, 一個在今天幾乎是完全被 C++ 社群擁抱推崇並標準化的 library, 的出現. 正因為 C++ 是如此的多樣化, 才得以促成它們的誕生. 數量少但質量高的 (準) 標準 library 對 C++ 的未來是好是壞, 還得看 C++ 與社群接下來的造化.</p>
<p>不可諱言, C++ 不是種容易的語言. 它的學習曲線陡得讓不少人畏懼三分. 就像是只有擁有好文筆的人 (甚至是詩人) 才能寫出動人的詩詞一般; 使用今天的 C++ 寫出簡潔優美的程式有時的確變成所謂的語言專家 (language lawyer) 的專利. 但這並不代表大部分認真學習過某種語文的人不能有效地以該語文與他人溝通, 甚至是寫出言簡易駭的文字. 只是可能沒那麼<strong>美</strong>罷了.</p>
<p>C++ 給 programmer 多變化的選擇一定程度上造成了此刻的我們只看到少數傑出的 library 的事實. 正如如此的多變的人類語文, 也只孕育出相對少量的雋永文字. 但若不是這樣的特性, 今天的世界會不會沒有李白? 我們是否會知道莎士比亞是誰?</p>
<p>實際的狀況是, 不是李白的我們還是照樣與人溝通, 或許也跟我一樣沒事寫寫文字發發牢騷. 不是 C++ 語言專家但<strong>合格</strong>的 C++ programmer<sup><a href="#footnote-5-242" id="footnote-link-5-242" class="footnote-link footnote-identifier-link" title="個人主觀認為, 只要不是笨蛋, 成為合格的 C++ programmer 完全看個人用不用功腦袋轉不轉得過來. 把 TC++PL, Effective C++, More Effective C++ 好好 K 懂個七成上下並加以應用就很強了">5</a></sup> 即便寫不出 STL, 照樣能寫出正確有效率可以維護的 C++ 程式.</p>
<p>Programming language 是一種工具. 選擇一個恰當的工具當看要達成的目的. 需要溝通的時候妳我不會因為不是莎士比亞, 就選擇變成啞巴不說話. 需要低階高效又可高度抽象的 programming language 的時候, 也不要抗拒把 C++ 列為選項.</p>
<p><em>PS: 雖然看起來可能像, 我也知道這篇的標題聽起來的確也像. 與其說這篇文字的重點是在 pro-C++, 更不如說是在鼓勵 programmer 選擇/使用正確的工具. 要做 web service 的時候 php/python 等更可能是較佳的工具. 前面的廢話是我的思路, C++ 只是我舉的例子. (沒辦法, 其他的 programming language 與相關應用不是我的專長)</em></p>
<p><em>PSS: 也許是我有偏見, 事實上我也一直沒去細究, 誰能告訴我用 C# 來寫 OS kernel (見 <a href="http://www.sharpos.org/redmine/wiki/3">SharpOS</a> and <a href="http://gocosmos.org/index.en.aspx">Cosmos</a>) 究竟是怎麼回事? 是因為好玩? 是單純因為 it can be done???</em></p>
<p><em>PSSS: 拿 programming language vs 人類語言做類比多少有點 far-fetched. 但我覺得其中的 analogy 還是有助於表達我的看法.</em></p>
<ol start="1" class="footnotes"><li id="footnote-1-242" class="footnote">先不論 C++ 的定位是 general purpose programming language, 本來就不願意把相對特殊非必須的 library 納入標準 [<a href="#footnote-link-1-242" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-242" class="footnote">這裡所謂的準標準 library 是如 Pthreads, OpenSSL, BSD socket 等<strong>非語言標準</strong>但被廣泛支援/使用的 library/interface/API [<a href="#footnote-link-2-242" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-3-242" class="footnote">有自 C 繼承過來的 <a href="http://en.wikipedia.org/wiki/Procedural_programming">procedural programming</a>, 與一開始就有的 <a href="http://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented programming</a>. 有催生出 STL/Boost/Loki 等的 <a href="http://en.wikipedia.org/wiki/Metaprogramming">metaprogramming</a> (templates). 以及 C++0x 將加入的 <a href="http://en.wikipedia.org/wiki/Functional_programming">functional programming</a> (Lambda Expressions and Closures)  [<a href="#footnote-link-3-242" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-4-242" class="footnote">例如 <a href="http://www.boost.org/doc/libs/1_35_0/doc/html/thread.html">Boost.Thread</a> vs <a href="http://msdn2.microsoft.com/en-us/library/48xz4yz9(VS.71).aspx">CWinThread</a> [<a href="#footnote-link-4-242" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-5-242" class="footnote"><strong>個人主觀認為</strong>, 只要不是笨蛋, 成為合格的 C++ programmer 完全看個人用不用功腦袋轉不轉得過來. 把 <a href="http://www.research.att.com/~bs/3rd.html">TC++PL</a>, <a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010264536">Effective C++</a>, <a href="http://www.books.com.tw/exep/prod/booksfile.php?item=0010264532">More Effective C++</a> 好好 K 懂個七成上下並加以應用就很強了 [<a href="#footnote-link-5-242" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/13/cpp-is-not-privileged-to-language-lawyers/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[五種寫 For Loop 的方法]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/267984797/" />
		<id>http://fsfoundry.org/codefreak/2008/04/11/five-ways-to-write-for-loops/</id>
		<updated>2008-04-29T14:41:58Z</updated>
		<published>2008-04-10T22:23:27Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Boost" /><category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="C++0x" /><category scheme="http://fsfoundry.org/codefreak" term="Coding" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[同樣是寫一個迭代的 loop, 至少有下面兩種標準 (C++98), 兩種半標準 (Boost), 以及一種未來式 (C++0x) 的寫法:


傳統的 for statement
size_t total_size(const list&#60;string&#62;&#038; strings)
{
  size_t total = 0;
  list&#60;string&#62;::const_iterator first = strings.begin();
  list&#60;string&#62;::const_iterator last = strings.end();
  for(;
      first != last;
      ++first)
  {
    total += first->size();
  }
 [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/11/five-ways-to-write-for-loops/"><![CDATA[<p>同樣是寫一個迭代的 loop, 至少有下面兩種標準 (C++98), 兩種半標準 (<a href="http://boost.org">Boost</a>), 以及一種未來式 (C++0x) 的寫法:<br />
<span id="more-240"></span></p>
<ol>
<li>傳統的 <a href="http://msdn2.microsoft.com/en-us/library/b80153d8(VS.71).aspx">for statement</a></li>
<pre><code>size_t total_size(const list&lt;string&gt;&#038; strings)
{
  size_t total = 0;
  list&lt;string&gt;::const_iterator first = strings.begin();
  list&lt;string&gt;::const_iterator last = strings.end();
  for(;
      first != last;
      ++first)
  {
    total += first->size();
  }
  return total;
}</code></pre>
<p>跟其他的方法相比, 手工打造的 for loop 雖然可能最容易寫, 卻也是最容易寫錯的. 不但要人工確保 <code>first</code> 與 <code>last</code> 屬於同一個 sequence,<sup><a href="#footnote-1-240" id="footnote-link-1-240" class="footnote-link footnote-identifier-link" title="不能利用如 MSVC 的 Debug Iterator Support 在執行時期自動報錯">1</a></sup> 更不能忘了要正確地對 <code>first</code> 做 increment.<sup><a href="#footnote-2-240" id="footnote-link-2-240" class="footnote-link footnote-identifier-link" title="不要懷疑, 很遺憾就是有這種 bug&#8230;">2</a></sup></p>
<li><a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=algorith.html#for_each">for_each</a> 加上手寫的 functor</li>
<pre><code>struct accumulator
{
  size_t& result;
  accumulator(size_t&#038; result)
  : result(result) {}

  accumulator&#038; operator()(size_t value)
  {
    result += value;
  }
};
size_t total_size(const list&lt;string&gt;&#038; strings)
{
  size_t total = 0;
  for_each(
    strings.begin(),
    strings.end(),
    accumulator(total));
  return total;
}</code></pre>
<p>這個方法固然避開了方法 1 的缺點. 若大規模的使用, 很可能要寫一堆這種小小的 functor. 不但一點也不優雅, 還很令人困擾.<sup><a href="#footnote-3-240" id="footnote-link-3-240" class="footnote-link footnote-identifier-link" title="至少對我很困擾">3</a></sup></p>
<li>或是 <a href="http://boost.org/doc/libs/1_35_0/doc/html/foreach.html">Boost.Foreach</a></li>
<pre><code>size_t total_size(const list&lt;string&gt;&#038; strings)
{
  size_t total = 0;
  BOOST_FOREACH(const string&#038; str, strings)
  {
    total += str.size();
  }
  return total;
}</code></pre>
<p>Boost.Foreach 是個使用起來簡單明瞭,<sup><a href="#footnote-4-240" id="footnote-link-4-240" class="footnote-link footnote-identifier-link" title="實作可不那麼簡單, 有興趣的請自行挖掘 source code">4</a></sup> 不容易寫錯看起來也漂亮直覺的 macro. 是最佳寫 for loop 的方法之一. 最大的缺點是 - 它是個 macro.</p>
<p>[Update] Boost.Foreach 還有個之前遺漏掉的優點; 它跟真正的 for statement 的 loop 一樣, 可以中途 <code>break</code> 掉.<sup><a href="#footnote-5-240" id="footnote-link-5-240" class="footnote-link footnote-identifier-link" title="也可以 continue, 只是 continue 是很容易模擬的">5</a></sup></p>
<p>[Update] 也可以參考<a href="http://barnesc.blogspot.com/2008/03/c-foreach.html">這裡</a>跟<a href="http://anthony.liekens.net/index.php/Computers/CppForeach">那裡</a>類似的 macro. </p>
<li><a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=algorith.html#for_each">for_each</a> + <a href="http://boost.org/doc/libs/1_35_0/doc/html/lambda.html">Boost.Lambda</a></li>
<pre><code>size_t total_size(const list&lt;string&gt;&#038; strings)
{
  size_t total = 0;
  for_each(
    strings.begin(),
    strings.end(),
    boost::ref(total) +=
      boost::lambda::bind(&#038;string::size, boost::lambda::_1));
  return total;
}</code></pre>
<p><a href="http://fsfoundry.org/codefreak/2006/09/29/boost-lambda/">Boost.Lambda 讓使用者就地產生匿名的 functional object 的功能真的很棒</a>, 免去了寫一堆小小鳥鳥 functor 的糗境. 它不只能與 algorithm 搭配使用, 我就曾在一個 project 大量使用它來就地產生 callback function (event handler).</p>
<p>缺點是想使用它的使用者一定要先用功 K 過<a href="http://boost.org/doc/libs/1_35_0/doc/html/lambda.html">使用手冊</a>.<sup><a href="#footnote-6-240" id="footnote-link-6-240" class="footnote-link footnote-identifier-link" title="仔細想想, 好像沒什麼東西是不先好好用功就可以耍得好的">6</a></sup> 更讓人怯步的是在寫錯時 compiler 吐出來的 error message. 即便是對號稱 C++ 高手的 programmer, 在看與它相關的錯誤訊息的時候都常會覺得正在看一段無法解讀的密碼.</p>
<p>說真的, 除非情非得已, 或是跟我一樣, 不時想要藉由見到鬼的錯誤訊息來自虐一下. 這個方法不見得是最好的選擇. 使用前需先做好心裡建設.</p>
<li id="cpp0x_lambda">在不遠的將來更可以用 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=algorith.html#for_each">for_each</a> 配上 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf">C++0x 的 Lambda Expressions and Closures</a> (PDF)</li>
<pre><code>size_t total_size(const list&lt;string&gt;&#038; strings)
{
  size_t total = 0;
  for_each(
    strings.begin(),
    strings.end(),
    [&#038;](const string&#038; str)
    {
      total += str.size();
    }
  );
  return total;
}</code></pre>
<p>先稍微解釋一下. 一對方括號 (<code>[]</code>) 是用來表示接下來是個 lambda expression. 在方括號內部的 <code>&#038;</code> 符號表示要把外部的變數以 reference 的方式抓 (capture) 到 lambda expression 的內部使用. 因此才能參考並修改到外部的 <code>total</code> 變數. <a href="http://herbsutter.wordpress.com/2008/03/29/trip-report-februarymarch-2008-iso-c-standards-meeting/">Sutter 最近的一篇關於 C++0x 的 blog</a> 有更詳細的說明.</p>
<p>這方法結合了 Boost.Foreach 的簡單容易讀寫, 更融入了 Boost.Lambda 不只能被使用在 for loop 的優點. 最棒的是錯誤訊息應該不再是見到鬼般的難以解讀, 而會是 programmer readable 了. <img src='http://fsfoundry.org/codefreak/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>等 C++0x 正式成為標準, 得到龍頭 compiler 廠商支援後. 我想這將會是最佳 for loop 的作法.
</ol>
<p>[Update] <a href="http://fsfoundry.org/codefreak/2008/04/15/the-free-launch-is-back/">又一個使用 <code>for_each</code> 的有力理由</a>.</p>
<ol start="1" class="footnotes"><li id="footnote-1-240" class="footnote">不能利用如 MSVC 的 <a href="http://msdn2.microsoft.com/en-us/library/aa985982(VS.80).aspx">Debug Iterator Support</a> 在執行時期自動報錯 [<a href="#footnote-link-1-240" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-240" class="footnote">不要懷疑, 很遺憾就是有這種 bug&#8230; [<a href="#footnote-link-2-240" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-3-240" class="footnote">至少對我很困擾 [<a href="#footnote-link-3-240" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-4-240" class="footnote">實作可不那麼簡單, 有興趣的請自行挖掘 source code [<a href="#footnote-link-4-240" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-5-240" class="footnote">也可以 <code>continue</code>, 只是 <code>continue</code> 是很容易模擬的 [<a href="#footnote-link-5-240" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-6-240" class="footnote">仔細想想, 好像沒什麼東西是不先好好用功就可以耍得好的 [<a href="#footnote-link-6-240" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/11/five-ways-to-write-for-loops/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Knock Knock, You&#8217;ve Been Hacked!]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/264787639/" />
		<id>http://fsfoundry.org/codefreak/2008/04/06/hacked/</id>
		<updated>2008-04-05T23:37:14Z</updated>
		<published>2008-04-05T23:31:45Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="English" /><category scheme="http://fsfoundry.org/codefreak" term="FSfoundry.org" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Security" />		<summary type="html"><![CDATA[I received an email yesterday afternoon, informing me this blog has been hacked:
Regarding fsfoundry.org,
This email is not an April&#8217;s fools email and it has been sent to notify you that your blog&#8217;s version is old and needs to be updated ASAP as it was hacked.
While tracking some Viagra spammers I have come accross several links [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/06/knock-knock-you-ve-been-hacked/"><![CDATA[<p>I received an email yesterday afternoon, informing me this blog has been hacked:</p>
<blockquote><p>Regarding fsfoundry.org,</p>
<p>This email is not an April&#8217;s fools email and it has been sent to notify you that your blog&#8217;s version is old and needs to be updated ASAP as it was hacked.</p>
<p>While tracking some Viagra spammers I have come accross several links coming from your blog and, after testing it, it appears your blog is 2.1.* generation hence vulnerable to SQL injection blind-fishing attacks. Search Google to learn more. In a few words: spammers can take full control of your blog in a matter of minutes and deface it at will.</p>
<p>These attacks are as serious as they can get as the spammers have full access to your blog and add hidden HTML elements to mask their links.</p>
<p>You MUST update your blog to the latest official WordPress version and manually clean your last 5-10 posts of the parasite links which you will only see in HTML view.</p>
<p>Not doing so may attract severe search engine penalties as you are currently linking to sites with VERY bad reputation.</p>
<p>Hoping you will take required action,<br />
A.S.S. (Anonymous Security Specialist)</p>
<p>PS: I got your email address from your Dashboard / Users Management Section. I have warned many during the past months regarding the vulnerable blogs, being a blogger myself, but it seems I haven&#8217;t warned everyone. Lateste WordPress is secure.</p>
<p>PPS: Your login name is XXXX and password hash is XXXXXXXXXXXXXXXXXX
</p></blockquote>
<p><span id="more-238"></span><br />
This email was sent to me anonymously, which inevitability made me more or less skeptical. I figured the best way to be sure was by making an examination of my posts manually as suggested.</p>
<p>So I did, and found one of the recent posts has indeed been inserted with a hidden <code>&lt;div&gt;</code> block full of links:</p>
<blockquote><pre><code>&lt;div style="height:1px; width:1px; overflow:hidden"&gt;
&lt;a href="http://www.agentie.info"&gt;agentie de modeling&lt;/a&gt;&lt;br&gt;
&lt;a href="http://bijuterii.ofertalunii.info"&gt;cantar bijuterii&lt;/a&gt;&lt;br&gt;
&lt;a href="http://cariera.e-consiliere.info"&gt;consiliere cariera&lt;/a&gt;&lt;br&gt;
&lt;a href="http://comenzi.pepiata.info"&gt;comenzi de carti&lt;/a&gt;&lt;br&gt;
&lt;a href="http://cumpar.pepiata.info"&gt;cumpar aparat foto&lt;/a&gt;&lt;br&gt;
&lt;a href="http://dormitoare.ofertalunii.info"&gt;dormitor pret&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.e-promotii.info"&gt;promotii la masini&lt;/a&gt;&lt;br&gt;
&lt;a href="http://educatie.e-consiliere.info"&gt;referat educatie&lt;/a&gt;&lt;br&gt;
&lt;a href="http://finantare.proiectenoi.info"&gt;program de finantare&lt;/a&gt;&lt;br&gt;
&lt;a href="http://gestiune.proiectenoi.info"&gt;curs gestiune&lt;/a&gt;&lt;br&gt;
&lt;a href="http://igiena.e-consiliere.info"&gt;igiena casei&lt;/a&gt;&lt;br&gt;
&lt;a href="http://instalatii.ofertalunii.info"&gt;instalatii sonorizare&lt;/a&gt;&lt;br&gt;
&lt;a href="http://investitie.proiectenoi.info"&gt;investitie profitabila&lt;/a&gt;&lt;br&gt;
&lt;a href="http://licitatii.pepiata.info"&gt;formulare licitatii&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.ofertalunii.info"&gt;oferta internet&lt;/a&gt;&lt;br&gt;
&lt;a href="http://optimizare.agentie.info"&gt;optimizare motoare&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.pepiata.info"&gt;piata agricola&lt;/a&gt;&lt;br&gt;
&lt;a href="http://promovare.agentie.info"&gt;plan promovare&lt;/a&gt;&lt;br&gt;
&lt;a href="http://regulament.e-promotii.info"&gt;regulament biliard&lt;/a&gt;&lt;br&gt;
&lt;a href="http://rochii.e-promotii.info"&gt;rochii la moda&lt;/a&gt;&lt;br&gt;
&lt;a href="http://sapard.proiectenoi.info"&gt;agentii sapard&lt;/a&gt;&lt;br&gt;
&lt;a href="http://sursa.proiectenoi.info"&gt;sursa de energie&lt;/a&gt;&lt;br&gt;
&lt;a href="http://tricouri.ofertalunii.info"&gt;tricouri sport&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.proiectenoi.info"&gt;proiecte cercetare&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www1.dietaslabirenutritie.info/"&gt;nutritie cura slabire&lt;/a&gt;&lt;br&gt;
&lt;a href="http://aerobic1.coolsportinfo.info/sitemap.html"&gt;rutine aerobic&lt;/a&gt;&lt;br&gt;
&lt;/div&gt;
</code></pre>
</blockquote>
<p>So yeah, this blog had been hacked,<sup><a href="#footnote-1-238" id="footnote-link-1-238" class="footnote-link footnote-identifier-link" title="The vulnerability exploited was probably this one.">1</a></sup> and upgraded as advised.</p>
<p>Thanks big for the heads up, A.S.S.</p>
<ol start="1" class="footnotes"><li id="footnote-1-238" class="footnote">The vulnerability exploited was probably <a href="https://bugs.launchpad.net/ubuntu/dapper/+source/wordpress/+bug/104944">this</a> <a href="http://www.securityfocus.com/bid/23294">one</a>. [<a href="#footnote-link-1-238" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/06/knock-knock-you-ve-been-hacked/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Mistake in IBM&#8217;s developerWorks]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/263370159/" />
		<id>http://fsfoundry.org/codefreak/2008/04/03/mistake-in-ibms-developerworks/</id>
		<updated>2008-04-05T18:28:06Z</updated>
		<published>2008-04-03T14:47:39Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="*nix" /><category scheme="http://fsfoundry.org/codefreak" term="C" /><category scheme="http://fsfoundry.org/codefreak" term="Cited" /><category scheme="http://fsfoundry.org/codefreak" term="Commentary" /><category scheme="http://fsfoundry.org/codefreak" term="English" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[Some months ago, I came across a mistake in Kernel command using Linux system calls, published by IBM&#8217;s developerWorks.

In the article, a listing of prototypes of two memory copy functions were as shown below:

unsigned long copy_from_user (
    void *to,
    const void __user *from, unsigned long n );
unsigned long copy_to_user [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/03/mistake-in-ibms-developerworks/"><![CDATA[<p>Some months ago, I came across a mistake in <a href="http://www.ibm.com/developerworks/linux/library/l-system-calls/" rel="nofollow">Kernel command using Linux system calls</a>, published by <a href="http://www.ibm.com/developerworks/">IBM&#8217;s developerWorks</a>.<br />
<span id="more-204"></span><br />
In the article, a listing of prototypes of two memory copy functions were as shown below:</p>
<blockquote>
<pre><code>unsigned long copy_from_user (
    void *to,
    const void __user *from, unsigned long n );
unsigned long copy_to_user (
    void *to,
    const void <strong>__user</strong> *from, unsigned long n );
</code></pre>
</blockquote>
<p>The <code>__user</code> annotation, in the second function declaration (copy_to_user), should&#8217;ve been preceded by the first argument (<code>to</code>), but not by the second argument (<code>from</code>). <a href="http://www.gelato.unsw.edu.au/~dsw/public-files/kernel-docs/kernel-api/r4037.html" title="The Linux Kernel API: copy_to_user">Like this</a>:</p>
<blockquote>
<pre><code>unsigned long copy_to_user(
    void <strong>__user</strong> * to,
    const void * from, unsigned long n);
</code></pre>
</blockquote>
<p>I had submitted a comment regarding the mistake months ago. However, it remains uncorrected at the time of posting.</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/03/mistake-in-ibms-developerworks/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[懷舊: WRC 2001 Teaser]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/263356847/" />
		<id>http://fsfoundry.org/codefreak/2008/04/03/retrospect-wrc-2001-teaser/</id>
		<updated>2008-04-13T05:34:00Z</updated>
		<published>2008-04-03T14:23:23Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Video" /><category scheme="http://fsfoundry.org/codefreak" term="技術狂也是人" />		<summary type="html"><![CDATA[


這世界上還有比把自己的性命托付給不要命的 WRC 駕駛, 坐在他的旁邊當他的副駕駛來得更瘋狂的事情嗎?
聽著這首 Linkin Park 的 In The End&#8230; 呵呵&#8230; 是啊~ 那一年, 我也開著一部 Impreza.
]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/03/retrospect-wrc-2001-teaser/"><![CDATA[<p><object width="415" height="350">
<param nam托付e="movie" value="http://www.youtube.com/v/4XKp00hWWAk&#038;color1=0xffffdd&#038;color2=0xffffdd"></param>
<param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/4XKp00hWWAk&#038;color1=0xffffdd&#038;color2=0xffffdd" type="application/x-shockwave-flash" wmode="transparent" width="415" height="350"></embed></object></p>
<p>這世界上還有比把自己的性命托付給不要命的 WRC 駕駛, 坐在他的旁邊當他的副駕駛來得更瘋狂的事情嗎?</p>
<p>聽著這首 <a href="http://en.wikipedia.org/wiki/Linkin_Park">Linkin Park</a> 的 <a href="http://www.last.fm/music/Linkin+Park/_/In+the+End">In The End</a>&#8230; 呵呵&#8230; 是啊~ 那一年, <a href="http://fsfoundry.org/codefreak/2006/06/09/the-ghost-of-my-past/">我也開著一部 Impreza</a>.</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/03/retrospect-wrc-2001-teaser/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[有趣的 Gmail 地址小技巧]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/263339706/" />
		<id>http://fsfoundry.org/codefreak/2008/04/03/interesting-gmail-address-tip/</id>
		<updated>2008-04-03T13:30:45Z</updated>
		<published>2008-04-03T13:30:03Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Cited" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[在 MakeUseOf 看到一個很有趣, 適用於 gmail 的 email address 的小技巧.
假設你的 gmail 帳號是 yourid@gmail.com, 送到下列 email address 的 email 都會被 forward 到你的信箱:


your.id@gmail.com (or your.id@googlemail.com)
y.our.id@gmail.com (or y.our.id@googlemail.com)
you.r.id@gmail.com (or you.r.id@googlemail.com)
&#8230;

如果是你的帳號是 immortal [小老鼠] gmail [點] com, 就可以玩像是 i.m.mortal [小老鼠] gmail [點] com 這類的文字遊戲.
這還沒完, 你還能在 gmail address 嵌入其他的文字. 只要在你的 ID 與 @ (小老鼠符號) 中間加上個 + (加號), 然後就可以 + 與 @ 中間插入你要的文字. [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/04/03/interesting-gmail-address-tip/"><![CDATA[<p>在 <a href="http://www.makeuseof.com/">MakeUseOf</a> 看到一個很有趣, <a href="http://www.makeuseof.com/tag/1-awesome-gmail-tip-you-dont-know-about-seriously/">適用於 gmail 的 email address 的小技巧</a>.</p>
<p>假設你的 <a href="http://mail.google.com">gmail</a> 帳號是 yourid@gmail.com, 送到下列 email address 的 email 都會被 forward 到你的信箱:</p>
<table>
<ul>
<li>your.id@gmail.com (or your.id@googlemail.com)</li>
<li>y.our.id@gmail.com (or y.our.id@googlemail.com)</li>
<li>you.r.id@gmail.com (or you.r.id@googlemail.com)</li>
<li>&#8230;</li>
</ul>
<p>如果是你的帳號是 immortal [小老鼠] gmail [點] com, 就可以玩像是 i.m.mortal [小老鼠] gmail [點] com 這類的文字遊戲.</p>
<p>這還沒完, 你還能在 gmail address 嵌入其他的文字. 只要在你的 ID 與 @ (小老鼠符號) 中間加上個 + (加號), 然後就可以 + 與 @ 中間插入你要的文字. 送到這些 email address 的 email 也一樣會被 forward 到你的信箱:</p>
<ul>
<li>yourid+spam@gmail.com</li>
<li>yourid+music@gmail.com</li>
<li>yourid+friends@gmail.com</li>
<li>&#8230;</li>
</ul>
<p>如此便可以很容易的用 To 欄位來設定你的 filter.</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/04/03/interesting-gmail-address-tip/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Source Code [Benchmarking Sequential Iterators]]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/253077604/" />
		<id>http://fsfoundry.org/codefreak/2008/03/17/source-code-benchmarking-sequential-iterators/</id>
		<updated>2008-04-05T18:17:31Z</updated>
		<published>2008-03-17T15:39:33Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Coding" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[Source code used to produce results in my previous post is available for download here.
Please note that Boost.Date_Time is required in order to build it.
]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/03/17/source-code-benchmarking-sequential-iterators/"><![CDATA[<p>Source code used to produce results in my <a href="http://fsfoundry.org/codefreak/2008/03/16/benchmarking-sequential-iterators/">previous post</a> is available for download <a href="http://fsfoundry.org/freak/biter.cpp">here</a>.</p>
<p>Please note that <a href="http://boost.org/doc/html/date_time.html">Boost.Date_Time</a> is required in order to build it.</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/03/17/source-code-benchmarking-sequential-iterators/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Benchmarking Sequential Iterators]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/252266992/" />
		<id>http://fsfoundry.org/codefreak/2008/03/16/benchmarking-sequential-iterators/</id>
		<updated>2008-03-28T03:50:23Z</updated>
		<published>2008-03-16T04:20:01Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[這幾天有空, 終於把一項幾個月前就開始做的 benchmark 完成了.

看過好幾次有同事的 code, 明明就是使用 vector 來管理一串 element, 卻硬要把被管理的 element 的 pointer 取出, 以代替 vector 本身的 iterator 來做迭代. 有些同事說是不熟悉 iterator 的特性與操作方式. 這個理由很難讓人接受. 身為職業 C++ programmer, 標準的 container 與 iterator 是無論如何也要掌握住的技巧. 促成我搞這個 benchmark 的原因是有另外的同事跟我說, 取 pointer 出來迭代是因為 vector 的 iterator 比 pointer 慢很多, 並且是指數級別的差距!
在進行這項 benchmark 之前, 說以 vector 的 iterator 迭代比 pointer 慢, (起碼不會快過 pointer) [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2008/03/16/benchmarking-sequential-iterators/"><![CDATA[<p>這幾天有空, 終於把一項幾個月前就開始做的 benchmark 完成了.</p>
<hr/>
看過好幾次有同事的 code, 明明就是使用 <code>vector</code> 來管理一串 element, 卻硬要把被管理的 element 的 pointer 取出, 以代替 <code>vector</code> 本身的 iterator 來做迭代. 有些同事說是不熟悉 iterator 的特性與操作方式. 這個理由很難讓人接受. 身為職業 C++ programmer, 標準的 container 與 iterator 是無論如何也要掌握住的技巧. 促成我搞這個 benchmark 的原因是有另外的同事跟我說, 取 pointer 出來迭代是因為 <code>vector</code> 的 iterator 比 pointer 慢很多, 並且是指數級別的差距!</p>
<p>在進行這項 benchmark 之前, 說以 <code>vector</code> 的 iterator 迭代比 pointer 慢, (起碼不會快過 pointer) 我絕對不會意外. 我猜大多數人也預期會看這樣的結果. 即便如此, 我還是很難想像其差異會大到如一位同事告訴我的. 因此我寫了個程式來 benchmark. 將 pointer 以及各種 STL 的 sequence container<sup><a href="#footnote-1-234" id="footnote-link-1-234" class="footnote-link footnote-identifier-link" title="測完後才發現漏掉了 basic_string">1</a></sup> 的 iterator 做同樣的迭代, 把所使用的時間紀錄下來, 製作成表格以比較其間差異. 讓數字來說話.<br />
<span id="more-234"></span><br />
由於我手上沒有機器上有 GNU/Linux 與 Windows 的 dual boot, 也不想在 VM 上測試. 所以只能讓兩個平台的測試跑在不同的機器上. GNU/Linux 上的測試用的是我的手提電腦,  Windows 的測試用的是工作的 workstation.</p>
<p>測試程式的內容是將 32 Mega (1024*1024) 個 integer 迭代兩個回合. 第一回先將其全部指派為 1. 第二回再將它們指派為 0. 所有的測試都是跑十次, 然後取平均時間, 順便紀錄這十次中最快的時間與最慢的時間以供參考.</p>
<p>這個測試刻意將 memory allocation 與 container 在被創建時或是 <code>resize()</code> 時, 啟始其管理的 element 的過程排除. 讓這個測試儘量只針對迭代的部份計時.</p>
<p>前兩組 benchmark (Table 1 and Table 2) 是在 GNU/Linux 下產生的結果, 測試環境如下:</p>
<ul>
<table>
<tr>
<td>CPU:</td>
<td>INTEL CORE DUO T2400/1.83G</td>
</tr>
<tr>
<td>RAM:</td>
<td>2G</td>
</tr>
<tr>
<td>OS:</td>
<td>Ubuntu 7.10</td>
</tr>
<tr>
<td>Compiler:</td>
<td>GCC 4.13</td>
</tr>
</table>
</ul>
<p>後面兩組 benchmark (Table 3 and Table 4) 是 Windows 的結果, 測試環境如下:</p>
<ul>
<table>
<tr>
<td>CPU:</td>
<td>INTEL CORE 2 DUO E8400/3.0G</td>
</tr>
<tr>
<td>RAM:</td>
<td>2G</td>
</tr>
<tr>
<td>OS:</td>
<td>XP</td>
</tr>
<tr>
<td>Compiler:</td>
<td>MSVC 2005</td>
</tr>
</table>
</ul>
<h3>Benchmark 1</h3>
<p>先來檢視 GNU/Linx 上的第一組測試結果.</p>
<table border="1" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="266" /><col width="99" /><col width="99" /><col width="99" /><col width="99" /></colgroup>
<tr class="ro1">
<td style="text-align:left;width:2.3992in; " class="ce1">
<p>OS</p>
<p>Compiler</p>
<p>Compiler flag(s)</p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Iterator Type </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Average </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Fastest </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Slowest </p>
</td>
</tr>
<tr class="ro2">
<td rowspan="4" style="text-align:left;width:2.3992in; " class="ce2">
<p><span class="T1">Ubuntu 7.10</span></p>
<p><span class="T1">GCC 4.1.3</span></p>
<p>-g </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>pointer </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.581 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.536 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.641 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>vector </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.521 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.493 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.552 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>deque </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.796 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.185 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.981 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>list </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.247 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.168 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>1.381 </p>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
<tfoot>
<div align="center">Table 1.</div>
</tfoot>
</table>
<p>這組 benchmark 沒有使用 GCC 的優化 (-O), 沒有定義 NDEBUG, (也就說會把 <code>assert()</code> 所花的時間也算進來, if any) 並加使用 -g 以在產出的執行檔加上 debug symbol.<sup><a href="#footnote-2-234" id="footnote-link-2-234" class="footnote-link footnote-identifier-link" title="加上 -g 只是方便需要時可以 trace code, 不清楚這會不會對測試產生影響">2</a></sup></p>
<p>從這個表上很容易可以看出來, pointer 明顯是最快的. 表中其他三種 iterator 所花的時間則介於 pointer 的 2.15 倍到 3.09 倍之間.</p>
<p>這裡有一個有趣的現象, <code>list</code> iterator 的迭代竟然較除了 pointer 之外的其他兩種 random access iterator 都來的快. 除此之外這組結果大都還容易解讀, 接近大部份人對它們的印象.</p>
<h3>Benchmark 2</h3>
<p>接下來這組測試結果更有意思了. 這次除了編譯時給 GCC 的參數不同之外, 測試方法與測試環境都跟第一組測試相同.</p>
<table border="1" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="266" /><col width="99" /><col width="99" /><col width="99" /><col width="99" /></colgroup>
<tr class="ro1">
<td style="text-align:left;width:2.3992in; " class="ce1">
<p>OS</p>
<p>Compiler</p>
<p>Compiler flag(s)</p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Iterator Type </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Average </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Fastest </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>Slowest </p>
</td>
</tr>
<tr class="ro2">
<td rowspan="4" style="text-align:left;width:2.3992in; " class="ce2">
<p><span class="T1">Ubuntu 7.10</span></p>
<p><span class="T1">GCC 4.1.3</span></p>
<p><span class="T1">-O -DNDEBUG</span></p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>pointer </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.273 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.256 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.287 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>vector </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.204 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.194 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.211 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>deque </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.205 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.191 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.224 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce7">
<p>list </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.787 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.763 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce8">
<p>0.861 </p>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
<tfoot>
<div align="center">Table 2.</div>
</tfoot>
</table>
<p>在 -O 的加持下, 果然讓所有 iterator 的速度都比上一組測試時得到的成績好了很多.</p>
<p>這次 <code>list</code> 的成績如預期的殿了後. <code>vector</code> 與 <code>deque</code> 幾乎是不相上下, 打了個平手. 叫我跌破眼鏡的是它們居然都比 pointer 還快! 硬是把 pointer 擠到第三名! 雖說 pointer 只比它們慢約 0.068 秒, 但畢竟是穩定的慢上三分之一左右的時間.</p>
<p>一開始觀察到這現象時, 第一個想法就是我那裡做錯了, 接著試了好幾個版本的迭代算法來 benchmark, 結果還是一致. 在後面的第四組測試數字也會看到類似的現象. 這樣的結果讓我不知道該如何解讀. 苦惱中&#8230;</p>
<h3>Benchmark 3</h3>
<p>接下來讓我們轉台到 Windows.</p>
<table border="1" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="266" /><col width="99" /><col width="99" /><col width="99" /><col width="99" /></colgroup>
<tr class="ro1">
<td style="text-align:left;width:2.3992in; " class="ce1">
<p>OS</p>
<p>Compiler</p>
<p>Configuration</p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Iterator Type </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Average </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Fastest </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Slowest </p>
</td>
</tr>
<tr class="ro2">
<td rowspan="4" style="text-align:left;width:2.3992in; " class="ce1">
<p><span class="T1">XP</span></p>
<p><span class="T1">MSVC 2005 w/SP1</span></p>
<p><span class="T2">Debug Build</span></p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>pointer </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.324 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.313 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.344 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>vector </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.302 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.256 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.360 </p>
</td>
</tr>
<tr class="ro3">
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>deque </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.558 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.529 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.607 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>list </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>19.245 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>3.876 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>65.244 </p>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
<tfoot>
<div align="center">Table 3.</div>
</tfoot>
</table>
<p>這組測試的名次是這次所有測試結果中最符合我預期的, 而且也讓我看到同事說的指數級的差距. Pointer 比 <code>vector</code> 快了十倍! 果然真的是這樣.</p>
<p>這組測試結果最困擾我的地方是 <code>list</code> 的十次測試結果非常不穩定. 最快與最慢的時間的差異幾乎是十六倍. 很遺憾的是我一直沒有機會在其他機器上跑這 <code>list</code> 的測試. 很想知道會不會是機器又或是我的系統的問題, 而造成這樣不穩定的結果?</p>
<h3>Benchmark 4</h3>
<table border="1" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="266" /><col width="99" /><col width="99" /><col width="99" /><col width="99" /></colgroup>
<tr class="ro1">
<td style="text-align:left;width:2.3992in; " class="ce1">
<p>OS</p>
<p>Compiler</p>
<p>Configuration</p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Iterator Type </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Average </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Fastest </p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce5">
<p>Slowest </p>
</td>
</tr>
<tr class="ro2">
<td rowspan="4" style="text-align:left;width:2.3992in; " class="ce1">
<p><span class="T1">XP</span></p>
<p><span class="T1">MSVC 2005 w/SP1</span></p>
<p><span class="T2">Release Build</span></p>
</td>
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>pointer </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.159 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.156 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.172 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>vector </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.130 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.125 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.141 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>deque </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.297 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.297 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.297 </p>
</td>
</tr>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="ce6">
<p>list </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.806 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.797 </p>
</td>
<td style="text-align:right; width:0.8925in; " class="ce7">
<p>0.813 </p>
</td>
</tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
</table>
<table border="0" cellspacing="0" cellpadding="0" class="ta1">
<colgroup><col width="99" /></colgroup>
<tr class="ro2">
<td style="text-align:left;width:0.8925in; " class="Default" /></tr>
<tfoot>
<div align="center">Table 4.</div>
</tfoot>
</table>
<p>在第四組測試又看到跟第二組測試一樣的現象. <code>vector</code> 的 iterator 比 pointer 還快. 到底是什麼原因造成這個現象? 我目前可是一點頭緒也沒有.</p>
<p>眼尖的人看到這兩組 Windows 上得到的數字可能會想; MSVC 會不會太猛了? 怎麼 Release build 優化的結果可以比 Debug build 快上這麼多? 差異最少的 pointer 都快了一倍. 進步第二少的 <code>deque</code> 更是快上近 12 倍!</p>
<p>Release build 的優化是會起一定的作用, 但造成這樣的差距更重要的原因是我所使用的這個版本的 MSVC 所附帶的 standard library 在 Debug build 模式下會自動 <code>#define <a href="http://msdn2.microsoft.com/en-us/library/aa985939(VS.80).aspx">_HAS_ITERATOR_DEBUGGING</a> 1</code>.</p>
<p>在 <code>_HAS_ITERATOR_DEBUGGING</code> 被 define 成 1 的情況下, (Debug build 的預設狀態) MSVC 的 debug runtime library 會在執行時期做如 iterator 越界以及驗證一對用來表示一個 range 的 iterator 是否屬於同一個 sequence 等的檢查. 於是效能就比沒這額外執行時期檢查的 Release build (或是 <code>_HAS_ITERATOR_DEBUGGING</code> 被 define 成 0 的 Debug build) 慢上很多很多. 在我的機器上只要在 project setting 的 Debug build 的 preprocessor 設定加上 <code>_HAS_ITERATOR_DEBUGGING=0</code>, 用這次的 benchmark 程式也可以一樣得到 <code>vector</code> 的 iterator 比 pointer 還快的結果.</p>
<h3>Conclusion</h3>
<p>這次的 benchmark 釐清了不少事情, 這些數字說了這麼多話, 也在我心裡留下新的問號.<sup><a href="#footnote-3-234" id="footnote-link-3-234" class="footnote-link footnote-identifier-link" title="寫累了, 晚些時候再把 benchmark 用的 source code 整理一下後放上來, 請有興趣的朋友一起玩玩, 幫忙研究驗證一下">3</a></sup></p>
<p>其中至少有一件事是肯定的, <code>vector</code> 的 iterator 在優化後 (-O in GCC or Release build in MSVC) 的速度是很快的. 別再捨 iterator 而就 pointer 了.</p>
<p>Update: <a href="http://fsfoundry.org/codefreak/2008/03/17/source-code-benchmarking-sequential-iterators/">Source code 可以下載了</a>.</p>
<ol start="1" class="footnotes"><li id="footnote-1-234" class="footnote">測完後才發現漏掉了 <code>basic_string</code> [<a href="#footnote-link-1-234" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-234" class="footnote">加上 -g 只是方便需要時可以 trace code, 不清楚這會不會對測試產生影響 [<a href="#footnote-link-2-234" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-3-234" class="footnote">寫累了, 晚些時候再把 benchmark 用的 source code 整理一下後放上來, 請有興趣的朋友一起玩玩, 幫忙研究驗證一下 [<a href="#footnote-link-3-234" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2008/03/16/benchmarking-sequential-iterators/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[拒絕 Singleton]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/198721597/" />
		<id>http://fsfoundry.org/codefreak/2007/12/12/say-no-to-singleton/</id>
		<updated>2008-04-12T19:40:57Z</updated>
		<published>2007-12-11T17:32:03Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Tutorial" />		<summary type="html"><![CDATA[去年我寫過一篇文章, 大意是在說 大多數人所使用的 Singleton 實作都是有問題的.  在文章靠近後面的部份, 我也介紹了一種較少為人知, 我常用在 lifetime 是全局但 scope 是局部的 (global) 變數的 Singleton 實作. 雖然這實作離 fool proof 還差得遠, 在使用者能夠正確地 include header 的情況下, 它可能已經是最接近 bullet proof 的實作了.
&#8220;好吧, 那我就用類似你的 Singleton 實作總行了吧!?&#8221; 先別急著動手改 code, 實作是容易更換的, 但使用 Singleton Pattern 的原因卻與更重要的介面, 甚至架構的設計思維息息相關. 工作的實務經驗以及本身的興趣研究讓我體會到, 大多數的情況下 Singleton 的使用是可以避免的. 在這些非必要情況卻依然採用 Singleton 的原因常是:

沒把問題想清楚
好玩
因為有個叫作 Singleton 的 pattern


有心學好寫好 C++ 的人可能不少都經歷過這個階段, 或許是為了好玩, 也可能是為了證明自己也可以做出好輪子. 在一本書一個網站上看到有趣的東西就自己也做一套出來.1 [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2007/12/12/say-no-to-singleton/"><![CDATA[<p>去年我寫過一篇文章, 大意是在說 <a href="http://fsfoundry.org/codefreak/2006/05/05/is-your-singleton-broken/" title="Is your Singleton Broken?">大多數人所使用的 Singleton 實作<strong>都是有問題的</strong></a>.  在文章靠近後面的部份, 我也介紹了一種較少為人知, 我常用在 lifetime 是全局但 scope 是局部的 (global) 變數的 Singleton 實作. 雖然這實作離 fool proof 還差得遠, 在使用者能夠正確地 include header 的情況下, 它可能已經是最接近 bullet proof 的實作了.</p>
<p>&#8220;好吧, 那我就用類似你的 Singleton 實作總行了吧!?&#8221; 先別急著動手改 code, 實作是容易更換的, 但使用 <a href="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton Pattern</a> 的原因卻與更重要的介面, 甚至架構的設計思維息息相關. 工作的實務經驗以及本身的興趣研究讓我體會到, 大多數的情況下 Singleton 的使用是可以避免的. 在這些非必要情況卻依然採用 Singleton 的原因常是:</p>
<ul>
<li>沒把問題想清楚</li>
<li>好玩</li>
<li>因為有個叫作 Singleton 的 pattern</li>
</ul>
<p><span id="more-229"></span><br />
有心學好寫好 C++ 的人可能不少都經歷過這個階段, 或許是為了好玩, 也可能是為了證明自己也可以做出好輪子. 在一本書一個網站上看到有趣的東西就自己也做一套出來.<sup><a href="#footnote-1-229" id="footnote-link-1-229" class="footnote-link footnote-identifier-link" title="至少我是幹了好幾回的 :P">1</a></sup> 這個階段對個人的編程技巧的成長很可能會有一定程度的幫助. 但做了就把它拿來用在 project 上, 或是自以為需要就抄來用在 project 上, 又或是認為用了 pattern 的程式就是較好的, 這樣的行為與認知其實更容易對 project 產生負面的影響. 尤其當使用的 pattern 是 Singleton Pattern 的時候.</p>
<p>不談之前討論過不同的 Singleton 實作上的問題, 缺陷或盲點. Singleton Pattern 的實作多是只要 include 了 header, 每段 code 都可以 access 到某個 instance. 而 access 到該 instance 的時候, 它會處於初始化已經完成的狀態.<sup><a href="#footnote-2-229" id="footnote-link-2-229" class="footnote-link footnote-identifier-link" title="先不論後者是需要有正確的 Singleton 實作才可能可以給這樣的保證">2</a></sup> 使用這樣的 singleton 跟使用一個全局的 <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">default constructible</a>, 或是有初始值的 global variable 在架構上幾乎沒有區別.<sup><a href="#footnote-3-229" id="footnote-link-3-229" class="footnote-link footnote-identifier-link" title="除了 initialized on reference 等實作層次上的安全之外">3</a></sup> 不是用個有響亮名字的 pattern 把 global variable 包裝起來就比直接使用 global variable 好到那裡去.</p>
<p>如果你不認同 global variable 的使用是一種漂亮的手法, 你也該一並鄙視全局的 singleton. 至少要以懷疑的眼光去檢視程式採用 Singleton Pattern 真正的原因.</p>
<ol start="1" class="footnotes"><li id="footnote-1-229" class="footnote">至少我是幹了好幾回的 :P [<a href="#footnote-link-1-229" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-229" class="footnote">先不論後者是需要有<strong>正確</strong>的 Singleton 實作才可能可以給這樣的保證 [<a href="#footnote-link-2-229" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-3-229" class="footnote">除了 initialized on reference 等實作層次上的安全之外 [<a href="#footnote-link-3-229" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2007/12/12/say-no-to-singleton/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[WIN32 的 _TCHAR 與 std::wstring 的問題]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/187310086/" />
		<id>http://fsfoundry.org/codefreak/2007/11/20/problem-with-win32-tchar-and-std-wstring/</id>
		<updated>2007-11-20T06:54:59Z</updated>
		<published>2007-11-19T19:28:14Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" /><category scheme="http://fsfoundry.org/codefreak" term="Tutorial" /><category scheme="http://fsfoundry.org/codefreak" term="不客觀觀點" />		<summary type="html"><![CDATA[我知道很多人一直是這樣做的, 可是我從沒搞懂為什麼在 windows 平台上, 用上了 _TCHAR, _TEXT 再 define 個 _UNICODE. 或是用上了 whar_t 與 std::wstring. 就能算是 Unicode 化的程式?

Unicode 說穿了就是一種 數字到字元的對應. 而 UTF-8/UTF-16/UTF-32 等則是 Unicode 這種數字的編碼方式, 也就是同一個 (能對應 Unicode 字元的) 數字在不同的編碼下會是不同的 byte sequence.
在 WIN32 平台上, wchar_t 是個 16-bits 的型別.1 很明顯地, 它最多只能 (事實上應該也是) 對應到 Unicode 中的 UTF-16 編碼.
UTF-16 定義了約十一萬個字元.2 Wikipedia 也提到 UTF-16 是一種可變長度的編碼. 由此可見, 一個 WIN32 下的 [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2007/11/20/problem-with-win32-tchar-and-std-wstring/"><![CDATA[<p>我知道很多人一直是這樣做的, 可是我從沒搞懂為什麼在 windows 平台上, 用上了 <a href="http://msdn2.microsoft.com/en-us/library/c426s321(vs.71).aspx">_TCHAR, _TEXT 再 define 個 _UNICODE</a>. 或是用上了 whar_t 與 std::wstring. 就能算是 <a href="http://unicode.org/" rel="lightbox">Unicode</a> 化的程式?<br />
<span id="more-231"></span><br />
Unicode 說穿了就是一種 <strong>數字到字元的對應</strong>. 而 <a href="http://www.ietf.org/rfc/rfc2279.txt">UTF-8</a>/<a href="http://www.ietf.org/rfc/rfc2781.txt">UTF-16</a>/UTF-32 等則是 Unicode 這種數字的編碼方式, 也就是同一個 (能對應 Unicode 字元的) 數字在不同的編碼下會是不同的 byte sequence.</p>
<p>在 WIN32 平台上, wchar_t 是個 16-bits 的型別.<sup><a href="#footnote-1-231" id="footnote-link-1-231" class="footnote-link footnote-identifier-link" title="Default 似乎還不是 built-in/primitive, 而是個 得 include stddef.h/stdlib.h 或&#8230; 的 typedef">1</a></sup> 很明顯地, 它最多只能 (事實上應該也是) 對應到 Unicode 中的 <a href="http://www.ietf.org/rfc/rfc2781.txt">UTF-16</a> 編碼.</p>
<p><a href="http://unicode.org/faq/utf_bom.html#9" rel="lightbox">UTF-16 定義了約十一萬個字元</a>.<sup><a href="#footnote-2-231" id="footnote-link-2-231" class="footnote-link footnote-identifier-link" title="另外在 rfc2781 的 Section 2 也說明了 UTF-16 無法表示值大於 0&#215;10FFFF 的 Unicode">2</a></sup> Wikipedia 也提到 <a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16 是一種可變長度的編碼</a>. 由此可見, 一個 WIN32 下的 whar_t 沒有辦法總是以一個 16-bits (最大值為 2^16 -1, 也就是 65535) 的數字來代表十一萬種字元.</p>
<p>由此可以知道一個 WIN32 的 wchar_t 是無法完全對應到一個 UTF-32 的 Unicode 字元. 所以類似下面的操作:</p>
<pre><code>
utf_32_char_t get_utf_32_char(const std::wstring&#038; wstr, size_t n)
{
  assert(wstr.size() > n);
  return wstr[n];
}
</code></pre>
<p>並無法正確的對應到位於 <code>n</code> 位置的 Unicode 字元. 程式還是必須從 wstr 的頭掃描到第 n 個 Unicode 才能正確將一個 UTF-16 編碼的字元轉為 UTF-32 的字元. Windows 的 wchar_t 的優點或用處到底在那裡?</p>
<p>我看來是這只是偷懶的行為, 假裝每一個 WIN32 的 wchar_t 可以代表任意一個 UTF-16 的字元. 跟鴕鳥把頭躲進沙坑逃避現實的的行為沒什麼差異.</p>
<p>PS. 我對 Unicode 沒有特別研究, 上面應該有很多 Unicode 術語都用錯了. 但 concept 應該沒問題.</p>
<hr/>
[Update: Nov 20, 2007 at 14:40]</p>
<p>感謝 <a href="http://fsfoundry.org/codefreak/2007/11/20/problem-with-win32-tchar-and-std-wstring/#comment-3987">Jeff 在回應裏面提到 Windows 的 wchar_t 是對應到 UCS-2</a>, 而不是 UTF-16.<sup><a href="#footnote-3-231" id="footnote-link-3-231" class="footnote-link footnote-identifier-link" title="What is the difference between UCS-2 and UTF-16?">3</a></sup> 這下子我可能有點搞懂了. UCS-2 的確就只能表達 <a href="http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Basic_Multilingual_Plane" rel="lightbox">Basic Multilingual Plane</a> (BMP), 也就是 Unicode 中的 0&#215;0000~0xFFFF. 以一個 16-bits 的整數是來表達 BMP 是 just make.</p>
<p>無法表達超出 BMP 的 Unicode, 這是 WIN32 的先天限制? 所謂的 Unicode API 也不真的那麼 Unicode, 是嗎?</p>
<p>好吧, 如果永遠活在 WIN32 的世界下這樣似乎也可行. 可是如果是從別的地方 (譬如透過網路) 傳過來一個非 BMP 的 Unicode 的字元時怎麼辦? 下面的 code 該怎麼寫?</p>
<pre><code>
wchar_t utf8_to_ucs2(const char* utf8)
{
  if(is_bmp(utf8) == true)
  {
    wchar_t usc2;
    // fine here, we just need an algorithm to transcode
    // a UTF-8 encoded BMP code point (character) to UCS-2
    return usc2;
  }
  else
  {
    // what goes here?
    // what to do if the code point is not a BMP?
  }
}
</code></pre>
<ol start="1" class="footnotes"><li id="footnote-1-231" class="footnote">Default 似乎還不是 built-in/primitive, 而是個 <a href="http://msdn2.microsoft.com/en-us/library/323b6b3k(VS.80).aspx">得 include stddef.h/stdlib.h 或&#8230; 的 typedef</a> [<a href="#footnote-link-1-231" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-2-231" class="footnote">另外在 <a href="http://www.ietf.org/rfc/rfc2781.txt">rfc2781</a> 的 Section 2 也說明了 UTF-16 無法表示值大於 0&#215;10FFFF 的 Unicode [<a href="#footnote-link-2-231" class="footnote-link footnote-back-link">↩</a>]</li><li id="footnote-3-231" class="footnote"><a href="http://www.unicode.org/faq/basic_q.html#25" rel="lightbox">What is the difference between UCS-2 and UTF-16?</a> [<a href="#footnote-link-3-231" class="footnote-link footnote-back-link">↩</a>]</li></ol>]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2007/11/20/problem-with-win32-tchar-and-std-wstring/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[忙茫盲？]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/183632181/" />
		<id>http://fsfoundry.org/codefreak/2007/11/13/busy-a-bian/</id>
		<updated>2007-11-12T16:21:33Z</updated>
		<published>2007-11-12T16:17:48Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Cited" /><category scheme="http://fsfoundry.org/codefreak" term="Funny" /><category scheme="http://fsfoundry.org/codefreak" term="Video" /><category scheme="http://fsfoundry.org/codefreak" term="技術狂也是人" /><category scheme="http://fsfoundry.org/codefreak" term="政治" />		<summary type="html"><![CDATA[阿扁到底是忙? 是茫? 還是盲?

以下轉自 總統很忙？ &#171; Odds@Blog:
總統很忙，到底在忙些什麼，忙著被嗆聲嗎？



歌詞：
嗚啦啦啦膽水逼 做宗痛做得歡喜 全家人衣食無虞 吳淑珍不用出庭
兩顆子彈拼選舉 八年做完任期 小車的定義是三千嘻嘻 嘻哈～
選舉不用拼經濟 國家尊嚴擺第一 人民不是豬狗雞  巴豆妖也不要緊
執政八年沒政績 要下台前請你 先順便餵飽台灣老百姓 嘻哈～
不用凍蒜了不用凍蒜了 不用凍蒜不用凍蒜了…..

]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2007/11/13/busy-a-bian/"><![CDATA[<p>阿扁到底是忙? 是茫? 還是盲?<br />
<span id="more-227"></span><br />
以下轉自 <a href="http://andyblog.wordpress.com/2007/11/11/%e7%b8%bd%e7%b5%b1%e5%be%88%e5%bf%99%ef%bc%9f/">總統很忙？</a> &laquo; <a href="http://andyblog.wordpress.com/">Odds@Blog</a>:</p>
<blockquote><p><a href="http://ipk.im.tv/mdis.php?code=111">總統很忙，到底在忙些什麼，忙著被嗆聲嗎？</a><br />
<object width="425" height="373">
<param name="movie" value="http://www.youtube.com/v/y4fAom0zRL8&#038;color1=0x3a3a3a&#038;color2=0x999999&#038;border=1"></param>
<param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/y4fAom0zRL8&#038;color1=0x3a3a3a&#038;color2=0x999999&#038;border=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="373"></embed></object><br />
歌詞：<br />
嗚啦啦啦膽水逼 做宗痛做得歡喜 全家人衣食無虞 吳淑珍不用出庭<br />
兩顆子彈拼選舉 八年做完任期 小車的定義是三千嘻嘻 嘻哈～<br />
選舉不用拼經濟 國家尊嚴擺第一 人民不是豬狗雞  巴豆妖也不要緊<br />
執政八年沒政績 要下台前請你 先順便餵飽台灣老百姓 嘻哈～<br />
不用凍蒜了不用凍蒜了 不用凍蒜不用凍蒜了…..</p>
</blockquote>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2007/11/13/busy-a-bian/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[Deque as Default Container]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/183588117/" />
		<id>http://fsfoundry.org/codefreak/2007/11/12/deque-as-default-container/</id>
		<updated>2007-11-12T14:23:07Z</updated>
		<published>2007-11-12T14:23:07Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="C++" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[搞不清楚 list, vector 與 deque 的差異?
最好的方法當然是能深入了解 C++ Standard 對它們的規範. 否則可以參考下面幾個 check point:

Container 所包含的 (element) sequence 在 memory 的 layout 必須是連續的. 唯一的選擇是 vector
需要 iterator 的位置在插入一個新的 element 或 remove 另一個 element 之後保持有效. 只有 list 能滿足這需求
常在 sequence 中間 (非頭尾) 位置 insert 或 remove. list 會是較好的選擇
vector 與 deque 都可以滿足以隨機方式存取 sequence 中的 element. 唯前者效能較好 (constant time)
在還沒確認需求時, 建議以 deque 做為 default [...]]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2007/11/12/deque-as-default-container/"><![CDATA[<p>搞不清楚 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=list.html#list"><code>list</code></a>, <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=vector.html#vector"><code>vector</code></a> 與 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=deque.html#deque"><code>deque</code></a> 的差異?</p>
<p>最好的方法當然是能深入了解 C++ Standard 對它們的規範. 否則可以參考下面幾個 check point:</p>
<ul>
<li>Container 所包含的 (element) sequence 在 memory 的 layout 必須是連續的. 唯一的選擇是 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=vector.html#vector"><code>vector</code></a></li>
<li>需要 <a href="http://www.sgi.com/tech/stl/Iterators.html">iterator</a> 的位置在插入一個新的 element 或 remove 另一個 element 之後保持有效. 只有 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=list.html#list"><code>list</code></a> 能滿足這需求</li>
<li>常在 sequence 中間 (非頭尾) 位置 insert 或 remove. <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=list.html#list"><code>list</code></a> 會是較好的選擇</li>
<li><a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=vector.html#vector"><code>vector</code></a> 與 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=deque.html#deque"><code>deque</code></a> 都可以滿足以隨機方式存取 sequence 中的 element. 唯前者效能較好 (constant time)</li>
<li>在還沒確認需求時, 建議以 <a href="http://www.dinkumware.com/manuals/?manual=compleat&#038;page=deque.html#deque"><code>deque</code></a> 做為 default <a href="http://www.sgi.com/tech/stl/Sequence.html">sequence container</a> template</li>
</ul>
<p>延伸閱讀 <a href="http://www.gotw.ca/gotw/054.htm">GotW #54: Using Vector and Deque</a>.</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2007/11/12/deque-as-default-container/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[加油~]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/179247341/" />
		<id>http://fsfoundry.org/codefreak/2007/11/03/kanbade/</id>
		<updated>2007-11-03T15:53:14Z</updated>
		<published>2007-11-03T15:53:14Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="技術狂也是人" /><category scheme="http://fsfoundry.org/codefreak" term="親朋好友" />		<summary type="html"><![CDATA[今天意外地在新聞上看到了你, 看起來很棒.
I am very proud of you. 加油~
]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2007/11/03/kanbade/"><![CDATA[<p>今天意外地在新聞上看到了你, 看起來很棒.</p>
<p>I am very proud of you. 加油~</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2007/11/03/kanbade/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>fr3@K</name>
						<uri>http://fsfoundry.org/codefreak/</uri>
					</author>
		<title type="html"><![CDATA[HTTPanties]]></title>
		<link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/codefreak/~3/178807210/" />
		<id>http://fsfoundry.org/codefreak/2007/11/03/httpanties/</id>
		<updated>2007-11-20T16:48:17Z</updated>
		<published>2007-11-02T16:18:52Z</published>
		<category scheme="http://fsfoundry.org/codefreak" term="Funny" /><category scheme="http://fsfoundry.org/codefreak" term="Geeky" />		<summary type="html"><![CDATA[死工程師的幽默. 輔導級&#8230;


應該還要有 407 Authentication Required, 480 Temporarily Unavailable&#8230;
]]></summary>
		<content type="html" xml:base="http://fsfoundry.org/codefreak/2007/11/03/httpanties/"><![CDATA[<p>死工程師的幽默. 輔導級&#8230;<br />
<span id="more-86"></span><br />
<a href="http://www.thinkgeek.com/tshirts/ladies/6792/"><img src="http://www.thinkgeek.com/images/products/zoom/httppanties_4up.jpg"/ alt="HTTPanties from ThinkGeek"></a></p>
<p>應該還要有 407 Authentication Required, 480 Temporarily Unavailable&#8230;</p>
]]></content>
	<feedburner:origLink>http://fsfoundry.org/codefreak/2007/11/03/httpanties/</feedburner:origLink></entry>
	</feed>
