2013-12-15

C++03とC++14の違い: ライブラリ導入編

京都C++勉強会の宣伝のために、C++03とC++11の違いを、少しづつ解説することにした。

今回は、ライブラリ導入編だ。ライブラリ導入(Library Introduction)とは、C++の標準ライブラリを使うにあたっての約束事を定める章である。たとえば、予約されている名前なども、ここで定められている。

新しい予約された識別子

C++11/14では、新しい標準ライブラリのために、多くの識別子を導入した。既存のC++03のコードで、たまたまその識別子を使っているコードは、名前の衝突を起こす可能性がある。

とはいえ、識別子はほとんどstd名前空間スコープの下にあるし、マクロ名もきぞんのコードと衝突を起こさないように注意深く命名されているので、通常は問題になることはない。

新しいヘッダー

C++11/14では、多くの新しいヘッダーが追加された。

C++の新しくつかされたヘッダーは以下の通り。

<array>, <atomic>, <chrono>, <codecvt>, <condition_variable>, <forward_list>, <future>, <initializer_list>, <mutex>, <random>, <ratio>, <regex>, <scoped_allocator>, <system_error>, <thread>, <tuple>, <typeindex>, <type_traits>, <unordered_map>, <unordered_set>

また、最新のC言語規格に合わせて、以下のヘッダーが追加された。

<ccomplex>, <cfenv>, <cinttypes>, <cstdalign>, <cstdbool>, <cstdint>, <ctgmath>, <cuchar>.

たまたま、同じ名前のヘッダーを使っていた場合、問題になるだろう。しかし、ヘッダーの名前も注意深く選ばれているので、通常は衝突することはないだろう。

std::swapのヘッダーが<algorithm>から<utility>に変更

std::swapを使うコードは、C++11からはutilityを#includeしなければならない。

予約された名前空間posixの追加

posixという名前の名前空間が、あらたに追加された。これは、現時点では空っぽだが、将来使うために予約されている。

もし、posixという名前の名前空間をC++03のコードで使っていた場合、互換性の問題がある。

マクロ名として名前キーワードの追加

attribute tokenとして使われている、override, final, carries_dependency, noreturnは、マクロ名として使うことができない。

もし、このような名前のマクロ名を使っている場合は、互換性の問題がある。

そもそも、まともなC++プログラマーはCプリプロセッサーマクロを使うべきではない。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

また、私の書いたC++11のコア言語を完全に解説した参考書もある。

Gumroadで購入: C++11参考書:C++11の文法と機能

今すぐ閲覧: C++11: Syntax and Feature

誤りがあればGitHubでPull Requestせよ: https://github.com/EzoeRyou/cpp-book

この参考書は、C++の規格のみを参照して記述しており、特定のC++の実装(コンパイラー)で確かめただけで合法、違法を判断する、世間一般によくある駄本とは根本的に質が異なる本である。本書に誤りがあるとすれば、

  1. 誤字脱字
  2. 筆者の規格文面の解釈間違い
  3. 規格文面の誤り

だけである。まだ、世の中の安定版コンパイラーはC++11の規格をバグフリーで完全に実装していない。

2013-12-14

SteamOSが公開された。

SteamOS FAQ :: Steam Universe

[Phoronix] SteamOS 1.0 Is Based Upon Debian Wheezy

[Phoronix] SteamOS Has Its Own Graphics Compositor

[Phoronix] SteamOS Compositor Details, Kernel Patches, Screenshots

[Phoronix] Former NVIDIA, Microsoft Developers Doing Lots Of The SteamOS Work

Valveの忌まわしきDRM付きの邪悪なゲームソフトウェア流通プラットフォームであるSteamに特化したGNU/Linuxのディストロ、SteamOSが公開された。

この不自由ソフトウェアの実行をたやすくしたSteamOSは、Debian Wheezyがベースとなっている。Debianを選んだ理由は、Valveがカスタマイズするものとしては、UbuntuよりDebianの方がやりやすいからだという。

nVidiaやAMDの最新版の不自由なグラフィックドライバーや、最新版のMesaがbackportされているという。また、LinuxカーネルもWheezyの3.2ではなく、3.10となっている。

SteamOSは、デフォルトのUIがBig Pictureモードとなっている。これは、Steamで遊ぶことに特化したUIだ。このBig Pictureモード自体は、GNOME上に構築されている。設定で有効にすれば、デスクトップに切り替えることもでき、普通のGNU/Linuxデスクトップ環境としても使えるそうだ。ただし、初期ではrootアカウントにパスワードがかけられておらず、デスクトップを有効にする際に、パスワードを設定する必要があるのだという。

ValveのFAQでは、passwordコマンドを使えとのことで、まだまだベータといった感じが漂う。

SteamOSは独自のグラフィックコンポジターを使っているという。独自というべきなのか、ややマイナーというべきなのか。その名前をXcompmgrといい、X11上で動作する。Xcompmagr自体は、Keith Packardが書いた、結構昔のコンポジターだ。とても軽いことが特徴で、利用者もいることはいるそうだ。最近は活動的ではなかったそうなのだが、いったいどういうことなのだろう。まあ、今すぐにゲームを実行する必要のある関係上、WaylandやMirのような、全く新しい実装という冒険はできなかったということか。ちなみに、上流のXcompmgrと、SteamOSのXcompmgrのdiffは、2400行になるそうだ。

SteamOSのLinuxカーネルは、linux 3.10 - PREEMPT_RT_FULLで、かなり大量のパッチを当てている。特にリアルタイムカーネル関連のパッチが多いのだとか。

初期化には、SysVinitを使用。今流行りのsystemdではなければ、UbuntuのUpstartでもない。ここも保守的だ。

AMD用のプロプライエタリなバイナリブロブのドライバーも入っているものの、現在のところ、nVidiaのGPUを推奨しているのだとか。

リアルタイムカーネル、X11のグラフィックコンポジターで軽量に定評のあるXcompmgr、SysVinit、ゲーム用の固定ライブラリバイナリセット、だいぶ保守的でゲームの高速動作に特化したような思想が伺える。

私は使いたいとは思わないが、こんな制限的なシステムでも、もたらす善の方が大きいのだろうか。おぼつかなし。

2013-12-13

ECMAがDartを標準化すべく技術委員会を立ち上げた

[Phoronix] ECMA Is Working On Standardizing Google's Dart

ECMAがDartを標準化すべく技術委員会を立ち上げたそうだ。

Dartについては色々と期待している。何しろ、初期に公開した規格書が、まともにフォーマルな文面を用いていて、実に素晴らしかったからだ。

最近のDartの動向は追いかけていないが、なかなか面白そうではある。

ただし、それはDartの独立した実装が複数出てきてからの話だ。現状で、Googleの独壇場なのは危険だ。

C++03とC++11の違い: テンプレート編

京都C++勉強会の宣伝のために、C++03とC++11の違いを、少しづつ解説することにした。

今回は、テンプレートについて、C++03とC++11/14の違いを取り上げる。

C++11では、export機能が廃止となった。

exportは、実装例が極めて少なかったために、C++11では廃止となった。

この変更による互換性の問題は、ほとんどないだろう。というのも、export機能自体が使われていなかったのだから。

C++11では、入れ子となったテンプレートの連続したアングルブラケットの間に、空白文字を挟む必要がなくなった。

template < typename T >
struct S { } ;

// C++03では違法
// C++11では合法
S<S<int>>> s ;

C++03では、右シフト演算子、operator >>と文法上曖昧になるため、必ず空白文字を挟まなければならなかったのだ。

// 空白文字が必要
S<S<int>> > s ;

