<?xml version="1.0" encoding="UTF-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
  <title>bkブログ</title>
  <link rel="alternate" type="text/html" href="http://0xcc.net/blog/" />
  <modified>2009-06-14T03:31:42Z</modified>
  <tagline>プログラミングやバッドノウハウについてのブログ</tagline>
  <id>tag:0xcc.net,2009:/blog//2</id>
  <generator url="http://www.movabletype.org/" version="4.12">Movable Type</generator>
  <copyright>Copyright (c) 2009, satoru</copyright>

  <entry>
    <title>バッドシグナル通信 - 相性の問題</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000211.html" />
    <modified>2009-06-14T03:31:42Z</modified>
    <issued>2009-06-14T12:31:13+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.211</id>
    <created>2009-06-14T03:31:13Z</created>
    <summary type="text/plain"> WEB+DB PRESS Vol. 51に「バッドシグナル通信」の第2回「相性...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>article</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic60.jpg" alt="" style="float: right">
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774138908/bk256-1-22/ref=nosim/">WEB+DB PRESS Vol. 51</a>に「バッドシグナル通信」の第2回「相性の問題」という記事を書きました。「相性の問題」のありがちなパターンと対策について考察しています。
</p>]]>
      
    </content>
  </entry>

  <entry>
    <title>バッドシグナル通信 - 歴史的理由</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000210.html" />
    <modified>2009-06-14T03:34:41Z</modified>
    <issued>2009-04-13T00:08:09+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.210</id>
    <created>2009-04-12T15:08:09Z</created>
    <summary type="text/plain"> WEB+DB PRESS Vol. 50から「バッドシグナル通信」という連載を...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>article</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic59.jpg" alt="" style="float: right">
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/477413838X/bk256-1-22/ref=nosim/">WEB+DB PRESS Vol. 50</a>から「バッドシグナル通信」という連載を始めました。第1回のテーマは「歴史的理由」です。
</p>]]>
      <![CDATA[<p>
バッドシグナルの紹介を、本文から引用しておきます。
</p>

<blockquote>
<p>
ソフトウェア開発を行っていると、「何かいやな予感がするなー」と直感が働いて、それが的中することがままあります。いやな予感には何かしらの原因があり、そこから発せられる危険信号を人は読み取っているのではないかと思います。
</p>
<p>
筆者の周りではこの危険信号を、バッドであることが予想されるシグナルという意味で、「バッドシグナル」と呼んでいます。筆者はこの言葉を使い始めてからは、いやな予感がするきは「このバッドシグナルは何だ？」と考えるようになり、いやな予感の原因を特定する習慣がつきました。
</p>
</blockquote>

<p>
ちなみに、前号まで連載していた<a href="http://gihyo.jp/dev/serial/01/bk">BK通信</a>は gihyo.jp で読めます。最終回の「文字コードのバッドノウハウ」もしばらくすると掲載されると思います。その前の連載の<a href="http://gihyo.jp/dev/serial/01/scene">プログラミングの光景</a>は全記事が掲載されています。
</p>]]>
    </content>
  </entry>

  <entry>
    <title>マッキントッシュ物語 - 僕らを変えたコンピュータ</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000209.html" />
    <modified>2009-02-22T15:42:16Z</modified>
    <issued>2009-02-22T18:40:44+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.209</id>
    <created>2009-02-22T09:40:44Z</created>
    <summary type="text/plain"> スティーブン・レヴィ氏の『マッキントッシュ物語 - 僕らを変えたコンピュータ』...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>book</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
スティーブン・レヴィ氏の<img src="http://0xcc.net/blog/archives/pic58.jpg" alt="" style="float: right">『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4835440455/bk256-1-22/ref=nosim/">マッキントッシュ物語 - 僕らを変えたコンピュータ</a>』を読みました。
</p>]]>
      <![CDATA[<p>
本書は、初代マッキントッシュ誕生とその後の数年の物語を関係者へのインタビューを元に再現したノンフィクションです。スティーブン・レヴィ氏の他の著作と同様に、インタビューは入念、ドラマ性たっぷり、ゴシップは多め、と期待通りの一冊でした。
</p>

<p>
物語にはスティーブ・ジョブズは当然として、ビル・アトキンソンやアンディ・ハーツフェルド、ジェフ・ラスキンなどの開発者も多数登場します。ジョブズは「現実ゆがみフィールド」を持ったカリスマとして頻繁に登場しますが、奮闘する開発者たちも負けず劣らず重要な役割を果たしています。
</p>

<p>
第一章は、著者とマックの出会いから始まります。1983年11月、ジャーナリストである著者はアップル本社を訪れ、発表前のマックのデモを目にします。即座に「目の前で改革が起こっている」ことを理解し、マックの記事を書くことを決意します。このときのスティーブ・ジョブズは意気揚々、まさに自信の塊です。
</p>

<p>
ジョブズとのインタビューが終わると、打って変わって 1945年に発表された風変わりなエッセイ「科学技術の今後の動向」（原題は <a href="http://www.theatlantic.com/doc/194507/bush">As We May Think</a>）の話題に移ります。バニーバー・ブッシュ氏によるこのエッセイの中には 1945 年に書かれたとは思えない、コンピュータの革新的な将来像が予言されています。
</p>

<p>
このエッセイは後に、ダグラス・エンゲルバート氏によるマウスとウィンドウの発明につながり、さらにこのビジョンはゼロックスPARCの研究者たちによって磨きがかけられます。これらの成果をベースとして誕生したのがアップルのリサ、そしてマッキントッシュです。2章から5章にかけて、マッキントッシュに至るまでのこういった過程を源流から丹念に辿っていきます
</p>

<p>
長い前置きが終わると、いよいよマッキントッシュの開発の物語に入ります。開発は最後の最後までめちゃめちゃ難航して、開発者の多くは完成後に燃え尽きてしまいます。
</p>

<p>
ともあれ、すったもんだの末にようやく1984年1月に発表。しかし、メモリが少なすぎるため事実上使い物にならず（フロッピーディスクを1枚コピーするのにディスクの交換が50回以上必要だった！）、さらにカーソルキーがないといった問題もあって予想よりぜんぜん売れず、絶望的なムードに落ちていきます。
</p>

<p>
結局、スティーブ・ジョブズはマック発表の翌年 1985年5月に追い出されるはめになります。その後もいろいろあって、マックは結局これからどうなるんだろう、という 93年の時点で本書は終わります。
</p>

<h2>まとめ</h2>

<p>
マックを使い始めたのは比較的最近ということもあって、マックの歴史への関心はあまりなかったのですが、本書は非常に楽しめました。序盤を読んでいるうちは、著者のマックへの思い入れが強すぎるんじゃないのと感じる部分もありましたが、途中からは自分もすっかり思い入れが強くなってきて、著者と一緒になってマック開発チームを応援するモードになっていました。絶版となっているのが残念な一冊です（熱い<a href="http://homepage.mac.com/benbrand/insanely_great.html">復刊要望文</a>があります）。
</p>

<p>
ところで、同様の開発物語では Windows NT をテーマとした<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4822740161/bk256-1-22/ref=nosim/">『闘うプログラマー』</a>もかなりおもしろいです。残念ながら、『こちらも絶版になっているようです（こちらの中古は豊富にあるようですが）。次は『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873112451/bk256-1-22/ref=nosim/">レボリューション・イン・ザ・バレー</a>』を読んでみようと思います。
</p>

<p>
p.s.<br>
最後の章で出てきた「自分のマックが調子悪いので調べたところ、オンロケーションという常駐ソフトが ワード 5.1に付属する『雇用報告書』というファイルと相性が悪いことが判明して、こいつを削除したら解決した」というどうでもいいようなエピソードがつぼに入りました。まさに<a href="http://0xcc.net/misc/bad-knowhow.html">BK</a>です。
</p>



<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4835440455/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51E3FEW23JL._SL160_.jpg" alt="マッキントッシュ物語―僕らを変えたコンピュータ" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4835440455/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">マッキントッシュ物語―僕らを変えたコンピュータ</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4835440455/bk256-1-22/ref=nosim/" title="マッキントッシュ物語―僕らを変えたコンピュータ" target="_blank">amazlet</a> at 09.02.22</div></div><div class="amazlet-detail">スティーブン レヴィ <br />ブッキング <br />売り上げランキング: 848708<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4835440455/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div>]]>
    </content>
  </entry>

  <entry>
    <title>GNU diff の地味だけど便利な機能</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000208.html" />
    <modified>2009-02-22T02:10:03Z</modified>
    <issued>2009-02-21T21:34:37+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.208</id>
    <created>2009-02-21T12:34:37Z</created>
    <summary type="text/plain"> 最近になって GNU diff の地味だけど便利な機能を2つ知りました。調べて...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>bk</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic57.jpg" alt="" style="float: right">最近になって GNU diff の地味だけど便利な機能を2つ知りました。調べてみると、いずれも昔からある機能でした。
</p>]]>
      <![CDATA[<p>
--side-by-side は2段組で結果を表示するオプションです。変更されていない行を含めて2つのファイルの内容全体と変更点が表示されるのがポイントです。変更された行の前後数行だけでなくファイル全体をまとめて読みたいときに使えます。デフォルトの表示の横幅は130文字です。必要に応じて --width オプションで変更できます。
</p>

<p>
こういった用途には <a href="http://meld.sourceforge.net/">meld</a> などの GUI の diff ツールを使えばいいのですが、 ssh 端末しかないような状況で重宝します。
</p>

<p>
--strip-trailing-cr は行末の CR を無視する機能です。改行コードが CRLF と LF で食い違っているけど、中身はほぼ同じ、というファイルを比較するときに使えます。
</p>

<p>
以上、GNU diff の地味だけど便利な機能でした。
</p>]]>
    </content>
  </entry>

  <entry>
    <title>BK通信 - 文字コードのバッドノウハウ</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000207.html" />
    <modified>2009-02-14T09:33:35Z</modified>
    <issued>2009-02-14T18:25:14+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.207</id>
    <created>2009-02-14T09:25:14Z</created>
    <summary type="text/plain"> WEB+DB PRESS Vol. 49に「BK通信」の第6回「文字コードのバ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>article</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic56.jpg" alt="" style="float: right">
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774137529/bk256-1-22/ref=nosim/">WEB+DB PRESS Vol. 49</a>に「BK通信」の第6回「文字コードのバッドノウハウ」を書きました。今回がBK通信の最終回です。文字コードは最終回にふさわしい、永遠の <a href="http://0xcc.net/misc/bad-knowhow.html">BK</a>テーマではないかと思います。
</p>]]>
      
    </content>
  </entry>

  <entry>
    <title>C++ の string と vector の reserve() の挙動</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000206.html" />
    <modified>2009-02-12T00:39:47Z</modified>
    <issued>2009-02-11T23:14:43+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.206</id>
    <created>2009-02-11T14:14:43Z</created>
    <summary type="text/plain"> C++ の string と vector には前もって容量を確保するための ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>c++</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic55.jpg" alt="" style="float: right">