このような些細な文法上の問題は、利用者の混乱を防ぐために、コンパイラーの努力で何とかするべきだという意見により、C++11では、このような場合、演算子ではなくテンプレートのアングルブラケットだと解釈するようになった。

この変更により、C++03では、右シフト演算子と解釈されるために合法だったコードの解釈が変わってしまう。

template <class T> struct X { };
template <int N> struct Y { };

// C++03では合法、1 >> 2は右シフト式
// C++11では違法、文法上の誤り。
X< Y< 1 >> 2 > > x;

ただし、このようなコードは稀であろうから、おそらくは大丈夫だろう。

C++11では、内部リンケージを持つ関数を依存呼び出しできるようになった。

C++03では、非修飾名での依存呼び出しの際には、外部リンケージの関数しか考慮されなかった。内部リンケージの関数はオーバーロード解決に置いて考慮されなかった。そのため、以下のようなコードは、厳格に規格準拠のC++03の実装とC++11の実装で実行した場合、挙動が異なる。

void f( long ) { } // #1
static void f( int ) { } // #2


template < typename T >
void g( T x )
{
    // C++03では#1を呼ぶ
    // C++11では#2を呼ぶ
    f( x ) ;
}

int main()
{
    g( 0 ) ;
}

C++03では、外部リンケージの関数しか考慮されないので、#2が呼ばれることはない。C++11では、単に実装の簡単化のため、内部リンケージも考慮されることになったので、#2が呼ばれる。

このこととは直接関係ないが、依存呼び出しにおいては、プログラムの全翻訳単位の、その文脈で発見できない名前も含めたすべての外部リンケージを持つオーバーロード関数の候補で、もし、オーバーロード解決の結果、より最適な候補となる関数が存在した場合は、プログラムは違法となる。

例えば、unit_1.cpp, unit_2.cppという、2つのソースファイル、2つの翻訳単位からなるプログラムがあったとする。

// unit_1.cpp
void f( int ) { } // #1
// unit_2.cpp
void f( long ) { } // #2

template < typename T >
void g( T x )
{
    f( x ) ; // 依存呼び出し
}

int main()
{
    g( 0 ) ; // 違法
}

このコードは違法である。なぜならば、依存呼び出しで#2が最適関数となるが、別の翻訳単位で、名前は見つからないものの、より最適な関数があるために、プログラムは違法となる。

これは、テンプレートの特殊化が翻訳単位ごとに異なる結果となることを防ぐためである。

依存名というのは厄介だ。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

また、私の書いたC++11のコア言語を完全に解説した参考書もある。

Gumroadで購入: C++11参考書:C++11の文法と機能

今すぐ閲覧: C++11: Syntax and Feature

誤りがあればGitHubでPull Requestせよ: https://github.com/EzoeRyou/cpp-book

この参考書は、C++の規格のみを参照して記述しており、特定のC++の実装(コンパイラー)で確かめただけで合法、違法を判断する、世間一般によくある駄本とは根本的に質が異なる本である。本書に誤りがあるとすれば、

  1. 誤字脱字
  2. 筆者の規格文面の解釈間違い
  3. 規格文面の誤り

だけである。まだ、世の中の安定版コンパイラーはC++11の規格をバグフリーで完全に実装していない。

JavaScriptへVimを移植

Vim.js - JavaScript port of Vim

なんと、JavaScriptへVimを移植したのだそうだ。準備に時間がかかり、さらに反応も悪いが、たしかにこれはVimだ。いや、Vimそのものだ。

Hacker Newsでは、さっそく、Atwordの法則を引用するものがいる。Atwordの法則、「JavaScriptで書かれ得るプログラムは、いずれJavaScriptで書かれる。」

この法則は、Tim Berners-Leeの the Principle of Least Powerをもとにしている。Tim Berners-Leeは、WebでJavaScriptのような貧弱なプログラミング言語が使われていることを大変喜んでいる。なぜならば、JavaScriptは比較的簡単に解釈できるからだ。そのため、データやプログラムは、他人にも比較的簡単に処理できる。これがもし、Javaアプレットとか、Flashなどで書かれていたならば、なるほど、確かに見た目はいいかもしれないが、とても他人にとって使いづらいデータになってしまう。

Design Issues for the World Wide Web

歯の詰め物がとれた

自宅で遅めの昼食を認めていたところ、右下の歯の詰め物が取れてしまった。

思えば、ここは確か人生初に虫歯になって歯医者にかかったところだ。たしか、7,8年前だったと記憶している。保険の範囲内の治療で、7,8年持てば、まあ平均的といったところだろうか。

どうせこの箇所は、ここ数ヶ月、水を飲んだり、冷たいサラダを食べたりしただけで、わずかに痛むようになっていたので、そろそろ歯医者に行って、診てもらわなければならないと思っていたところなのだ。ただ、その痛むというのが、食べ始めのほんの数秒痛むだけで、痛み自体も僅かなものなので、ついつい放っておいてしまっていた。

しかし、冷たいものが痛むとか、食事で詰め物が取れたということは、中で虫歯にでもなっているのかもしれない。鏡でみてもわからないので、やはり歯医者に行かなければならない。

しかし、残念ながら、今日はあいにくと普段行っている歯医者が開いていない。幸い、土曜日もやっている歯医者なので、明日行くことにしよう。

追記:幸い、とれた詰め物は無事だったので、付け直すだけですんだ。

C++03とC++11の違い: 特別なメンバー関数編

京都C++勉強会の宣伝のために、C++03とC++11の違いを、少しづつ解説することにした。

今回は、特別なメンバー関数について解説する。

C++11では、デフォルトの実装が違法になる暗黙に宣言される特別なメンバー関数は、delete定義される。

delete定義はC++11からの機能だ。これにより、宣言は参照するが、定義を使わないために問題にならなかったC++03のコードが、C++11では明確に違法になる。

いまいちいいコード例が思い浮かばない。

C++11では、デストラクターが暗黙で無例外指定になった。

これにより、デストラクターから例外で脱出すると、std::terminateが呼ばれる。

struct S
{
    // call std::terminate
    ~S() { throw 0 ; } 
} ;

これは、デストラクターは例外を投げるべきではないという原則による変更である。もし、C++11で、どうしてもデストラクターから例外を投げたい場合は、noexcept(false)を明示的に使わなければならない。

struct S
{
    // OK
    ~S() noexcept(false)
    { throw 0 ; }
} ;

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

また、私の書いたC++11のコア言語を完全に解説した参考書もある。

Gumroadで購入: C++11参考書:C++11の文法と機能

今すぐ閲覧: C++11: Syntax and Feature

誤りがあればGitHubでPull Requestせよ: https://github.com/EzoeRyou/cpp-book

この参考書は、C++の規格のみを参照して記述しており、特定のC++の実装(コンパイラー)で確かめただけで合法、違法を判断する、世間一般によくある駄本とは根本的に質が異なる本である。本書に誤りがあるとすれば、

  1. 誤字脱字
  2. 筆者の規格文面の解釈間違い
  3. 規格文面の誤り

だけである。まだ、世の中の安定版コンパイラーはC++11の規格をバグフリーで完全に実装していない。

2013-12-12

Vimにclang_completeを導入した

NoeBundleを得て、Vimのプラグイン導入を恐れなくなった私は、さっそく、Vimにclang_completeを導入した。

Rip-Rip/clang_complete

NeoBundleを使った。とりあえず色々と試した結果、、以下の設定に落ち着いた。

" Install clang_complete
NeoBundle 'Rip-Rip/clang_complete'

let g:clang_periodic_quickfix = 1
let g:clang_complete_copen = 1
let g:clang_use_library = 1

" this need to be updated on llvm update
let g:clang_library_path = '/usr/lib/llvm-3.4/lib'
" specify compiler options
let g:clang_user_options = '-std=c++11 -stdlib=libc++'

他にもテンプレートや関数の引数まで保管してくれるスニペットや、最長一致のものを自動的に入力してくれるオプションもあるのだが、私はテキストエディターが勝手に文字列を入力するのが嫌いなので、有効にはしなかった。

さて、この結果として、私のVim環境は最強のC++IDE環境になってしまった。今や私のVimは、以下のことができる。

  • Makefileを使ってC++11までのコンパイルや実行ができる
  • clang_completeを使ってC++11までの補完ができる
  • Wandboxを使ってC++14のオンラインコンパイルができる

ああ、なんということだ。Windows環境を離れて、唯一心残りのあった、Visual StudioによるInteliSense以上のものが、今ここにある。しかも、もはやMSのような不自由ソフトウェアの追随を許さないほどの高機能だ。しかも、全て自由ソフトウェアだけで実現できている(ただしWandboxは私が支配力を持たないSaaSSであるが)。いや、不自由ソフトウェアでは実現できないことだ。ああ、C++といえばWindowsという時代(一時期MSVCの方がテンプレートのサポートが優れていた時代があった)は、本当に終わってしまった。

ああ、はやくClang 3.4とGCC 4.9が安定リリースされ、C++14が正式発行されて、C++14の補完とローカルでのコンパイルができるようになりたい。

C++03とC++11の違い: 宣言子編

京都C++勉強会の宣伝のために、C++03とC++11の違いを、少しづつ解説することにした。

今回は、宣言子だ。

C++11にはリスト初期化のNarrowing Conversionが禁止された。

以下のような合法なC++03コードが、C++11では違法となる。

// C++03では合法
// C++11では違法
int a[] = { 1.0 } ;

C++11では、リスト初期化というものを新たに導入し、従来aggregateにのみ許されていた{ }による初期化を、ユーザー定義型のクラスにももたらした。この心機能の追加にあたって、リスト初期化では、浮動小数点数から整数型や、より表現できる範囲が狭い可能性のある型への暗黙の変換(例:doubleからfloat、intからshort)を、縮小変換(narrowing conversion)と名付け、明確に禁止した。

もし、どうしても型変換を行いたい場合は、明示的なキャストが必要になる。

// well-formed
int a[] = { static_cast<int>( 1.0 ) } l

そもそも、このような暗黙の型変換には頼ってはならないのである。強い静的型付けによって、コンパイル時にくだらない不具合を発見できるべきで、暗黙の型変換はその妨げになる。

いつか、暗黙の型変換が一切廃止される日をこの目で見たい。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

また、私の書いたC++11のコア言語を完全に解説した参考書もある。

Gumroadで購入: C++11参考書:C++11の文法と機能

今すぐ閲覧: C++11: Syntax and Feature

誤りがあればGitHubでPull Requestせよ: https://github.com/EzoeRyou/cpp-book

この参考書は、C++の規格のみを参照して記述しており、特定のC++の実装(コンパイラー)で確かめただけで合法、違法を判断する、世間一般によくある駄本とは根本的に質が異なる本である。本書に誤りがあるとすれば、

  1. 誤字脱字
  2. 筆者の規格文面の解釈間違い
  3. 規格文面の誤り

だけである。まだ、世の中の安定版コンパイラーはC++11の規格をバグフリーで完全に実装していない。

2013-12-11

C++で、(a/b)*b + a%b != aとなる例

C++では、整数a, bにおいて、"(a/b)*b + a%b"の結果が、"a"と等しくない場合、a/bとa%bの挙動は未定義である(5.6 paragraph 4)

この条件に当てはまるaとbの値が、さっぱり思いつかなかった。b = 0の場合はそうなのだが、それは一つ前のセンテンスでカバーされている。わざわざ書く以上、b = 0以外の例があるはずだ。そこで人に聞いた。一瞬で答えを教えてもらった。

aとbがint型で、int型は2の補数で表現されていて、INT_MIN == -2^(n-1) (nはintのビット数)の場合における、a = INT_MIN, b = -1

なるほど、2の補数だから、最小値と最大値の絶対値が1ずれるわけだ。ずれは最小値の絶対値の方が1大きくなる。-1で割るということは、つまり最大値が最小値の絶対値になるということで、オーバーフローする。

#include <limits>
#include <iostream>

int main()
{
    int a = std::numeric_limits<int>::min() ;
    int b = -1 ;

    int c = (a/b)*b + a%b ;

    std::cout << c << '\n' ; 
}

興味深いことに、GNU/Linux x64のGCCとClangでコンパイルすると、標準出力にFloating point exceptionと出力され、その時点でプログラムの実行が止まる。

xkcd What if?: 星の王子様に出てきた小さな惑星が本当にあったらどうなるの?っと

またもやxkcdから。

小さなお星様

もし、小惑星がとても小さく、しかし超密度であれば、星の王子様みたいに生活できるの?っと

Samantha Harper

先週、我々は巨大な惑星における生活を考察した。今週は、小さな惑星に目を向けよう。

アントワーヌ・ド・サン=テグジュペリ著の星の王子様は、遠く離れた小惑星からの旅人のお話だ。読みやすく、どこか物悲しく、印象深い絵本だ。[1]。子供向けの本だが、対象読者を限定するのは難しい。ともかく、大衆受けしていて、歴史的にもベストセラーになっている。

[1]: 星の王子様のような話をもっと読みたければ、Mallory Ortberg著のこの素晴らしい小説を下までスクロールするといい。

星の王子様は1942年に書かれた。これは小惑星について書くにあたって、とても興味深い年代である。というのも、1942年には、我々はまだ、小惑星がどのような形をしているか知らなかったのだ。当時の最高の望遠鏡を使っても、最大の小惑星は、単なる光の点としてしか観測できなかった。実は、asteroidという名前の由来はそこから来ている。意味は「星のような」だ。

我々が小惑星の形について初めて確認できたのは、1971年、Mariner 9が火星に到達して、フォボスとダイモスの写真を撮影した時だ[2]。この、当時小惑星と信じられていた月[3]は、現代風のポテトのような形の小惑星のイメージを形成した。

[2]: コレがフォボスの画像だ。典型的な小惑星の見た目をしている。この計画に画像アーカイブは、NASA Space Science Data Centerにあるが、奇妙なことに、NSSDCは、実際の画像閲覧は、どっかの個人サイトTripod pageに丸投げしている。

[3]: 興味深いことに、フォボスとダイモスは小惑星の形をしているが、最近の研究によれば、小惑星ではないという。Craddock, Robert AのAre Phobos And Deimos The Result Of A Giant Impact? Icarus (2010)を参照。

1970年代以前、SFでは小さな小惑星も、惑星のように丸いものであるとの考えが一般的だった[4]。

[4]: 皆がそういう考えだったわけではない。だいぶ正確な考えの人もたくさんいた。ヘンテコな考えもあった。

星の王子様はこの考えをさらに飛躍させた。小惑星が、小さな惑星で、重力があり、空気があり、バラもある。ここで科学的に糾弾するのはあたらない。なぜならば、(1) これは小惑星の話ではないし、(2) 大人が物事を真面目に考えすぎることを茶化すためのものだからだ。

そこで、お話を変更するのではなく、科学的に考えればどうなるのかについてみてみよう。もし、歩き回れるほどの表面重力を持った超密度の小惑星があるとする。その小惑星は、とても面白い特性を持っている。

もし、小惑星が半径1.75メートルであれば、地表で地球と同等の重力を有するためには、その質量は500万トンなければならない。これは、地球上に存在するすべての人間分の質量と同じ程度の質量だ。