C++ の string と vector には前もって容量を確保するための reserve() というメンバ関数があります。何気なく使っていた関数ですが最近になって興味深い挙動に気づきました。
</p>]]>
      <![CDATA[<h2>reserve() の基本</h2>

<p>
string と vector の reserve() は前もって容量 (capacity) を確保しておくためのメンバ関数です。前もって容量を確保 (reserve) しておけば、データの追加時に発生する再割り当て (reallocation) を防ぐことができ、効率的です。
</p>

<p>
たとえば、何もしないで文字列に 1,000文字追加した場合、（内部的に倍々で容量を増やしていくため）10回程度の再割り当てが発生しますが、 s.reserve(1000) のように容量を確保しておけば 1回の割り当て (allocation) だけで済みます。
</p>

<p>
以下は Mac OS X 10.5 の gcc version 4.0.1 (Apple Inc. build 5465) での実行結果です。
</p>

<h3>何もしない場合</h3>

<pre>
% cat reserve0.cc
#include &lt;string&gt;

const int N = 1000;
int main() {
  std::string s;
  for (int i = 0; i &lt; N; ++i) {
    s.append(&quot;a&quot;);
  }
  return 0;
}

% g++ -g reserve0.cc
% gdb ./a.out
(gdb) start
...
Breakpoint 1, main () at reserve0.cc:5
5         std::string s;
(gdb) b malloc
Breakpoint 2 at 0x954f825b
(gdb) c
Continuing.

Breakpoint 2, 0x954f825b in malloc ()   ← 1回
(gdb) bt
#0  0x954f825b in malloc ()
#1  0x97009598 in operator new ()
#2  0x96ff0fd2 in std::string::_Rep::_S_create ()
#3  0x96ff129a in std::string::_Rep::_M_clone ()
#4  0x96ff2a8f in std::string::reserve ()
#5  0x96ff2d21 in std::string::append ()
#6  0x96ff2da5 in std::string::append ()
#7  0x00001f61 in main () at reserve0.cc:7
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 2回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 3回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 4回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 5回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 6回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 7回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 8回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 9回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 10回
(gdb)
Continuing.

Breakpoint 2, 0x954f825b in malloc ()  ← 11回
(gdb)
Continuing.

Program exited normally.
(gdb)
</pre>

<p>
たしかに 10回ほどの再割り当てが行われていることが確認できました。再割り当て時には元の領域から新しい領域への文字列のコピーも行われます。
</p>

<h3>reserve() した場合</h3>

<pre>
% cat reserve1.cc
#include &lt;string&gt;

const int N = 1000;
int main() {
  std::string s;
  s.reserve(N);
  for (int i = 0; i &lt; N; ++i) {
    s.append(&quot;a&quot;);
  }
  return 0;
}

% g++ -g reserve1.cc
% gdb ./a.out
(gdb) start
...
Breakpoint 1, main () at reserve1.cc:6
6         s.reserve(N);
(gdb) b malloc
Breakpoint 2 at 0x954f825b
(gdb) c
Continuing.

Breakpoint 2, 0x954f825b in malloc () ←1回
(gdb) bt
#0  0x954f825b in malloc ()
#1  0x97009598 in operator new ()
#2  0x96ff0fd2 in std::string::_Rep::_S_create ()
#3  0x96ff129a in std::string::_Rep::_M_clone ()
#4  0x96ff2a8f in std::string::reserve ()
#5  0x00001f42 in main () at reserve1.cc:6
(gdb) c
Continuing.

Program exited normally.
(gdb)
</pre>

<p>
reserve() すると確かに 1回だけの割り当てで済むことが確認できました。
</p>

<h2>reserve() の間違った使い方</h2>

<p>
それでは reserve() を間違って使うとどうなるでしょうか。以下のコードではループの中で、現在のサイズ + 1 を reserve しています。 
</p>

<pre>
% cat reserve2.cc
#include &lt;string&gt;

const int N = 1000;
int main() {
  std::string s;
  for (int i = 0; i &lt; N; ++i) {
    s.reserve(s.size() + 1); 
    s.append(&quot;a&quot;);
  }
  return 0;
}
</pre>

<p>
これをさきほどと同じようにデバッガで追いかけると 1,000回もの再割り当てが起きることがわかります。毎回文字列のコピーが行われていることを考えると、これは O(n^2) の計算量になります。実際、 N の数を 100000 くらいに増やすと、プログラムが終了するまでに 7秒もかかりました。
</p>

<h2>reserve() の不思議な挙動</h2>

<p>
さきほどのプログラムの挙動をもう少し追ってみると、容量の増え方が予想外の動きをしていることがわかりました。以下のコードでは reserve() の直後に容量を表示しています。 
</p>

<pre>
% cat reserve3.cc
#include &lt;string&gt;
#include &lt;iostream&gt;

const int N = 1000;
int main() {
  std::string s;
  for (int i = 0; i &lt; N; ++i) {
    s.reserve(s.size() + 1);
    std::cout &lt;&lt; s.capacity() &lt;&lt; &quot; &quot;;
    s.append(&quot;a&quot;);
  }
  return 0;
}

% g++ -g reserve3.cc
% ./a.out
1 2 4 4 8 6 12 8 16 10 20 12 24 14 28 16 32  ... 1988 996 1992 998 1996 1000
</pre>

<p>
このように、容量が 1 2 4 4 8 6 12 8 16 10 20 12 24 14 28 ... のように増えたり減ったりしていることがわかりました。増えるだけで減ることはないと思っていたので、意外でした。2倍に増えたかと思えばまたすぐに小さくなっています。なぜこんな挙動をするのでしょうか。
</p>

<p>
謎を調べるため、デバッガで追ってみることにします。 Mac OS X の場合 /usr/lib/libstdc++-static.a にデバッグ情報つきの C++ のライブラリがあるので、これを使います。これを使うには g++ に -lstdc++-static を渡す必要があります。
</p>

<pre>
% g++ -g -lstdc++-static reserve3.cc
% gdb ./a.out
(gdb) start
Breakpoint 1 at 0x3c400: file reserve3.cc, line 6.
...
Breakpoint 1, main () at reserve3.cc:6
6         std::string s;
(gdb) n
7         for (int i = 0; i &lt; N; ++i) {
(gdb) n
8           s.reserve(s.size() + 1);
(gdb) s
std::string::size (this=0xbffff578) at bits/basic_string.h:584
584     bits/basic_string.h: No such file or directory.
        in bits/basic_string.h
</pre>

<p>
おっと、ソースコードが見当たらないといって怒られてしまいました。こういうときは dir コマンドでソースコードの場所を教えてあげれば OK です。
<p>

<pre>
(gdb) dir /usr/include/c++/4.0.0/bits
Source directories searched: /usr/include/c++/4.0.0/bits:$cdir:$cwd
(gdb) s
585           { return _M_rep()-&gt;_M_length; }
</pre>

<p>
が、デバッガで追いかけるより basic_string.h を直接読んだほうが早そうなので、そうすることにします。ざーっと読んでいくと basic_string.tcc の次のコードにたどり着きます。reserve() から間接的に呼ばれている _S_create() という関数内です。
</p>

<pre>
      // The below implements an exponential growth policy, necessary to
      // meet amortized linear time requirements of the library: see
      // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
      // It's active for allocations requiring an amount of memory above
      // system pagesize. This is consistent with the requirements of the
      // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
      if (__capacity &gt; __old_capacity &amp;&amp; __capacity &lt; 2 * __old_capacity)
        __capacity = 2 * __old_capacity;
</pre>

<p>
コメントには「ここでは償却線形時間要求を満たすために指数的な成長ポリシーを実装する」といった旨のことが書かれています。コードの方を見ると、「指定された新しい容量が現在よりも大きく、かつ、現在より2倍未満の場合は、新しい容量を現在の２倍にする」という処理が行われています。
</p>

<p>
文字列追加のために「指数的な成長ポリシー」が必要なことはわかりますが、reserve() したときに行わなくてもいいような気がします。
</p>

<p>
ともあれ、これで、現在の容量に 1しか足していないのに、容量が2倍になる謎が解けました。では減るほうはどうでしょうか。SGI の <a href="http://www.sgi.com/tech/stl/basic_string.html">string のマニュアル</a>を読むと次のように書かれています (C++ の仕様書は確認していません)。
</p>

<blockquote>
Requests that the string's capacity be changed; the postcondition for this member function is that, after it is called, capacity() >= n. <strong>You may request that a string decrease its capacity by calling reserve() with an argument less than the current capacity</strong>. (If you call reserve() with an argument less than the string's size, however, the capacity will only be reduced to size(). A string's size can never be greater than its capacity.) reserve() throws length_error if n > max_size().
</blockquote>

<p>
太字のところに「現在の容量 (capacity) よりも小さい値で reserve() を呼ぶことで、容量を減らすことができる 」と書かれています。つまり、string の reserve() で容量を減らせるのは仕様です。
</p>

<p>
というわけで、「指数的な成長ポリシー」と「現在の容量より減らせる」の2つが組み合わせると、容量が増えたり減ったりするという挙動が説明できます。
</p>

<h2>reserve() のアンチパターン</h2>

<p>
上のような一目で非効率とわかるコードを書くことはないと思いますが、複雑なコードでは reserve() の呼び出しが思わぬところに埋もれている可能性があるので注意が必要です。せっかく前もって適切に reserve() していても、処理の途中で余計な reserve() が入ってしまったら台無しになります。

<p>
たとえば、次の関数は、よかれと思って reserve() を行っていますが、余計なお世話になります。前述のとおり、reserve() には容量を縮める効果があるので下手に reserve() するとせっかく前もって確保していた容量が台無しになってしまうためです。
</p>

<pre>
void AppendTwice(const string&amp; stuff, string* output) {
  output-&gt;reserve(output->size() + stuff.size() * 2);
  output-&gt;append(stuff);
  output-&gt;append(stuff);
}
</pre>

<p>
余計なお世話をしないためには次のように書く必要があります。
</p>

<pre>
void AppendTwice(const string&amp; stuff, string* output) {
  // 容量が足りていないときだけ reserve する
  string::size_type new_size = output->size() + stuff.size() * 2;
  if (output-&gt;capacity() < new_size) {
    output-&gt;reserve(new_size);
  }
  output-&gt;append(stuff);
  output-&gt;append(stuff);
}
</pre>

<p>
処理の最初に前もって reserve() することは効果的ですが、文字列を連結していく途中で reserve() が入ると逆効果になることがあります。下手に reserve() を入れるくらいなら何もしないで「指数的な成長ポリシー」に任せたほうがましです。あるいは <a href="http://www.sgi.com/tech/stl/Rope.html">Rope</a> のような内部的に非連続な文字列を使う手もあります。
</p>


<h2>vectorの場合</h2>

<p>
では vector の reserve() の方はどうでしょうか。結論からいうと、 vector の reserve() は容量を減らすことはありません。SGI の <a href="http://www.sgi.com/tech/stl/Vector.html">vector のマニュアル</a>に次のように書かれています。
</p>

<blockquote>
<strong>If n is less than or equal to capacity(), this call has no effect.</strong> Otherwise, it is a request for allocation of additional memory. If the request is successful, then capacity() is greater than or equal to n; otherwise, capacity() is unchanged. In either case, size() is unchanged. 
</blockquote>

<p>
つまり、capacity() より小さい値を reserve() した場合、何も起きない仕様です。string もこの仕様なら、前述のコードで容量が増えたり減ったりするという不思議な挙動に悩まされることはなかったはずです。
</p>

<p>
また、vector.tcc の reserve() のコードは比較的シンプルで、素直に指定されたサイズで reallocation します。その代わり、「指数的な成長ポリシー」は _M_insert_aux() の中で実装されています。
</p>

<pre>
          size_type __len = __old_size != 0 ? 2 * __old_size : 1;
</pre>

<p>
reserve() の中で「指数的な成長ポリシー」を実装している string より、 vector のやり方の方が好ましいように思います。
</p>

<h2>まとめ</h2>

<p>
長くなりましたが、まとめると次のようになります。
</p>

<ul>
<li>reserve() を間違って使うと非常に非効率</li>
<li>string の reserve() は現在より容量を減らせる</li>
<li>vector の reserve() は現在より容量を減らせない</li>
<li>string の reserve() は「指数的成長ポリシー」を発動する</li>
<li>vector の reserve() は「指数的成長ポリシー」を発動しない</li>
<li>string の reserve() するときは余計なお世話にならないように気をつけるべし</li>
<li>Mac OS X でデバッグ情報つき C++ ライブラリを使うときは -lstdc++-static</li>
<li>gdb にソースコードの場所を教えるときは dir コマンド</li>
</ul>

<p>
なお、この記事で取り上げた string と vector の挙動は GCC 4.0.3 に付属する STL での挙動です。他の STL の実装では挙動が異なると思います。
</p>

<p>
p.s.<br>
これを書いた後で、<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4894714108/bk256-1-22/ref=nosim/">Effective STL</a> の「reserve を使って不必要な割り当てを避けよう」のところを確認してみると、string の reserve() が 容量を減らす件について軽く触れていました。以前に読んだのにすっかり忘れていました。
</p>

<blockquote>
string では size() か n の小さい方の値に容量を「減らすことがある」が、string のサイズは常に変わらない。筆者の経験では、 string から余分な容量を減らすには「swap」技法を使ったほうが成功することが多い。
</blockquote>]]>
    </content>
  </entry>

  <entry>
    <title>暗号化 - プライバシーを救った反乱者たち</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000205.html" />
    <modified>2009-02-05T13:28:27Z</modified>
    <issued>2009-02-02T23:25:49+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.205</id>
    <created>2009-02-02T14:25:49Z</created>
    <summary type="text/plain"> 先日、移動中に読む本を物色しているときに、たまたま目についた『暗号化 - プラ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>book</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic54.jpg" alt="" style="float: right">先日、移動中に読む本を物色しているときに、たまたま目についた『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4314009071/bk256-1-22/ref=nosim/">暗号化 - プライバシーを救った反乱者たち</a>』を持って出かけました。
</p>]]>
      <![CDATA[<p>
この本は買ってから長らく放置していました。何の気なしに電車の中で手にとって見ると、「まえがき」の時点でこれがただならぬ本であることが伝わってきました。結局、電車、空港、機内とノンストップで読み続けて、あっという間に読み終えました。
</p>

<p>
暗号をテーマにした本といえば、サイモン・シンの『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/410215972X/bk256-1-22/ref=nosim/">暗号解読</a>』という本が有名です（<a href="http://0xcc.net/blog/archives/000058.html">以前に紹介</a>しました）。２冊を比べると、暗号解読がサイエンスライターによって書かれているのに対し、本書はジャーナリストによって書かれているという違いが出ています。数字で感覚的に表すと次のような感じです。
</p>

<blockquote>
<p>
暗号解読 = サイエンス : 歴史 : ドラマ = 4 : 4 : 2<br>
暗号化 = サイエンス : 歴史 : ドラマ = 1 : 4 : 5
</p>
</blockquote>

<p>
大雑把にいえば、『暗号解読』がサイエンス（暗号の仕組みと解読法）と歴史に重点を置いているのに対し、本書は歴史とドラマ、特に人間の泥臭いドラマに力を入れている点が異なります。
</p>

<p>
ホイットフィールド・ディフィー（Diffie-Hellman鍵交換の発明者の一人）の放浪生活、RSAデータセキュリティ社の初期の窮乏とその後の躍進、暗号アナーキストの会合、クリッパーチップをめぐる攻防、といった出来事が当事者たちのインタビューを元に生々しく再現されており、1970年代から1990年代にかける暗号の世界を一緒に駆け抜けているかのような臨場感があります。
</p>

<p>
下世話なエピソードがたくさん取り上げられているのもポイントで、『暗号解読』の高尚な雰囲気とは異なり、ゴシップ度が結構高いのも本書の特色です。
</p>

<h2>まとめ</h2>

<p>
『暗号解読』と比べるとやや影の薄い感がありますが、読み物としての完成度は高く、一読に値する本だと思います。最高に面白いノンフィクション本でした。
</p>

<p>
p.s.<br>
ちなみに、スティーブン・レビー氏の『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/487593100X/bk256-1-22/ref=nosim">ハッカーズ</a>』（こちらも<a href="http://0xcc.net/blog/archives/000058.html">以前に紹介</a>しました）も、コンピュータ関連の読み物の中で最高峰にある一冊だと思います。今回の『暗号化』ですっかりスティーブン・レビー氏のファンになったので、未読だった『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4835440455/bk256-1-22/ref=nosim/">マッキントッシュ物語</a>』『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4022569573/bk256-1-22/ref=nosim/">人工生命 - デジタル生物の創造者たち</a>』『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797334150/bk256-1-22/ref=nosim/">iPodは何を変えたのか?</a>』をまとめ買いしました。楽しみです。
</p>

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4314009071/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51ZRZ62WKCL._SL160_.jpg" alt="暗号化 プライバシーを救った反乱者たち" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4314009071/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">暗号化 プライバシーを救った反乱者たち</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4314009071/bk256-1-22/ref=nosim/" title="暗号化 プライバシーを救った反乱者たち" target="_blank">amazlet</a> at 09.02.02</div></div><div class="amazlet-detail">スティーブン・レビー <br />紀伊國屋書店 <br />売り上げランキング: 370545<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4314009071/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div>]]>
    </content>
  </entry>

  <entry>
    <title>Best Software Writing</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000204.html" />
    <modified>2009-01-06T13:52:05Z</modified>
    <issued>2009-01-06T20:38:50+09:00</issued>
    <id>tag:0xcc.net,2009:/blog//2.204</id>
    <created>2009-01-06T11:38:50Z</created>
    <summary type="text/plain"> 正月休みに何か気楽なものでも、と思い『Best Software Writin...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>book</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic53.jpg" alt="" style="float: right">正月休みに何か気楽なものでも、と思い『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798115819/bk256-1-22/ref=nosim/">Best Software Writing</a>』を読みました。
</p>]]>
      <![CDATA[<p>
この本は『<a href="http://0xcc.net/blog/archives/000097.html">Joel on Software</a>』で知られる Joel Spolsky 氏が編纂した、ソフトウエアに関するエッセイ集です。20数名の著者による 30本以上のエッセイがまとめられています。
</p>

<p>
エッセイの選択は2004年に行われたため、今となっては目新しくないものもありましたが（Python は動的型付けで楽ちん。テストを書けば安心、みたいな）、今読んでも十分におもしろいエッセイが多くありました。なかでも次のエッセイが特におもしろいと思いました。
</p>

<ul>
<li><strong>なぜ、アンドキュメンテッドな振る舞いに依存するアプリケーションを単に締め出さないのか</strong>  by レイモンド・チェン<br>文書化されていない Windows の挙動に依存している行儀の悪いアプリをなぜ締め出さないのかという話。動かないアプリがあったら企業は新しい Windows にアップグレードしてくれない。ゲーム会社は既に売ってしまったゲームを新しい Windows に対応させることに興味などない、などなど。</li>
<li><strong>情熱</strong> by ロン・ジェフリーズ<br>エクストリームプログラミングとアジャイルに情熱を注いだ頃について、シニカルにではなく熱く思いを込めて回顧する。筆者にとって情熱とは欠かせないものである。</li>
<li><strong>電球を替えるのにMicrosoft社員は何人必要か</strong> by エリック・リッパート<br>たかだか5行程度で実装できる関数を API として VBScript に追加するのは容易に思えるかもしれないが、そのためには仕様書、セキュリティレビュー、テスト、ドキュメント、ドキュメントの校正と翻訳、などなどといろいろやるべきことがあり、全体の作業は膨大になる。Microsoft において、出荷できる製品のクオリティを達成するのは大変なのだ、という話。</li>
<li><strong>グループにとって最悪の敵は自分自身である</strong> by クレイ・シャーキー<br>過去40年において、ソーシャルなソフトウェアでは同じような失敗が繰り広げられてきた。そしてそれは今も変わらない。グループは外部からの攻撃ではなく、参加者による内部からの攻撃によって崩壊する。自由・平等主義はグループを崩壊に導く。グループ内のコアグループには強い力を持たせる必要がある。などなど、といった内容。長文で示唆に富んでいます。</li>
<li><strong>ユーザとしてのグループ: フレーミングとソーシャルソフトウェアのデザイン</strong> by クレイ・シャーキー<br>こちらも同じ著者によるもの。フレーマー（荒らし）は確実に現れる。これは共有地の悲劇である。Slashdot ではレーティング、カルマ、メタモデレーションといったシステムでフレーマーに対処している。これは技術的には単純だが効果的であり、時間をかけて進化したシステムである。といった内容。</li>
<li><strong>採用の危険</strong> by エリック・シンク<br>独立系ソフトウェア会社が採用するときの注意点について。プログラマではなく開発者を雇え。つまり、コードを書いてバグを直すだけの人ではなく、製品の成功のためにさまざまな方法で貢献できる多才な開発者を探すことが大切。などなど、他にもいろいろな助言あり。</li>
</ul>

<p>
これらの中でも、長年に渡ってネット・コミュニティを観察し続けてきたクレイ・シャーキー氏による2本のエッセイは、語り口が鮮やかなこともあって、とりわけ興味深く思いました。
</p>

<h2>まとめ</h2>

<p>
エッセイ集ということで、何かすぐに役立つといったことが書かれているわけでもありませんが、気が向いたときに読む読み物としてはなかなかよいのではないかと思います。
</p>

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798115819/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51TSXSjc4-L._SL160_.jpg" alt="BEST SOFTWARE WRITING" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798115819/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">BEST SOFTWARE WRITING</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4798115819/bk256-1-22/ref=nosim/" title="BEST SOFTWARE WRITING" target="_blank">amazlet</a> at 09.01.06</div></div><div class="amazlet-detail"><br />翔泳社 <br />売り上げランキング: 123449<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798115819/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div>]]>
    </content>
  </entry>

  <entry>
    <title>BK通信 - ブラウザのバッドノウハウ コンテンツ編</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000203.html" />
    <modified>2008-12-23T04:47:52Z</modified>
    <issued>2008-12-23T13:29:55+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.203</id>
    <created>2008-12-23T04:29:55Z</created>
    <summary type="text/plain"> WEB+DB PRESS Vol. 48に「BK通信」の第5回「ブラウザのバッ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>article</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic52.jpg" alt="" style="float: right">
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774136913/bk256-1-22/ref=nosim/">WEB+DB PRESS Vol. 48</a>に「BK通信」の第5回「ブラウザのバッドノウハウ コンテンツ編」を書きました。Content-Type と Content-Disposition ヘッダにまつわるBKを取り上げました。あまりにバッドすぎて、通常2ページのところ今回は4ページに膨らんでしまいました。
</p>]]>
      <![CDATA[<p>
今号は田中哲さん、太田一樹さん、森田創さんによるデバッグに関するエッセイや、最新のJavaScript エンジンの技術解説、スクリプト言語のモダンプログラミングなど、読み応えのある記事が満載でした。
</p>

<p>
個人的には田中哲さんのデバッグ記事に畏敬の念を覚えました。
</p>

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774136913/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/61UITuqsyWL._SL160_.jpg" alt="WEB+DB PRESS Vol.48" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774136913/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">WEB+DB PRESS Vol.48</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4774136913/bk256-1-22/ref=nosim/" title="WEB+DB PRESS Vol.48" target="_blank">amazlet</a> at 08.12.23</div></div><div class="amazlet-detail">WEB+DB PRESS編集部 編 <br />技術評論社 <br />売り上げランキング: 236<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774136913/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div>

]]>
    </content>
  </entry>

  <entry>
    <title>プログラミングの力を生み出す本</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000202.html" />
    <modified>2008-08-31T16:34:36Z</modified>
    <issued>2008-08-31T19:59:53+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.202</id>
    <created>2008-08-31T10:59:53Z</created>
    <summary type="text/plain"> 知人がお勧めしていた『プログラミングの力を生み出す本』を読みました。 ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>book</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic51.jpg" alt="" style="float: right">知人がお勧めしていた『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274132072/bk256-1-22/ref=nosim/">プログラミングの力を生み出す本</a>』を読みました。