地面に立つと、潮汐力を感じるだろう。頭より足のほうが重く感じるので、ゆっくりとストレッチしたような感覚を覚えるだろう。あたかも、丸まったゴムボールの上でストレッチしているような感じ、あるいは、頭を中央に向けてメリーゴーラウンドに寝そべったような感覚だ。

地表における脱出速度は、秒速5メートルだ。これは全力疾走よりは遅いが、それでもそれなりには速い。目安として、もし読者がバスケットボールをダンクシュートできなければ、垂直跳びで脱出するのは無理だ。

しかし、脱出速度の面白いところは、進む方向は関係がないということだ[5]。もし、読者が脱出速度よりも速く動けば、その方向が惑星に向かうものでないかぎり、脱出できる。つまり、小惑星を水平方向に走って、崖でジャンプしてもオサラバできるのだ。

[5]: ・・・だからこそ、脱出速度(escape velocity)は、本当は脱出速度(escape speed)と呼ばれるべきなのだ。方向がないというのは(それこそがspeedとvelocityを区別するものなのだから)、とても重要な違いだ。

もし、読者が惑星を脱出するほど速く動けなかったとしたら、軌道上を回ることになる。読者の軌道速度は約秒速3メートルだ。これはジョギングの速度である。

だが、これはとても奇妙な軌道になるだろう。

潮汐力が読者の複数箇所に対して働くことになる。もし、読者が惑星方向に腕を伸ばしたとすると、その腕は体の他の部分よりより強く引かれることになる。もし、腕を地面に下ろしたとすると、体の他の部分は上方向に押し上げられる。これはつまり、読者の体の他の部分は、重力をより軽く感じることになる。結果的に、体の各部位が、それぞれ別々の軌道を辿ろうとするのだ。

このような潮汐力下における巨大な軌道物体は--例えば、月--は、一般的に、粉々に砕けて輪を形成する。これは読者には起こらない。しかし、軌道はカオス的かつ不安定なものとなるだろう。

このような軌道については、Radu D. RugescuとDaniele Mortariによる興味深い論文[6]で検証されている。彼らのシミュレーションによれば、巨大な長い物体は、中心部を軸に不思議なパターンをたどるのだという。質量の中心点すら、古典的な円を描かない。五角形軌道のこともあれば、カオス的に回転した挙句、惑星に衝突するものもある。

[6]: >Rugescu, Radu D., Mortari, Daniele "Ultra Long Orbital Tethers Behave Highly Non-Keplerian and Unstable" WSEAS Transactions on Mathematics, Vol. 7, No. 3, March 2008, pp. 87-94.

このような解析には、実は実用的な応用対象がある。長年、とても高い、車輪とヒモで、荷台を重力圏内外に運ぼうという提案がなされている。いわば空中に浮かぶ 宇宙エレベーターだ。そのようなヒモは、荷台を地表と月間で移動させることができたり、地球の大気圏内から宇宙船を捕まえたりできる。軌道ヒモの不安定性は、この計画における難しい課題となっている。

さて、この超高密度小惑星の住人は、とても注意深く暮らさなければならないだろう。もし速く走り過ぎると、激しく揺さぶられて、昼飯を戻してしまう深刻な危険がある。

幸い、垂直跳びは問題ない。

星の王子様の生活は大変そうだ。

C++03とC++11の違い: 式編

京都C++勉強会の宣伝のために、C++03とC++11の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

今回は式(expression)について。

C++11では、整数の除算と剰余の丸め方向がゼロに向かう。

これはC99との互換性を向上させるための変更である。

C++03では、 整数a, bに対して、a / b の結果が、実数では0.9とか-0.9になった場合、整数の結果の丸め方向がどちらになるのか規定されていなかった。

9 / 10 ; // 0? 1?
-9 / 10 ; // 0? -1?

C++03では、整数a, bで、a, bが、片方、あるいは両方とも正の整数でない場合、a % bの符号は実装依存だった。

3 % 2 ; // 1
-3 % 2 ; // 1? -1?
3 % -2 ; // 1? -1?
-3 % -2 ; // 1? -1?

C++03では、C言語の規格策定で、ISO Fortran 90、つまりISO/IEC 1539:1991の仕様に合わせるのが推奨されていると注記している。

Fortran 90規格の文面によれば、除算の商は、必ずゼロ方向に丸められる。

 9 / 10 ; // 0
-9 / 10 ; // 0

剰余の符号は、以下のようになる。

 8 %  5 ;    //  3
-8 %  5 ;    // -3
 8 % -5 ;    //  3
-8 % -5 ;    // -3

C99はFortranに合わせるによう規定され、C++11でも、C99との互換性向上のため、この規定に合わせることにした。

それにしてもわからないのが、未定義動作となる条件だ。a / bの商が式の結果の型で表現可能ではない場合というのはいいとしても、(a/b)*b + a%bがaと等しくない場合というのは、どうやったら可能になるのかわからない。そういうハードウェアがあるのだろうか。

参考文献:GFortranStandards - GCC Wiki

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

2013-12-10

xkcd What if: お茶をどのくらい激しくかき混ぜたら沸騰するの?っと

xkcdのWhat ifで、お茶をどのくらい激しくかき混ぜたら沸騰するのかということについて考察していた。

What if: 紅茶をかき混ぜる

ぼんやりと熱い紅茶をかき混ぜながら、こう思った。「まてよ、俺は運動エネルギーをこのカップに与えているのではないか?」とね。お茶をかき混ぜると冷めやすくなるけど、もし、高速にかき混ぜたらどうだろうか。かき混ぜることによって、お湯を沸かすことができるだろうか。

Will Evans

ノー

基本的な考えとしては間違ってない。温度というのは単なる運動エネルギーだ。お茶をかき混ぜるということは、運動エネルギーを与えているということだ。そのエネルギーはどこかに行く。お茶がにわかに浮遊したり光を放ったりしない以上、そのエネルギーは熱に変わっているはずだ。

熱に気が付かない理由は、それほど多くの熱を与えていないからだ。水を熱するにはとても多くのエネルギーを必要とする。容量あたりで言えば、水は通常の物質の中では相当に多くの質量あたりの熱容量を持っている[1]

[1]: 水素とヘリウムは、より多くの質量あたりの熱容量を持っているが、これらは気体だ。通常の物質で水に勝るのは、跡はアンモニアぐらいしかない。これら3つの物質は、体積あたりで比較すれば、水に負ける。

水を室温から沸騰寸前まで二分で加熱したい場合、相当の力が必要になる。

\[1\text{ cup}\times\text{Water heat capacity}\times\tfrac{100^\circ\rm{C}-20^\circ\rm{C}}{2\text{ minutes}}=700\text{ watts}\]

注意:沸騰寸前の水を沸騰にまで持って行くには、沸騰寸前までにかかったエネルギーに加えて、さらに大量のエネルギーを必要とする。これはenthalpy of vaporizationと呼ばれている。

この数式によれば、二分でコップ1杯のお湯を得たければ、700ワットの力が必要になる。通常の電子レンジは、700から1100ワットぐらいで、お茶を淹れるぐらいにコップ1杯の水を熱するのに、二分ほどかかる。動くってのは素晴らしいことだ。[2]

[2]: もし動かないとしたら、「非効率」とか「熱源」とかに文句を言うべきだ。

700ワットを二分間というのは、とてつもなく大きなエネルギーだ。水がナイアガラの滝から落ちるとき、運動エネルギーを得て、落下地点で熱に変わる。しかし、相当な距離を落下しても、水は小数点以下の温度ぐらいしか上昇しない[3]。コップ1杯の水を沸騰させるには、大気圏外の高さから落下させなければならない。

[3]: \(\text{Height of Niagra Falls}\times\frac{\text{Acceleration of gravity}}{\text{Specific heat of water}}=0.12^\circ\text{C}\)

オチャアアアアアアァァァァァーーー!!!

かき混ぜることと電子レンジを比較すると?

工業ミキサーの技術レポート[4]によると、筆者の推定では、カップのお茶を激しくかき混ぜると、約百万分の一ワットの熱を与えることになる。これは無視できる範囲だ。[5]

[4]: Brawn Mixer, Inc., Principles of Fluid Mixing (2003)

[5]: お茶はこれよりはやく熱を失う。参照:Ben Harden, Tea temperature vs. Time graph

かき混ぜることによる物理的効果は、やや複雑だ[6]。ティーカップは、その上を対流する空気によって熱が奪われるため、上から冷めていく。かき混ぜるということは、新鮮な温かい水を底からもたらすので、冷却の過程に貢献するだろう。しかし、かき混ぜることによって、空気の流れが阻害され、コップを温めることもある。データ無しでは、なんとも言えない。

[6]: ある状況では、液体をかき混ぜると温度維持に貢献することになる。温かい水は上昇し、水の量が広く十分ならば(例えば海)、温かい層が水面に形成される。この温かい層は冷たい層よりも、ずっとはやく熱を放出する。かき混ぜることに寄って、この温かい層を崩すと、熱を失う速度が減少する。ハリケーンの移動が止まると、力を失うのは、このためである。ハリケーンの波が冷たい水をかき混ぜて、主要なエネルギー源である薄く温かい水の層から遠ざけるのだ。

幸い、我々にはインターネットがある。StackExchangeユーザー、drhodesが、かき混ぜるVSかき混ぜないVSスプーンを連続的に出し入れすることについて、ティーカップの冷却率を計測してくれたのだ。素晴らしいことに、drhodes君は高精度グラフもうpしてくれたし、さらになんと、生データまでうpってくれたのだ。どこぞの科学記事よりよほどデキる奴だ。

結論:かき混ぜるかどうか、スプーンを出し入れするかどうかでは、何も変わらない。お茶は同じ割合で冷却されていく(ただし、スプーンの出し入れはわずかに冷却速度が早かったが)

さて、もとの質問に戻ろう。十分に激しくかき混ぜたら、お茶を沸騰させることができるか?

ノー

まず問題なのだ力だ。700ワットとは、約1馬力にあたる。そこで、お茶を二分間で沸騰させたければ、少なくとも馬を一頭用意して、十分に激しくかき混ぜてもらわなければならない。

あの・・・君、もしよかったら、その・・・
スプーンをくわえて、かき混ぜてもらえるかな?

お茶を長時間加熱することにより、必要な力を減少させることはできる。しかし、時間をかけ過ぎると、加熱より冷却速度が勝ってしまう。

仮にスプーンを十分に激しく--毎秒一万回--かき混ぜることができたとしても、液体力学が立ちはだかる。これほど高速になると、お茶にはキャビテーションが発生する。スプーンの軌跡に真空が発生し、かき混ぜ効率を下げてしまうのだ。

それに、お茶にキャビテーションが発生するほど十分に激しくかき混ぜた場合、水面部分は激しく上昇し、数秒で室温に冷却されてしまうだろう。

いくら激しくお茶をかき混ぜようとも、それ以上に温かくはならないのだ。

C++03とC++14の違い:標準型変換編

京都C++勉強会の宣伝のために、C++03とC++14の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

さて、今回は標準型変換だ。私は便宜上、Starndard Conversionのことを、標準型変換と呼んでいる。

C++14では、リテラルのみが整数nullポインター定数として扱われる。

C++03/11では、コンパイル時に値が0になる整数型もリテラルとして扱われていた。

C++14では、無用の混乱を避けるために、リテラルのみをnullポインター定数とするように改められた。

この違いは、オーバーロード解決などに影響を及ぼす。

void f( void * ) ; // #1
void f( ... ) ; // #2

template < int N >
void g()
{
    // C++03/11では#1を呼ぶ
    // C++14では#2を呼ぶ
    f( 0*N ) ;
}

この例で、依存式、"0*N" は、Nの値がどうなろうと0になる。そのため、C++03では、nullポインター定数として扱われ、オーバーロード解決の結果、ポインター型が最適関数に選ばれる。C++14では、リテラル("0")のみをnullポインター定数と制限したため、0*Nはポインターではなく、#2が呼ばれる。

ただし、C++11/14では、nullポインター定数には、特別なキーワード、nullptrを使うべきであり、0やNULLマクロの使用は、既存のC++03コードを未改変で使う場合のみに留めるべきである。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

当日はUstreamによる配信もある

http://ustream.tv/channel/hatenatech

2013-12-09

Linus、CPUの信頼性について語る

CPU reliability (Linus Torvalds)

2007年のLinusのメールだが、Hacker Newsで話題になっていたので。

From: Linus Torvalds <torvalds@linux-foundation.org>
Newsgroups: fa.linux.kernel
Subject: Re: [patch] CFS scheduler, -v8
Date: Fri, 11 May 2007 16:52:21 UTC
Message-ID: <fa.oZhj8hj7kSDLnitsqrEJcRJN+RE@ifi.uio.no>

On Thu, 10 May 2007, Pavel Machek wrote:

そもそも、今のCPUは300年も稼働するようには設計されていない。50年以上稼働するハードウェアが設計された後で考えても遅くはない。

そうだな。CPU屋はそういうことをあんまり話したがらないようだな、intel.comをgoogleで検索したらこんなのを見つけた。

故障率と平均故障間隔(Mean Time Between Failure: MTBF)のデータは現在、このWebサイトにはございません。情報についてはIntel® カスタマーサポートまでお問い合わせください。

これは要するに、「俺らそんなこたぁ話したかねーや」ってことを丁重に言ってるんだろう。それが実際に悪いとかじゃなくて、単にそういうことを考えていないのだろうし、CPU屋が、顧客にそういうことを考えてほしい理由もない。

ところで、サーバーのCPUは、たいてい低い周波数で稼働しているが、これはMTBF問題によるものだ。思うに、デスクトップCPUは、たいてい5年間稼働ぐらいのスペックなんだろう。(しかも、電源を落とすこともあるし、たいていの時間はアイドルだ)。しかし、サーバーCPUは、もっと長く稼働するし、もっとアクティブだ。

(「アクティブ」 == 「熱」 == 「原子移動とかのダメージがより大きい等」。オーバークロックすべきでない理由はこれだ。そりゃ、快適に動くかもしれんが、CPUの予測寿命を90%落とすことになる)

もちろん、他の部品にだってMTBFはある。(思うに、電源はたいていCPUより先に壊れるだろう)。もちろん、数十年稼働する機械だってあるにはある。だが、機械はすべて、それほど信頼性を持たないと考えるべきなのだろう。

Linus

私の経験からすると、デスクトップコンピューターで壊れやすいのは冷却のためのファンだ。特にGPUカードに内蔵してあるファンが壊れやすい。もう何度も、GPUのファンが壊れたためにGPUを交換している。また、CPUファンが壊れたこともある。

電源ユニットが壊れたこともあるのだが、どうもこれは、電源ユニットのファンが壊れたらしい。しばらくは動くのにいきなり電源が落ち、しかもやたらとPCケースが熱くなっているので、CPUのファンが壊れたかと思って、よく調べたら、電源ユニット内蔵のファンが回っていなかった。

わたしの経験上、CPUが壊れたことはない。CPUファンが壊れて冷却できずに落ちたことなら度々あるのだが(ケースを開けるまでCPUファンの故障に気が付かず、何度か熱で落ちたが)、熱を検知する保護機能によるものか、CPUは故障しなかった。CPUファンを交換後は、全く問題なく動作した。