</p>
]]>
      <![CDATA[<p>
読みはじめてすぐに、この本は異色なプログラミングの入門書であることがわかりました。普通のプログラミングの入門書は「プログラミングとは」という序論が終わったら hello, world 的なものからコードを書き始めるものが多いと思うのですが、本書の導入はまるっきり異なります。1章の目次は以下の通りです（カッコ内は私のコメント）。
</p>

<dl>
<dt>1章 プログラミングへの導入</dt>
<dd>プログラミングことはじめ（なぜか例が x-y プロッタ）</dd>
<dd>プログラミングの構造（なぜかフローチャート登場）</dd>
<dd>データ（整数、文字列、論理型など）</dd>
<dd>プログラミング言語の構造（コンパイラ、リンカの説明とか）</dd>
<dd>x86 CPU の概要（レジスタの説明とか）</dd>
<dd>GCC と GNUPLOT（なぜか GNUPLOT が導入に登場...）</dd>
<dd>GNU アセンブリ言語（GAS の概要）</dd>
<dd>GNU デバッガ (GDB の概要)</dd>
</dl>

<p>
2章からは  x86 のプログラムをアセンブリ言語で書き始めます。ここでも hello, world 的なものは一切登場しません。ビルドしたプログラムを GDB 上で命令単位でステップ実行して、レジスタの変化を見るというスタイルで解説が続きます。2章の目次は以下の通りです。
</p>

<dl>
<dt>2章 アセンブリ言語によるプログラミング基礎</dt>
<dd>CPUとレジスタ</dd>
<dd>メモリとデータ型</dd>
<dd>フラグ</dd>
<dd>条件判断</dd>
<dd>論理演算</dd>
<dd>ループ</dd>
<dd>配列</dd>
<dd>アドレッシング</dd>
<dd>その他の命令</dd>
<dd>スタック</dd>
<dd>C言語とのリンク</dd>
<dd></dd>
</dl>

<p>
2章の序盤では、 GDB を使ってステップ実行する過程が丁寧に解説されています。自分で実行してみなくてよいところが親切です。GDB のチュートリアルとしても役立ちそうです。「スタック」の説では関数呼び出しがどのように行われるか（コーリングコンベンション）について解説されています。
</p>

<p>
3章はC言語の話、4章はプログラムの例の話です。これらは、すでにある程度 C言語でプログラミングの経験がある人にとってはそれほど興味深い内容ではないと思います。
</p>

<p>
巻末には付録で x86 の命令表がついています。すべての命令が網羅されているわけではありませんが、 gcc -S -O0 が出力しそうな命令はカバーされているのでリファレンスとして役立ちそうです。
</p>

<h2>まとめ</h2>
<p>
異色のプログラミング入門書でした。説明が駆け足な点も見受けられるので、本当のプログラミング入門者が読むのに適した本かどうかはやや疑問ですが、gcc が出力する x86 用のアセンブリコードを読むためにアセンブリ言語を学びたい、という目的にちょうどいい本なのではないかと思います。
</p>

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274132072/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/412BKEJ1A6L._SL160_.jpg" alt="プログラミングの力を生み出す本―インテルCPUのGNUユーザへ" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274132072/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">プログラミングの力を生み出す本―インテルCPUのGNUユーザへ</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4274132072/bk256-1-22/ref=nosim/" title="プログラミングの力を生み出す本―インテルCPUのGNUユーザへ" target="_blank">amazlet</a> at 08.08.31</div></div><div class="amazlet-detail">橋本 洋志 松永 俊雄 冨永 和人 石井 千春 <br />オーム社 <br />売り上げランキング: 261702<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4274132072/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]>
    </content>
  </entry>

  <entry>
    <title>split の研究</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000201.html" />
    <modified>2008-09-07T09:45:24Z</modified>
    <issued>2008-08-30T14:13:00+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.201</id>
    <created>2008-08-30T05:13:00Z</created>
    <summary type="text/plain"> split 関数の挙動が言語ごとに微妙に異なると知人と話題になったので調べてみ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>emacs</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic50.jpg" alt="" style="float: right">split 関数の挙動が言語ごとに微妙に異なると知人と話題になったので調べてみました。結果は<a href="http://0xcc.net/blog/archives/000201.html#summary">まとめ</a>をどうぞ。
</p>]]>
      <![CDATA[<style type="text/css">
<!--
table.comparison {
  font-size: 7pt;
  border-collapse: collapse;
  line-height: 150%;
}
table.comparison td, table.comparison th {
  border-style: solid;
  border-color: #bbb;
  border-width: 1px;
  vertical-align: top;
  padding: 4px;
}
table.comparison th {
  text-align: left;
  background-color: #ddf;
}
table.comparison td.empty {
  background-color: #eee;
}
table.comparison td.odd {
  background-color: #fdd;
}
-->
</style>



<h2>Ruby</h2>
<p>
まずはRubyから調べてみます。irb を使って調べました。
</p>

<pre>
% irb
...
まずは普通に分割
&gt;&gt; "a,b,c".split(",")
=&gt; ["a", "b", "c"]

末尾に空要素があると、省略されてしまう
&gt;&gt; "a,,c,,".split(",")
=&gt; ["a", "", "c"]

末尾の空要素を省略しないためには -1 が必要
&gt;&gt; "a,,c,,".split(",", -1)
=&gt; ["a", "", "c", "", ""]

空文字列だと結果も空
&gt;&gt; "".split(",")
=&gt; []

-1 をつけても同様
&gt;&gt; "".split(",", -1)
=&gt; []

分割パターンを指定しない場合も同様
&gt;&gt; "".split()
=&gt; []

分割パターン省略時は空白で分割（厳密には $; の値が影響）
&gt;&gt; "a b\tc\nd".split()
=&gt; ["a", "b", "c", "d"]

分割パターンは文字列で指定できる
&gt;&gt; "a:b;c.d".split(".")
=&gt; ["a:b;c", "d"]

分割パターンは正規表現でも指定できる
&gt;&gt; "a:b;c.d".split(/[:;]/)
=&gt; ["a", "b", "c.d"]

分割パターンが空の文字列だったら？
&gt;&gt; "abc".split("")
=&gt; ["a", "b", "c"]

分割パターンが空の正規表現だったら？
&gt;&gt; "abc".split(//)
=&gt; ["a", "b", "c"]

分割パターンの正規表現が . だったら？
&gt;&gt; "abc".split(/./)
=&gt; []
</pre>

<h2>Perl</h2>

<p>
次は Perl です。Perl -d -e1 でデバッガを起動して調べました。-MData::Dumper はデータの表示用、 -MTerm::ReadLine はコマンドライン編集用のモジュールです。
</p>

<pre>
% perl -MData::Dumper -MTerm::ReadLine -d -e1
...
まずは普通に分割
  DB&lt;1&gt; p Dumper(split(",", "a,b,c"))
$VAR1 = 'a';
$VAR2 = 'b';
$VAR3 = 'c';

末尾に空要素があると、省略されてしまう
  DB&lt;2&gt; p Dumper(split(",", "a,,c,,"))
$VAR1 = 'a';
$VAR2 = '';
$VAR3 = 'c';

末尾の空要素を省略しないためには -1 が必要
  DB&lt;3&gt; p Dumper(split(",", "a,,c,,", -1))
$VAR1 = 'a';
$VAR2 = '';
$VAR3 = 'c';
$VAR4 = '';
$VAR5 = '';

空文字列だと結果も空
  DB&lt;4&gt; p Dumper(split(",", ""))

-1 をつけても同様
  DB&lt;5&gt; p Dumper(split(",", "", -1))

分割パターンは正規表現で指定できる
  DB&lt;6&gt; p Dumper(split(/[:;]/, "a:b;c.d"))
$VAR1 = 'a';
$VAR2 = 'b';
$VAR3 = 'c.d';

分割パターンは文字列では指定できない（正規表現として解釈される）
  DB&lt;7&gt; p Dumper(split("[:;]", "a:b;c.d"))
$VAR1 = 'a';
$VAR2 = 'b';
$VAR3 = 'c.d';

分割パターンが空の正規表現だったら？
  DB&lt;8&gt; p Dumper(split(//, "abc"))
$VAR1 = 'a';
$VAR2 = 'b';
$VAR3 = 'c';

分割パターンの正規表現が . だったら？
  DB&lt;9&gt; p Dumper(split(/./, "abc"))

分割パターンおよび入力文字列を省略時は $_ を空白で分割
  DB&lt;10&gt;  $_="a b\tc\nd"

  DB&lt;11&gt;  p Dumper(split)
$VAR1 = 'a';
$VAR2 = 'b';
$VAR3 = 'c';
$VAR4 = 'd';
</pre>

<p>
というわけで、 Perl の挙動は分割パターンが文字列で指定できない（文字列で指定しても正規表現として解釈されてしまう）以外は Ruby と同じです。Ruby が Perl の挙動と揃えたのかもしれません。
</p>

<h2>Python</h2>

<p>
次は Python です。python コマンドを使って調べました。
</p>

<pre>
% python
...
まずは普通に分割
&gt;&gt;&gt; "a,b,c".split(",")
['a', 'b', 'c']

末尾の空要素は無視されない
&gt;&gt;&gt; "a,,c,,".split(",")
['a', '', 'c', '', '']

空文字列を分割すると配列に空文字列がひとつ入る
&gt;&gt;&gt; "".split(",")
['']

しかし、分割パターンを指定しないとなぜか空になる！
&gt;&gt;&gt; "".split()
[]

分割パターン省略時は空白で分割
&gt;&gt;&gt; "a b\tc\nd".split()
['a', 'b', 'c', 'd']

分割パターンは文字列で指定できる
&gt;&gt;&gt; "a:b;c.d".split(".")
['a:b;c', 'd']

分割パターンが空の文字列だったら？
&gt;&gt;&gt; "abc".split("")
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
ValueError: empty separator
</pre>

<p>
Python の挙動は Ruby/Perl 組とは異なります。最後の「分割パターンを指定しないとなぜか空になる」は不思議です。分割パターンが空のときにエラーになるのも特徴です。
</p>

<h2>JavaScript</h2>

<p>
次は JavaScript です。<a href="http://0xcc.net/blog/archives/000048.html"> js コマンド</a>を使って調べました。
</p>

<pre>
% js
...
まずは普通に分割
js&gt; "a,b,c".split(",").toSource()
["a", "b", "c"]

末尾の空要素は無視されない
js&gt; "a,,c,,".split(",").toSource()
["a", "", "c", "", ""]

空文字列を分割すると配列に空文字列がひとつ入る
js&gt; "".split(",").toSource()
[""]

分割パターンを指定しない場合も空文字列がひとつ入る
js&gt;  "".split().toSource()
[""]

分割パターン省略時は分割しない
js&gt; "a b\tc\nd".split()
a b     c
d

分割パターンは正規表現で指定できる
js&gt; "a:b;c.d".split(/[:;]/).toSource()
["a", "b", "c.d"]

分割パターンは文字列でも指定できる
js&gt; "a:b;c.d".split(".").toSource()
["a:b;c", "d"]

分割パターンが空の文字列だったら？
js&gt; "abc".split("").toSource()
["a", "b", "c"]

分割パターンが空の正規表現だったら？
js&gt; "abc".split(new RegExp("")).toSource()
["a", "b", "c"]

分割パターンの正規表現が . だったら？
js&gt; "abc".split(/./).toSource()
["", "", "", ""]
</pre>

<p>
正規表現 /./ で分割したときの挙動が Ruby/Perl と異なります。
</p>

<h2>Emacs</h2>

<p>
最後は Emacs です。*scratch* バッファで C-u C-x で式を評価＆表示して調べました。
</p>

<pre>
まずは普通に分割
(split-string "a,b,c" ",") =&gt; ("a" "b" "c")

末尾の空要素は無視されない
(split-string "a,,c,," ",") =&gt; ("a" "" "c" "" "")

空文字列を分割すると配列に空文字列がひとつ入る
(split-string "" ",") =&gt; ("")

しかし、分割文字列を指定しないとなぜか空になる
(split-string "") => nil

分割パターン省略時は空白で分割
(split-string "a b\tc\nd") =&gt; ("a" "b" "c" "d")

分割パターンは正規表現で指定できる
(split-string "a:b;c.d" "[:;]") =&gt; ("a" "b" "c.d")

分割パターンが空の正規表現だったら？
(split-string "abc" "") =&gt; ("" "a" "b" "c" "")

分割パターンの正規表現が . だったら？
(split-string "abc" ".") =&gt; ("" "" "" "")
</pre>

<p>
分割パターンが空の正規表現のときの挙動が Ruby, Perl, JavaScript のいずれとも異なります。
</p>

<h2 id="summary">まとめ</h2>

<p>
結果をまとめて表にしてみました。
</p>

<table class="comparison">
<tbody>
<tr>
<th>言語</th>
<th>分割パターンの型</th>
<th>末尾の空要素</th>
<th>分割パターン省略時</th>
<th>入力が空文字列かつ<br>分割パターン指定あり</th>
<th>入力が空文字列かつ<br>分割パターン指定なし</th>
<th>分割パターンが空文字列</th>
<th>分割パターンが空正規表現</th>
<th>分割パターンが正規表現の .</th>
</tr>

<tr>
<td>Ruby</td>
<td>文字列または正規表現</td>
<td class="odd">省略される (-1で抑制)</td>
<td>空白で分割</td>
<td>空の配列</td>
<td>空の配列</td>
<td>文字ごとに分割</td>
<td>文字ごとに分割</td>
<td>空の配列</td>
</tr>

<tr>
<td>Perl</td>
<td>正規表現</td>
<td class="odd">省略される (-1で抑制)</td>
<td>$_ を空白で分割</td>
<td>空の配列</td>
<td class="empty"></td>
<td class="empty"></td>
<td>文字ごとに分割</td>
<td>空の配列</td>
</tr>

<tr>
<td>Python</td>
<td>文字列</td>
<td>省略されない</td>
<td>空白で分割</td>
<td>空文字列入りの配列</td>
<td class="odd">空の配列</td>
<td class="odd">エラー</td>
<td class="empty"></td>
<td class="empty"></td>
</tr>

<tr>
<td>JavaScript</td>
<td>文字列または正規表現</td>
<td>省略されない</td>
<td class="odd">分割しない</td>
<td>空文字列入りの配列</td>
<td>空文字列入りの配列</td>
<td>文字ごとに分割</td>
<td>文字ごとに分割</td>
<td>文字数 + 1 の空文字列</td>
</tr>

<tr>
<td>Emacs</td>
<td>正規表現</td>
<td>省略されない</td>
<td>空白で分割</td>
<td>空文字列入りの配列</td>
<td  class="odd">空の配列</td>
<td class="empty"></td>
<td class="odd">文字ごとに分割＋前後に空文字列</td>
<td>文字数 + 1 の空文字列</td>
</tr>
</tbody>
</table>

<p>
ここでは、「空白で分割」の「空白」とは「スペース、タブ、改行など」を意味します。個人的に妙だと思った挙動に色をつけておきました。
</p>


<p>
Ruby, Perl の末尾のから要素がデフォルトで省略されるという挙動は親切というよりは、落とし穴という感じがします。一方、 Python などの入力が空文字のときは空文字列入りの配列が返るという挙動も、これはこれではまりそうです。簡単そうに見える split 関数でも注意して使う必要があるようです。
</p>

<p>
以上、チマチマした研究でした。
</p>

<p>
追記: Perl の split は引き数なしで実行すると $_ の内容を空白で分割するとのこと、<a href="http://d.hatena.ne.jp/boscono/20080902">てきとうなメモ</a>さんにご指摘いただきました。
</p>


<!--
Ruby 1.8.6
Perl v5.8.8
SpiderMonkey 1.6
Python 2.5.1
GNU Emacs 22.1.1
-->]]>
    </content>
  </entry>

  <entry>
    <title>BK通信 - C++のバッドノウハウ</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000200.html" />
    <modified>2008-08-13T14:13:27Z</modified>
    <issued>2008-08-13T23:02:26+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.200</id>
    <created>2008-08-13T14:02:26Z</created>
    <summary type="text/plain"> WEB+DB PRESS Vol. 46に「BK通信」の第3回「C++のバッド...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>article</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic49.jpg" alt="" style="float: right">
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774135607/bk256-1-22/ref=nosim/">WEB+DB PRESS Vol. 46</a>に「BK通信」の第3回「C++のバッドノウハウ」を書きました。C++ の雑多なバッドノウハウを取り上げています。 
</p>
]]>
      <![CDATA[<p>
ちなみに、連載の過去の記事は gihyo.jp の「<a href="http://gihyo.jp/dev/serial/01/bk">BK通信</a>」のコーナーでも読めるようになりました。
</p>
]]>
    </content>
  </entry>

  <entry>
    <title>LINUXシステムプログラミング</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000199.html" />
    <modified>2008-07-21T00:32:36Z</modified>
    <issued>2008-07-20T21:01:29+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.199</id>
    <created>2008-07-20T12:01:29Z</created>
    <summary type="text/plain"> 発売後すぐに入手したものの長らく積読状態が続いていた『LINUXシステムプログ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>book</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic48.jpg" alt="" style="float: right">発売後すぐに入手したものの長らく積読状態が続いていた『<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113628/bk256-1-22/ref=nosim/">LINUXシステムプログラミング</a>』をようやく読みました。
</p>
]]>
      <![CDATA[<p>
本書はその名の通り、Linux のシステムプログラミングについての解説書です。システムプログラミングの定義は明確ではありませんが、システムコールを用いて OS に近いレイヤーで行うプログラミングのことと考えて差し支えないと思います。
</p>

<p>
UNIX一般のシステムプログラミングについては『<a href="http://0xcc.net/blog/archives/000127.html">詳解UNIXプログラミング</a>』という決定版がありますが、本書は Linux 固有の話題や POSIX の比較的新しい API が載っているところが異なります。
</p>

<p>
たとえば、前者になく本書にだけ載っている話題としては以下のようなものがあります。知らなかった話も多くて勉強になりました。
</p>

<ul>
<li>posix_fadvise で I/Oのアクセスパターンのヒントを与える</li>
<li>epoll でI/Oイベントを効率的に監視する</li>
<li>Linux のI/Oスケジューラのアルゴリズム</li>
<li>sched_setaffinity でプロセスを特定のCPUにバインドする</li>
<li>sched_getschduler でスケジュールポリシーを変更する</li>
<li>getxattr, setxattr でファイルの拡張属性を操作する</li>
<li>inotify でファイルイベントを監視する</li>
<li>/dev/full に書き込んで ENOSPC をテストする</li>
<li>posix_memalign でアライメントを指定してメモリを確保する</li>
<li>mlock, mlockall でアドレス空間の一部または全体を物理メモリにロックする</li>
<li>mincore でメモリ領域が物理メモリにあるか調べる</li>
<li>glibc の malloc に特有の関数 mallopt, mallinfo, etc.</li>
<li>sigqueue でシグナルを送りつつデータも送る</li>
<li>素晴らしきかな sig_code の世界</li>
<li>POSIX のクロックインタフェース (clock_*)</li>
<li>POSIX のタイマーインタフェース (timer_*)</li>
<li>GCC の拡張機能</li>
</ul>

<p>
前述の『詳解UNIXプログラミング』が個々の話題を徹底的に掘り下げているのと比べると、本書の解説は比較的、簡素な部類に入ります。それから、本書は扱う話題をプロセス、ファイル、シグナル、時間といった基本的な概念に絞っているのも特徴です。

<p>
プロセス間通信、スレッド、ネットワークプログラミングといった高度な話題は本書の対象外です。同様に、端末やモデムといった、今となっては重要性が薄れた話題も省かれています。
</p>

<h2>まとめ</h2>

<p>
Linux のシステムプログラミングの基本、および、新しいシステムコールを活用した一歩進んだテクニックが学べる良書です。初心者もベテランもどちらも楽しめる内容だと思います。全体で380ページ程度と比較的コンパクトなので、気負わずに読めるところもポイントです。唯一気になったのは図が少ない点です。
</p>

<p>
ところで、日本語訳である本書にはたびたび訳注が登場します。原書には登場しない openat システムコールを紹介するなど、ためになる注が入っています（蛇足っぽいものもありますが）。
</p>

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113628/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51Oy0hCw4eL._SL160_.jpg" alt="Linuxシステムプログラミング" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113628/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Linuxシステムプログラミング</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4873113628/bk256-1-22/ref=nosim/" title="Linuxシステムプログラミング" target="_blank">amazlet</a> at 08.07.20</div></div><div class="amazlet-detail">Robert Love ロバート ラブ <br />オライリージャパン <br />売り上げランキング: 9166<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113628/bk256-1-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div>
]]>
    </content>
  </entry>

  <entry>
    <title>シンプル＝バッドシグナル説</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000198.html" />
    <modified>2008-06-23T15:59:22Z</modified>
    <issued>2008-06-24T00:14:46+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.198</id>
    <created>2008-06-23T15:14:46Z</created>
    <summary type="text/plain"> 知人と話していて、シンプルという言葉は手抜きの言い訳として使われることがあまり...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>essay</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic47.jpg" alt="" style="float: right">知人と話していて、シンプルという言葉は手抜きの言い訳として使われることがあまりに多いので、シンプル＝バッドシグナル（バッドな兆候）なのではないか、という話になりました。