私が思うに、ゲーム用の高性能なGPUのビデオカードは、長期間稼働することを全く考慮しない設計になっているのではないかと思う。過去に二台しかデスクトップPCを持っていないのに、グラフィックカードは6枚ぐらい故障のために交換している。これは異常な故障率だ。

C++03とC++11の違い: 字句編

京都C++勉強会の宣伝のために、C++03とC++11の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

C++11の新しい文字列リテラル

C++11では、新しい文字列リテラルが導入された。特に、その文字列リテラルのプレフィクス、R, u8, u8R, u, uR, U, UR, LRは、C++03では合法なプログラムで違法になるものがある。例えば、そのような名前をマクロを使っていた場合だ。

#define u8 "abc"

// C++03では"abcdef"
// C++11では"def"
const char * ptr = u8"def" ;

このことからもわかるように、Cプリプロセッサーマクロは危険であり、使ってはならない。

C++11のユーザー定義リテラル

C++11では、ユーザー定義リテラルが導入された。これにより、C++03で合法なプログラムで違法になるものがある。たとえば、ユーザー定義リテラルの場所でマクロを使った場合だ。

#define _x "def"

// C++03では"abcdef"
// C++11では、ユーザー定義リテラル
"abc"_x ;

このことからもわかるように、Cプリプロセッサーマクロは危険であり、使ってはならない。

C++11の新しいキーワード

C++11では、以下の新しいキーワードが導入された。

alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, thread_local

これらのキーワードは、C++03ではキーワードではないので、当然、以下のようなコードを記述することができた。

// C++03では合法
// C++11では違法
int alignas = 0 ;

たまたま新しいキーワードを使っていた既存のコードは、C++03では合法だが、C++11では違法になる。

C++では、標準化にあたって、既存のコードで慣習的によく使われている名前をキーワードとすることは避けている。そのため、通常はこれらの新しいキーワードと既存のコードが衝突することはないだろう。

整数の型

C++では、サフィックスを用いていない整数リテラルの型は、その値によって変わる。もし値がint型で表現できない場合long int型、符号付き整数型で表現できない場合、符号なし整数型になる。

C++11では、C99との互換性のため、long long intを取り入れた。このため、C++03では、unsigned long型になっていた整数リテラルが、C++11では、signed long long int型になる可能性がある。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

wandbox-vimで最高のC++14環境を体験

ClangがC++14の機能完全に到達した話はすでにした。しかし、現状ではClangでC++14が使いづらい

今、ClangでC++14を使うためには、まだ安定リリースされていないレポジトリにある最新のglibc、最新のGCC、最新のClangを落としてビルドして配置して適切にパスを通すことが必要になる。そのような作業は面倒すぎて、個人のローカル上ではやってられない。

そもそも、GNU/LinuxでClangとlibc++を適切に配置してパスを通すのも難しいのだ。そのようなパッケージ化は、メンテナーの手によって行われて欲しいが、それには安定リリースを待たなければならない。はやくても来年後半の話だ。

そこで活躍するのがWandboxだ。

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

なんと、Wandboxでは、常に最新のレポジトリHEADのClangが使えるのだ。コードを送信すれば、コンパイルして、実行して、結果を返してくれる。

これは素晴らしいが、しかし、コードはVimのような本物のテキストエディターで書きたいものだ。そして、コンパイル程度のことは、Vimから行いたいものだ。

Vimではコマンドを呼び出せる。また、makeには特別な対応がなされていて、コンパイルの処理をMakefileで書いておけば、Vimから簡単に呼び出せる。

そして、VimはGCCのような有名コンパイラーのエラーメッセージをパースして表示し、直接問題箇所に飛べる、quickfixという機能を標準で提供している。

これにより、Vimは何もプラグインをインストールしなくても、コーディングに最適なテキストエディターとなっているのだ。

しかし、Wandboxはオンラインのサーバーで提供されているSaaSSだ。ああ、なんとかしてVimで簡単に扱えないものか。

実は、そのようなプラグインがある。その名も、wandbox-vimだ。

rhysd/wandbox-vim

Wandbox-vimでは、vimで:Wandboxとコマンドを打つだけで、現在のバッファーをWandboxに送って、結果を表示してくれる。

しかもしかも、このwandbox-vimは、機能の更新で、エラーや警告のメッセージをquickfixに流しこんでくれるようにもなったのだ。

今すぐC++14の環境使いたいですよね?

さあ、今すぐアクセス!

GCC 4.9が安定リリースされ、GNU/Linuxのディストロがパッケージ化するまでの間は、とりあえずWandboxでC++14を試すことができる。

2013-12-08

予定のメモ

来週はやることが多いので、メモ代わりに書き出してみる。

16日の夜に、はてなのセミナールームを借りて、江添とボレロ村上の京都C++勉強会を行う

勉強会が終わった後に、ボレロ村上さんを囲んで鍋をする。

17日、おそらく朝は吉田寮にいる。

18日の夜、依頼が会ったので、東京でC++の歴史について講演。(いずれ機会があればスライド資料を使って公開された場でも行うかも)

たぶん卓球ハウスに泊まる。

19日以降、

ギークハウスを見学する。少なくとも、ギークハウス水道橋とギークハウス文京護国寺を見学する。他のギークハウスはどうしよう。

妖怪ハウスにも行く。

さて、これを考えると、18日からその週末まで東京でぶらぶらするべきなのかもしれない。

また、17日のうちに東京入りしてしまうのも手かもしれない。

せっかくだから、この機会に都内のギークハウスに連絡して、行ける場所に一日一件見学に行ってみたい。問題は、東京都内だけでも10件以上あるということだ。

квашеная капустаの肉炒め

квашеная капуста(クヴァーシュナヤ カプーシュタと聞こえる)の肉炒めを食べた。ロシア風のザワークラウトだそうだ。要はキャベツの塩漬けだ。人参が入るのがロシア風なのだとか。

酸っぱいキャベツと肉を一緒に食べると、とてもうまい。

ついでに、日本語入力経由でキリル文字で入力してもらった。

あとで、試みにiBus 1.5でロシア語キーボードレイアウトを追加してみた。キリル文字が打てるようになったが、残念ながら私にはキリル文字は読めないので、もとに戻した。

neobundle.vimのインストール方法

Shougo/neobundle.vimは、Vimプラグインのインストールと管理のためのプラグインである。

インストール方法

まず、GitHubから最新版を引っ張ってくる。私の今使っているネットワークの都合上か、sshでcloneできなかったので、httpsを使う。

$ mkdir -p ~/.vim/bundle
$ git clone https://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim

次に.vimrcに設定をする。最小限の例は以下のようになる。

if has('vim_starting')
  set runtimepath+=~/.vim/bundle/neobundle.vim/
endif

call neobundle#rc(expand('~/.vim/bundle/'))

" Let NeoBundle manage NeoBundle
NeoBundleFetch 'Shougo/neobundle.vim'

" add plugins

filetype plugin on

NeoBundleCheck

neobundleにプラグインを管理させるのはとても簡単。.vimrcに追加していく。特に、プラグインがgithubで公開されている場合、ユーザー名とレポジトリ名を指定するだけでいい。

" install wandbox-vim
NeoBundle 'rhysd/wandbox-vim'

必要なだけ書いたら、vimを起動して、

:NeoBundleInstall

すればよい。

アップデートしたくなったら、

:NeoBundleUpdate

するだけでいい。

GitHub以外の場合、gitのURLを指定することができる。また、subversionもサポートしているようだ。

それにしても、よくVimプラグインでこれをやるものだ。これまで、@ShougoMatsu さんは、Vimの頭のおかしい人だと思っていたが、なんとVimの変態だったとは。

CとC++の違い: プリプロセッサー編

京都C++勉強会の宣伝のために、CとC++の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

C++では、__STDC__については規定されていない。

__STDC__は、C言語の実装において定義されるプリプロセッサーマクロである。C++はC言語ではないので、このマクロについてC++の標準規格上、なにか規定することはできない。

そのため、__STDC__は、その値と、定義されるかどうかも含めて、何も規定されていない。C++実装はそれぞれ独自に、このマクロの扱いを決めることになる。

しかし、C++はC言語の拡張として発展したという歴史があり、100%ではないものの互換性があるという事情もある。既存のCコードに、このプリプロセッサーマクロに依存したコードがある場合、たとえC++と互換性のあるCコードでも、このプリプロセッサーマクロが定義されていないという理由だけでコンパイルできなくなるかもしれない。そのために、このようなプリプロセッサーは、C言語との互換性が問題になる場合、定義しておきたい。しかしそれは、ある意味嘘をつくことになる。しかし、そもそもそのようなプリプロセッサーに依存するようなCコードの問題もある。

Cプリプロセッサーは滅びるべきなのだ。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

2013-12-07

CとC++の違い: 特別なメンバー関数編

京都C++勉強会の宣伝のために、CとC++の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

C++では、暗黙に生成されるコピーコンストラクターとコピー代入演算子は、volatileオブジェクトをコピーできない。

struct S
{
    int i ;
    // C++
    // 暗黙のコピーコンストラクター
    // S( S const & ) ;
    // 暗黙のコピー代入演算子
    // S & operator =( S const & ) ;
} ;

int main()
{
    volatile struct S s = { 0 } ;

    // Cでは合法
    // C++では違法
    struct S s2 = s ;
}

これは、暗黙に生成されるコピーの仮引数の型が、T const &だからだ。強い静的型付けをもつC++だから、このままではvolatileオブジェクトは受け取れない。

volatileの扱いは色々と難しく、C++では色々と議論された。

暗黙のコピーを、const volatile T &とする案は、最適化の妨げになるという理由で却下された。三種類のCV修飾されたコピーを暗黙に生成するという案は、とても複雑になり、予期しない問題を生むだろうという理由で却下された。結局、このようなコード例は少ないだろうからということで、この点ではCとは非互換になることを決定した。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

2013-12-06

CとC++の違い: クラス編

京都C++勉強会の宣伝のために、CとC++の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

今回は、クラス編だ。C++ではクラスを導入したせいで、C言語の構造体とは少し違ったスコープのルールになっている。

C++では、クラス宣言はクラス名をスコープに持ち込む。C言語ではクラス名を持ち込まないし、外部スコープの名前を隠すこともない。

int x[99] ; // #1

void f()
{
    struct x { int i ; } ; // #2

    // Cでは#1のサイズ
    // C++では#2のサイズ
    sizeof( x ) ;
}

これはなぜかというと、C言語では、宣言した構造体名は必ず、structキーワードをつけて使うからだ。C++では、基本型とユーザー定義型の文法に違いを持たせたくないため、クラス名だけで使えるようにしている。そのため、クラス名がスコープに導入される。

C++では、int型のビットフィールドの型は符号付きである。Cでは符号は実装依存である。

int型のビットフィールドの符号を実装依存にするのは、テンプレートの実体化のさいに問題になる。一貫性を保つため、非依存名でも、符号つきになるように、実装の自由度を狭めた。

いくらビットフィールドとはいえ、"int"なのに、符号付きかどうか実装依存というCの定義は不思議だ。

C++では、ネストされたクラス名の属するスコープは、直前の外側のクラススコープである。Cでは、直前の外側のクラスが属するスコープである。

struct Outer
{
    struct Inner { } ;
} ;

// Cでは合法
// C++では違法
struct Inner i ;

C言語はわけがわからない。

どうやら、当時のC言語における構造体というのは、そもそもスコープがどうというものではなかったようだ。そもそも、名前もtypedef名で与えるコードが一般的だったようだし、全然別の言語なのだろう。

C++では、メンバー関数を導入したことにより、クラスは厳格にスコープを持たなくてはならなくなった。それがこの違いを生んだのだろう。それにしても、Cは汚い。

C++では、クラス名ですでにtypedef名が使われた場合、そのtypedef名が再宣言されてはならない。

typedef int I ;

struct S
{
    I i ; // typedef名をすでに使う

    // Cでは合法
    // C++では違法
    int I ;
} ;

たしかこれはD&Eにも書いてあった内容のはずだ。クラスはその完全な定義が明らかになった後に、再び銭湯から解釈した時に、メンバー名の意味が変わってはならないというルールだ。それにしても、Cは汚い。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

OCNモバイルONEのレビュー

好意で、OCNモバイルONEのSIMカードをしばらく貸してもらうことになった。

今回貸してもらったSIMカードの契約内容は、月々1980円で、帯域が500kbps、転送量制限が月あたり7GBで、転送量を超過すると、帯域が200kbpsに制限されるというものだ。

OCN モバイル ONE | OCN プロバイダ(インターネット接続)

何故か公式Webサイトには負の広告効果を発生させそうなデブ女が怪訝そうな顔をしてSIMカードをつまんでいるが、この女がSIMカードの意味を理解しているとは思えない。一体、世の広告業界は何を考えているのだろうか。特に英語力で有名でもない人間に英会話教室の広告をさせたり、特に技術力に優れていると定評のあるわけでもない人間にコンピューターやソフトウェアの広告をさせたりしている。

試みに、筆者が、かければアキバ系の彼でもジャニ系に変身できるというあの伝説のサングラスの広告に出ている場面を想像せよ。およそあり得べからざる光景である。およそジャニ系を名乗るには、髪をだらしなく生やした上で寝ぐせをたっぷりとつけねばならないのである。機能美を何よりも優先する筆者は、頭髪などもとより剃りあげている。頭髪などは本来人間に不要の体毛である。人間がいまだわずかに体毛を維持しているのは、単にヒトが進化の途中であるに過ぎないのだ。

これまでに使っていた、DTIのServerMan SIM LTEは、帯域が150kbps、転送量制限がなし、強制画像劣化圧縮プロクシというものだった。

ServersMan SIM LTE:【dream.jp】

本の虫: 100kbpsで閲覧できるWebサイト、できないWebサイト

この記事を書いた後も色々と試したのだが、このDTIの画像の劣化圧縮のためのプロクシは、かなり厄介だ。というのも、このプロクシが間にあるおかげで、ものすごい遅延が発生する。しかも、このプロクシサーバー、かなり頻繁に不安定になり、コネクションははれるが、一切受信できない状態に陥る。例えば、昨日は一日中、使うことができなかった。

そう、DTIの格安SIMでよく発生している問題は、帯域ではなく、DTIのクソプロクシの問題だと思うのだ。

OCNモバイルONEには、そのような罠はない。500kbpsとは帯域が5倍であるが、帯域以上に、このクソプロクシがなくなったというのが大きい。これで、十分に待てば、どのようなWebサイトでも閲覧できるようになる。

たとえば、通常のGMailのWeb上のUIも少し待てば表示されるし、Google Mapsも少し読み込みに時間がかかるが使える。さらに、Street Viewまで使えるのだ。

もちろん、筆者のコンピューターはOSから上のソフトウェアはすべて自由ソフトウェアのみで構成されているので、Flash Playerは入れていない。同じく貰い物のこのラップトップは、IntelのHD3000を使っており、公式に自由なソフトウェアスタックを使ったドライバーが提供されていて、ドライバー環境はとても綺麗なのだ。Google MapsのStreet viewは、GPU支援があるのか、それともChromiumのソフトウェアエミュレーションかはしらないが、WebGLを使うことで、パフォーマンス上全く問題なく利用できる。