</p>
]]>
      <![CDATA[<p>
シンプルが言い訳としてよく使われるのは以下のような場面です。
</p>

<ul>
<li>必要な機能が足りていない</li>
<li>デザインがださい</li>
<li>そこらじゅう手を抜いている</li>
</ul>

<p>
プログラミングにおいてよくあるのが、まじめに実装していないクラスに Simple なんとかという名前をつけるパターンです。自らシンプルと名乗っているものには疑ってかかったほうがいいのかもしれません。
</p>

<p>
以上、シンプルな考察でした。
</p>
]]>
    </content>
  </entry>

  <entry>
    <title>BK通信 - 数値のバッドノウハウ</title>
    <link rel="alternate" type="text/html" href="http://0xcc.net/blog/archives/000197.html" />
    <modified>2008-06-23T15:58:29Z</modified>
    <issued>2008-06-23T23:48:27+09:00</issued>
    <id>tag:0xcc.net,2008:/blog//2.197</id>
    <created>2008-06-23T14:48:27Z</created>
    <summary type="text/plain"> WEB+DB PRESS Vol. 45に「BK通信」の第2回「数値のバッドノ...</summary>
    <author>
      <name>satoru</name>
      <url>http://namazu.org/~satoru/</url>
      <email>satoru@namazu.org</email>
    </author>
    <dc:subject>article</dc:subject>
    <content type="text/html" mode="escaped" xml:lang="en" xml:base="http://0xcc.net/blog/">
      <![CDATA[<p>
<img src="http://0xcc.net/blog/archives/pic46.jpg" alt="" style="float: right">
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774134864/bk256-1-22/ref=nosim/">WEB+DB PRESS Vol. 45</a>に「BK通信」の第2回「数値のバッドノウハウ」を書きました。数値の処理ではまった話を取り上げています。
</p>
]]>
      
    </content>
  </entry>

</feed>