他にも、pixivを画像の超絶劣化なしに閲覧できるし、今は吉田寮にいるので検証できないが(とはいっても、今筆者が座っているこたつの周りにはエロ画集とかも転がっているので、できない理由もないのだが)、おそらくxvideosも問題なく閲覧できることであろう。特に、今回は技術的に面白いこともないので、xvideosは検証しない。特に動かないであろう理由もないからだ。

しかし、今は無線によるインターネット接続が本当にお手軽になってきた。

CRTPと仮想関数呼び出しの比較

Eli Bendersky's website » The cost of dynamic (virtual calls) vs. static (CRTP) dispatch in C++

CRTPを使えば、コンパイル時に決定できるような派生クラスの関数呼び出しは、仮想関数呼び出しで実行時に解決しなくても、直接呼び出せることになり、仮想関数呼び出しを省略できる。このコストはいかほどか。

アーキテクチャーによっては6倍になるそうだ。

X11の究極の互換性の実証

The Resistor Network: A Testament to X11 Backwards Compatibility

Hewlett Packard 1670A Deep Memory Logic Analyzerという1992年のマシンに、Xサーバーに接続できる機能があるので、Linux Mint 15とe17で試してみたところ、なんと問題なく動いたそうだ。

なんと言うプロトコルの後方互換性。

2013-12-05

CとC++の違い: 宣言編

京都C++勉強会の宣伝のために、CとC++の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

今日は、宣言の違いを解説する。

C++では、staticやexternキーワードは、オブジェクトの宣言にのみ使用できる。型の宣言に指定することはできない。Cでは、型の宣言に指定することもできた。その場合、単に無視される。

// Cでは無視される
// C++ではエラー
static struct S
{
    int i ;
} ;

C言語では、合法ではあるが、単に無視されていた文法を、禁止しただけだ。このようなコードはまず書かれていないだろうから、特に問題にはならないだろう。

C++では、同一のスコープ内で、typedef名とクラス名を重複して宣言することができない(ただし、同名のクラスへのtypedef名を除く)。Cでは、構造体名と異なるエンティティで同名のtypedef名を宣言できる

// OK in C and C++
typedef struct S { } S ;

// CではOK
// C++ではエラー
struct name { } ;
typedef int name ; 

なぜC言語ではこれが許されていたかというと、C言語では、構造体は必ずstructキーワードを使う必要があったからだ。

struct S { } ;

// Cではstructキーワードが必須
struct S s ;

C++では、基本型とユーザー定義型を、なるべく区別なく使えるようにしようという観点から、このようなstructキーワードの使用の省略を許した。そのため、クラス名はスコープ内で重複することができなくなり、このような変更が必要となった。

C++ではconstなオブジェクトは必ず初期化されなければならない。Cでは、初期化しなくてもよい。

// well-formed in C
// ill-formed in C++
const int object ;

constオブジェクトは、変更できないわけだ。したがって、constオブジェクトが有益な値をとるには、必ず初期化されなければならない。したがって、C++ではconstは初期化しなければならない。

そもそも、constを導入したのはC++が先で、Cが後から追随したはずだ。C言語というのは不思議な劣化があるものだ。

C++では、暗黙のintを廃止

あー、暗黙のint、あの忌まわしき機能を解説することになるとは、私はよほど前世で悪業を重ねてきたに違いない。

f( const x )
{
    const y = x ;
}

このようなコードが、「暗黙のint」というタイプするのさえ恐ろしい機能によって、Cでは合法になる。関数fの型はint( int )で、変数yの型もintだ。

C++では、autoキーワードをストレージクラス指定子として使えなくなった。

Cでは、autoキーワードは、ローカル変数を自動ストレージ上に確保するための指定子だった

void f()
{
    auto int x = 0 ;
}

ただし、古今のC言語のコードで、autoキーワードを教科書以外で使っているのを見たことがない。なぜならば、ローカル変数はデフォルトで自動ストレージ上に確保されるのだから、わざわざつける必要がないからだ。

C++では、キーワードを再利用して、初期化子の式から変数の型を推定する新機能として生まれ変わった。

auto x = 0 ; // int

C++でこのような破壊的変更を行えたのも、結局、誰もautoキーワードなんか使っていなかったからだ。

C++では、enum型のオブジェクトには、同じenum型のenumeratorしか代入できない。Cでは、どんな整数型でも代入できる。

// well-formed in C
// ill-formed in C++
enum color { Red, Green, Blue } ;
enum color = 1 ;

強い静的型付けを持たないCはどうしようもない。

C++では、enumeratorの型はその属するenum型。Cでは、int型

enum E { value } ;

// C++における式の型はE
// Cにおける式の型はint
value ;

強い静的型付けを持たないCは悲惨だ。

次回は、宣言子の違いについて解説する。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

2013-12-04

CとC++の違い:式編

京都C++勉強会の宣伝のために、CとC++の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

今回は式編

C++には関数の暗黙宣言がない

昔のC言語には、関数の暗黙宣言があり、関数名は宣言しなくても使うことができた。C++では、名前は宣言しなければ使えない。

void f()
{
   g() ; // エラー、gは宣言されていない
}

C++では、型は宣言の中で定義しなければならない。C言語ではsizeof演算子やキャスト式の中で定義することもできた。

// Cでは合法
// C++では違法
size_t size = sizeof( struct { int i ; } ) ;

条件式、代入式、コンマ式の結果がlvalueになることがある

C++では、リファレンスにより、関数がlvalueを返すこともできる。

これは、lvalueからrvalueへの変換をあてにしていたCコードを壊すおそれがある。例えば以下のようなコードの挙動が異なる。

char arr[100] ;

// C++では結果は100
// Cでは結果はsizeof(char *)
sizeof( 0, arr ) ;

まあ、この挙動に依存したコードはまれだろう。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

C++の歴史のスライド資料をGitHubで公開

C++の歴史について話してくれという依頼があったので、そのためのスライド資料を書いた。

依頼主からは独立した内容で、C++の歴史や標準化委員会の実情を書いていて面白いと思うので、GitHubで公開する。

GitHub: EzoeRyou/cpp-history

GitHub Pages: C++の歴史

まだまだ加筆するかも知れない。

今回の依頼主の講演は非公開だが、いずれ個人的に勉強会を開いて、このスライドを使った発表もしたいものだ。

結局、自由なものに金をだすというのは、こういうものを作るのに金を出すということになるのだろう。金を出さなくても誰かがいずれ書くかも知れないが、それは数百年後かも知れない。今欲しければ、金を出して書ける者に書いてもらうのが手っ取り早い。

2013-12-02

CとC++の違い: 標準型変換編

京都C++勉強会の宣伝のために、CとC++の違いを、少しづつ解説することにした。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

今回は標準型変換の違い。

C++では、void *から任意のポインター型への変換には明示的なキャストが必要

C言語では、void *型は特殊な型で、任意の型へのポインター型をvoid *型に暗黙に型変換できるし、またvoid *型から任意の型へのポインター型に暗黙に型変換できた。

// Cコード

int * ptr = NULL ;
void * v = ptr ; // OK
int * i = v ; // OK

C++では、void *への変換は暗黙にできるが、void *から他の型への変換は、明示的なキャストが必要になった。

// C++コード

int * ptr = nullptr ;
void * v = ptr ; // OK
int * i = static_cast< int * >( v ) ;

明日も、宣伝のために式の変更点を解説する。

江添とボレロ村上の京都C++勉強会が、12月16日に行われる。これを書いている時点では、まだ空きがあるので、最新のC++14の新機能と、コンパイル時レイトレーシングを勉強したければ、ATNDで参加申し込みをせよ。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド