2017-04-26

どんなWebページでもtexによる数式描画を追加できるブラウザー拡張

EzoeRyou/inject-mathjax: どんなWebページにもMathJaxをロードするブラウザー拡張

任意のWebページにMathJaxを読み込ませてtexによる数式表現を化膿するChromium, Google Chrome向けブラウザー拡張。

インストール


git clone
vim whitelist_urls.conf
make

してからChromiumにインストールする。

whitelist_urls.confには一行にひとつ、MathJaxを読み込ませたいURLをマッチパターンで記述する

Match Patterns - Google Chrome

特徴

このブラウザー拡張はwhitelist_url.confに記述したマッチパターンのURLに対し、

  1. CSP(Content Security Policy)を無効化する
  2. MathJaxをロードする
  3. MathJaxを定期的に呼び出す

という処理を行う。

類似のブラウザー拡張より優れている点

すでに類似機能を提供しているブラウザー拡張があるが、コンピューターリテラシーのないユーザーのためにあまり洗練されていない実装になっている。

CSPの普及により、多くのWebサイトでは外部ドメインのスクリプトがロードできなくなっている。CDN経由でMathJaxをロードするには、まずCSPを無効化しなければならない。CSPはセキュリティを向上させるものであり、不必要に無効化すべきではない。そのため、MathJaxをロードする必要があるURLのみ無効化すべきだ。 Chromium, Google ChromeでCSPを無効化するには、レスポンスヘッダーをブラウザーが解釈する前に改変するブラウザー拡張用の機能を使う。そしてCSPの部分を削除する。

これは以下のようなコードになる。


for (var i = 0; i < details.responseHeaders.length; i++) {
    if ('content-security-policy' === details.responseHeaders[i].name.toLowerCase()) {
        details.responseHeaders[i].value = '';
        // 実際にはCDNを追加するのでもう少しマシ
    }
}

巷に出回っているブラウザー拡張は、このレスポンスヘッダーからCSPを削除するためのコールバック関数を、すべてのURLに対して読み出す。そして、自薦に設定したURLのみに適用するように条件分岐する。


function( details ) {

    if ( !is_whiltelist_urls(details.url) )
        return ;
}

ブラウザー拡張側のコードでURLを判定している。

理想的には、ブラウザー拡張のmanifest.jsonのpermissionsで適用されるURLを厳しく指定すべきだ。しかし、そのためにはユーザーがmanifest.jsonを変更する必要がある。

このブラウザー拡張は、whitelist_urls.confに記述されたマッチパターンをpermissionsにもつmanifest.jsonを生成して、ブラウザー拡張をユーザーが作るようになっている。

2017-04-24

マストドンで数式を表示するブックマークレット

読者はすでにマストドンをしているだろうか。マストドンは自由なSNSで未来がある。もはや不自由なSNSであるTwitterやFacebookの時代は終わった。今年中にも滅びるだろう。

さて、マストドンで不便な点として、数式が表示できないという問題がある。しかし、これは自由なソフトウェアであれば改良が可能だ。

以下のリンクをブックマークバーまでドラッグするか、URLをコピーしてブックマークとして追加しよう。

#mathトドン

そして、マストドンを開いたタブで、ブックマークをクリックするのだ。

すると、

$$
 \mathsf{K}_\nu(x) =
  (\pi/2)\mathrm{i}^{\nu+1} (            \mathsf{J}_\nu(\mathrm{i}x)
       + \mathrm{i} \mathsf{N}_\nu(\mathrm{i}x)
       )
  =
  \left\{
  \begin{array}{cl}
  \displaystyle
  \frac{\pi}{2}
  \frac{\mathsf{I}_{-\nu}(x) - \mathsf{I}_{\nu}(x)}
       {\sin \nu\pi },
  & \mbox{for $x \ge 0$ and non-integral $\nu$}
  \\
  \\
  \displaystyle
  \frac{\pi}{2}
  \lim_{\mu \rightarrow \nu} \frac{\mathsf{I}_{-\mu}(x) - \mathsf{I}_{\mu}(x)}
                                  {\sin \mu\pi },
  & \mbox{for $x \ge 0$ and integral $\nu$}
  \end{array}
  \right.$$

$$ \mathsf{K}_\nu(x) = (\pi/2)\mathrm{i}^{\nu+1} ( \mathsf{J}_\nu(\mathrm{i}x) + \mathrm{i} \mathsf{N}_\nu(\mathrm{i}x) ) = \left\{ \begin{array}{cl} \displaystyle \frac{\pi}{2} \frac{\mathsf{I}_{-\nu}(x) - \mathsf{I}_{\nu}(x)} {\sin \nu\pi }, & \mbox{for $x \ge 0$ and non-integral $\nu$} \\ \\ \displaystyle \frac{\pi}{2} \lim_{\mu \rightarrow \nu} \frac{\mathsf{I}_{-\mu}(x) - \mathsf{I}_{\mu}(x)} {\sin \mu\pi }, & \mbox{for $x \ge 0$ and integral $\nu$} \end{array} \right.$$

と表示される。ちなみにこれはIrregular modified cylindrical Bessel functionだ。

これで、マストドンで数式を表現できる。このブックマークレットを使っているもの同士ならば、数式で会話できる。

ちなみに、コードは以下の通り。

(function(){

var config = document.createElement( "script" ) ;
config.type = "text/x-mathjax-config" ;
config.appendChild( document.createTextNode( 'MathJax.Hub.Config({tex2jax: {inlineMath: [["$","$"], ["\\\\(","\\\\)"]]}});' ) ) ;

document.head.appendChild(config) ;

let script = document.createElement( "script" ) ;
script.type = "text/javascript" ;
script.async="async" ;
script.src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_SVG" ;

let inner_script =
    'window.setInterval( function() { MathJax.Hub.Queue(["Typeset",MathJax.Hub]); '
+   'let textarea = document.getElementsByClassName("autosuggest-textarea__textarea")[0] ;'
+   'if ( textarea !== null && textarea.value === "" )'
+       'textarea.value = "#math " ;'
+   '}, 1000 ) ;' ;


script.appendChild( document.createTextNode( inner_script ) ) ;

document.head.appendChild(script) ;
})() ;

ちなみに、このコードはデフォルトで入力欄に#mathを入力する。この挙動が気に入らない人は、以下のブックマークレットを使うとよい。

mathトドン

コードは以下の通り。

(function(){
var config = document.createElement( "script" ) ;
config.type = "text/x-mathjax-config" ;
config.appendChild( document.createTextNode( 'MathJax.Hub.Config({tex2jax: {inlineMath: [["$","$"], ["\\\\(","\\\\)"]]}});' ) ) ;

document.head.appendChild(config) ;

let script = document.createElement( "script" ) ;
script.type = "text/javascript" ;
script.async="async" ;
script.src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_SVG" ;

let inner_script = 'window.setInterval( function() { MathJax.Hub.Queue(["Typeset",MathJax.Hub]); }, 1000 ) ;' ;



script.appendChild( document.createTextNode( inner_script ) ) ;

document.head.appendChild(script) ;
})() ;

2017-04-20

ここらでもう一度マストドンについて語っておくか

オレが間違っていたぞ、清水亮。

なんで「オレが間違っていた」と最初に書けないのか。つまんねープライドもってんなー

-- 清水亮

https://mstdn.onosendai.jp/users/shi3z/updates/1002

前回、前々回と、マストドンについての批判を書いた。結論を先に書くと、私の技術上の懸念以外の懸念はすべてあたらなかった。

本の虫: そろそろマストドンについて語っておくか

本の虫: マストドンが直面している問題はすでにP2P技術が15年前に遭遇した問題だ

そうこうしていると、ドワンゴがマストドンのインスタンスを立ち上げた。

https://friends.nico/

これはなかなか興味深い。というのも、私はドワンゴに雇用されているので、ドワンゴが悪意を持っているかどうかについては内部の情報があるため判断しやすい。マストドンはインスタンスの管理者が悪意を持っているかどうかが極めて重要だ。内部の情報をもって判断した結果、今は信用できそうだ。

そこでものは試しとアカウントを作ってみた。

EzoeRyou

そして、感動した。これだ。久しく忘れていたインターネットがここにある。何ということだ。

そこにあったのは、黎明期の怪しげな雰囲気を持つインターネットだった。今から20年ほど前の2chやIRCの雰囲気だ。インターネットよ、私は帰ってきた。

ともすればインターネット老人会とも揶揄される環境がそこにあった。我々はぬるぽにガッされ、ゴノレゴが吉野家のにわか客に文句を言い、ペリーに開国を迫りミキコにピアノを教えるあの空気が再現されていた。

そうだ。当時もこうして、夜遅くまで寝不足になりながらインターネットを閲覧したものだ。そうこうしているうちに、誰かがセンシティブなコンテンツのフラグが立てられた画像が投下される。みてみるとうまそうな飯テロ画像であった。「これはけしからん、無修正じゃないか」と文句を言うと、こんどはモザイクをかけた飯テロ画像が投下される。

開始当初のマストドンのドワンゴインスタンスには優れた点が二つある。まずエロが投下されないことと、誰も煽り合わないことだ。放っておいても人はエロを探すし、勝手に煽りあう。そういうものだ。

インターネットからきらめきと魔術的な美がついに奪い取られてしまった。2chや、IRCや、アングラサイトがユーザー達と共に中二病を誇り合い、徹夜でチャットにあけくれ、不毛なネット議論を繰り広げる。そんなことはもう、なくなった。

これからのインターネットユーザーは、安全で静かで、物憂いスマフォを握って、画面を受動的にタップ操作のみする。一方何千というコンテンツ達が、アルゴリズム一つで機械の力によってフィルターされ、検閲される。これから先のインターネットは、安全と引き換えにその娯楽性を完全に殺すだろう。

やがてそれぞれのプラットフォームには、大規模で、限界のない、一度発動されたら制御不可能となるような検閲のためのシステムを生み出すことになる。

人類ははじめて自分たちが手に入れた自由な情報流通手段を、みすみす自ら手放すことになる。これこそが人類の栄光と苦労のすべてが最後に到達した運命である。

結局、Twitterなどの大手のSNSはあまりにも有名になりすぎ、あまりにも大衆化しすぎたために、つまらなくなってしまったのだろう。大衆受けを目指すと、きらめきと魔術的な美が失われてしまうのだ。

この歴史は連続している。パソ通が、あめぞうが、2chが、ニコニコ動画が、開始当初はこの黎明期特有の怪しいきらめきを有していたが、大衆化に伴って消失してしまったのだ。これはどうしようもないことだ。大衆化の過程で、より多くの、より幅広い人間に受け入れやすくなり、その結果利益を出すことができ、その利益をプラットフォームの維持と拡張に使うことができる。大衆化をしない場合、利益が出ずにプラットフォームが継続できないとしたら、結局大衆化するしかない。

もちろん、これはドワンゴのマストドンインスタンスとて例外ではない。いずれはユーザーが集まりすぎて大衆化して万人受けにはなるが陳腐化するか、ユーザーが集まらず過疎化してひっそりと消失するかのどちらかになるだろう。どちらにしても、現在のこの魔術的な美は速やかに失われるだろう。

せめて今は、この雰囲気を楽しむとしよう。

さて、ポエムを書くのはここまでにして、技術的な話をしよう。

マストドンと元になったGNU Socialは、OStatusというプロトコルを使っている。このプロトコルの詳細な内容を筆者は知らない。

というのも、OStatusプロトコルの網羅的なドキュメントが存在しないからだ。5年前は存在していたのかもしれないが、散逸してしまっている。本来ドキュメントをホストしていたはずのURLのドメインの所有者が変わって全く関係ない内容になったりしている。

それでも散らばっているドキュメントを読んでキーワードを拾っていくと、ユーザーの発見にWebFinger、購読にPubSubHubbub、メッセージのやり取りにSalmonを使っていることなどがわかった。あるいは、OStatusプロトコルという単一のものはなくて、細分化されたプロトコルの寄せ集めでできているのかもしれない。

さて、プロトコルの技術的な詳細は後で調べるとして、筆者の理解する限りでは、OStatusプロトコルはスケーラビリティの問題を抱えている。おそらく現在の設計では、規模が拡大したときに、負荷がとても増えていくはずだ。なので、Twitterを代替するほどの規模で成立できるかどうか疑問だ。

また、ユーザーの認証がサーバーに結びついているのも問題だ。ユーザーの発見と認証のプロトコルであるWebFingerを調べたところ、どうやらユーザーには絶対に変わらない永続URLが必要なようだ。これではサーバーレスな実装は困難だ。

したがって、規模の小さい今はこのままOStatusプロトコルを使うのはいいとしても、早急に別のより優れたスケールするプロトコルを設計すべきだろう。

ただし、この技術的にスケールしないという問題は、実は問題にならないかもしれない。というのも、1インスタンスに数万人もユーザーが殺到するような状況を作り出さなければいいのだ。したらばやRedditのように、ユーザーが自分の管理するインスタンスを立ち上げるようなサービスにして、1インスタンスあたりのユーザーを抑える文化を作り出せば、スケールは問題ではなくなる。たかだか1万に満たない程度のユーザーを処理するならば、どんなに富豪的な設計でも耐えられる。ユーザーがジャンルごとにインスタンスを作り、自治を行う。楽しい世界だ。

例えば支持政党ごとにインスタンスがあり、自民党支持者は自民党インスタンスに、民進党支持者は民進党インスタンスに登録する。そしてインスタンス間の戦争が起き、連結が遮断される。「我々自民党インスタンスは民進党インスタンスとの連結を解除した。これは民進党が我々の党議に賛同しないからである」などといった具合だ。

さて、最後に自由の話をしよう。

マストドン、GNU Socialにとって、自由は極めて重要だ。なぜならばその開発目的が、SNSプラットフォームの独占の打倒にあるからだ。

マストドンとGNU Socialでは、サーバー実装が自由なライセンスであるAGPLで公開されているので、誰でも必要なインフラさえあれば、マストドンでは「インスタンス」と呼んでいるサーバーを建てることができる。あるインスタンスの管理が気に食わないのであれば、別のインスタンスを使えばよい。気に入るインスタンスがないのであれば、自分で立ち上げればよい。これによりTwitterやFacebookのような一企業に独占され、一企業の一存で好きなように検閲される問題を解決できる。

すでに解説したように、大抵のユーザーは自前のインスタンスを立ち上げるのではなく、有名なインスタンスに集中する。大勢のユーザーの負荷に耐えられるインフラを運営するには、企業でしか支えられないほどの資金と労働者が必要だ。すると特定のインスタンスが独占的な地位を得て、ユーザーを囲い込み、外部との連結を無効化するという邪悪に走るだろう。そう考えていた。

たしかにその懸念はあるのだが、現実は違った。そのような鎖国を嫌う文化が生まれていれば、利用者の期限を損ねないように、そのような邪悪を行わないインセンティブが生まれる。

ああ、先見性というのは難しいものだ。すっかり見誤った。

結果として、マストドンは流行るだろう。もうTwitterに独占される必要はないのだ。

2017-04-16

マストドンが直面している問題はすでにP2P技術が15年前に遭遇した問題だ

Media content caching strategy · Issue #1847 · tootsuite/mastodon

日本勢がマストドンに目をつけ始め、Pixivがマストドンのインスタンスを立ち上げてからというもの、マストドンは2つの問題に直面している。

  1. 日本国内で合法である現実に基づかない純粋な思想の表現である絵が海外基準では児童ポルノであり違法なデータである
  2. 画像投稿を主目的とするPixivの利用形態により大量のトラフィックとストレージがキャッシュとして消費されるため貧弱なインフラでは耐えられない

これにより、Pixivによるマストドンのインスタンスは海外で主流のマストドンのインスタンスから遮断された。

現在、マストドンのコミュニティではこの問題に対する議論が行われているが、この問題には見覚えがある。15年前のP2P技術が流行した時代と同じ問題だ。我々は歴史に学ぶべきである。

今をさかのぼることおよそ15年前、P2P技術があらゆる問題を解決する夢の技術として期待されていた。当時、P2P通信により、インターネット上に分散メッシュネットワークを構築し、その分散メッシュネットワーク上に、ファイル共有、掲示板、チャット、ブログ、Webページ、その他あらゆるネットワーク通信を実装していた。純粋な分散メッシュネットワークでは、すべての参加者が、計算機、ストレージ、トラフィックなどの資源の大小を別にすれば、平等である。

その実装方法は様々で、例えば特定の機能に特化した実装、例えば、ファイル共有や掲示板のWinny、ファイル共有のBitTorrent、チャットのSkypeのような実装もあれば、Webページのようなより汎用的な機能を提供するfreenetのような実装、あるいは分散メッシュネットワークを構築した上でローカルsocksプロクシーサーバーとして動作して通過的にTCP/IPをアプリケーション層に提供するような実装もあったはずだ。

その具体的な実装方法については様々な方法が乱立して試されたが、どれも同じ問題を抱えていた。現在のマストドンが抱える問題と同じだ。

  1. 著作権侵害、児童ポルノ、その他の違法なデータ(ドイツにおけるナチ党のシンボルなど)がネットワーク上に蔓延する
  2. ネットワークに参加するノードがキャッシュとしてデータを溜め込むためにネットワークに参加するための計算機、ストレージ、帯域などの資源が莫大になり、個人が参加しづらくなり、結果としてゲートウェイ経由での参加が増える

その結果どうなったか。まず、ソースコードを公開せず、プロトコルの仕様も公開しないような閉鎖的な実装であるWinnyは滅びた。純粋な分散メッシュネットワークにこだわったfreenetのような実装は問題2.によってスケールせずに非効率性によって実質的に廃れた。

当時を生き延びて今も使われている実装もある。例えばSkypeとBitTorrentだ。

Skypeは当初P2Pな分散メッシュネットワーク(完全に平等ではなく、特にトラフィックに余裕のあるノードがスーパーノードとして局所的な管理サーバーの役割を果たし、NAT超えのために通信を仲介するリレーノードも存在した)によるチャットの実装であったが、今ではMicrosoftの管理するところとなり、その実装はサーバークライアント型の中央集権的で効率的な実装に切り替わった。もはや、今のSkypeはP2Pではなくなってしまった。とはいえ、表向きの末端のユーザーに対する利便性には違いがないので、よく使われている。

BitTorrentプロトコルは当初、純粋な分散メッシュネットワークではなかった、サーバーでファイルのメタデータやファイルを保有しているシードと呼ばれるノード、ファイルをダウンロード中のピアと呼ばれるノードを管理する。ファイルをダウンロードするには、すでに完全なファイルを保有しているシードの他に、現在部分的にファイルを保有しているピアからも分散してダウンロードを行う。後にファイルのメタデータに対するハッシュ値だけで、ファイルのメタデータとピア/シードの取得も分散メッシュネットワークを介して行う実装も追加されたが、依然として最初のハッシュ値を分散メッシュネットワーク単体で検索したりする機能は提供されないので、やはり何らかの中央管理的なサーバーは必要だ。

P2P技術を利用したファイル共有には著作権侵害などの負のイメージがつきまとうが、BitTorrentプロトコルは数あるファイル共有プロトコルの中でも、特にサーバー側で多大なトラフィックが必要ないという点から、今でも自由なOSのISOイメージの配布とか、ソフトウェアのアップデートを全コンピューターに行き渡らせるためなどの目的で活用されている。

当時のP2P技術を考え、現在の実用化された例を参考にすると、問題の解決方法が見えてくる。

問題1.を解決するには、結局有人の検閲を設置するしかない。問題2.は解決できない。純粋な分散メッシュネットワークによりすべての参加者が平等であることを目指すのであれば、すべての参加者が平等に全ネットワークのコストを負担するので、ネットワークの規模が拡大するほど参加者の負担が増えてしまう。

さて、話をマストドンに戻そう。マストドンはOStatusプロトコルの実装で、もともとは当初StatusNetと名乗り、今はGNU Socialと名乗っているソフトウェアの互換実装だ。その目的は、単一の企業からのSNS支配の解放だ。

その思想と設計はこうだ。TwitterやFacebookのような一企業がSNSの実装とインフラを独占しているから不平等な権利格差が発生するのだ。SNSの自由な実装を提供し、誰もがSNSのインスタンス(サーバー)を立ち上げることができればこの権利格差は解消する。インスタンス同士がデータを相互にやり取りできるように互換性のあるOStatusプロトコルで通信できるようにしておけば、どのインスタンスを選ぶかという問題は、どのインスタンスが便利で信頼に値するかという問題になる。既存のインスタンスのどれもガキに食わないのであれば、自分でインスタンスを立ち上げればよい。

考えようによっては、サーバー同士がゆるくわずかにP2P風に繋がっていると考えることもできる。もちろん、分散メッシュネットワークほどの強い結びつきではない。RSSをすこし強力にしたようなデータ共有用のOStatusプロトコルでお互いにデータを共有できるという程度の薄いつながりだ。

さて、問題1.に対処するには、有人の検閲を設置するしかない。有人の検閲を設置するには、結局企業としての資本や雇用が必要だ。企業による支配から脱却することを目指しているマストドンとしては皮肉なことに、企業が必要になる。自分のインスタンス内のデータの適法性については十分な資本と労力さえかければ検閲できるが、よそのインスタンスのデータはどうしようもない。すると、外から内へのリモートフォローは無効化せざるを得ない。

問題2.に対処するには、強力なインフラが必要だ。大規模なデータセンター、ストレージ、トラフィックを提供する必要がある。これにも、企業による資本が必要だ。ネットワークの規模が大きくなっていくと、これまた皮肉なことに個人ではその規模のインフラを提供できず、企業には勝てない。そして、規模が大きくなっていくと、すべてを無制限にスクレイピングできるAPIを外部に提供することがパフォーマンス上難しくなっていくだろう。そこで、内から外へのリモートフォローも無効化せざるを得ない。

こうして、マストドンのインスタンスをまともに運営できるのは十分な資本と、最低でも数百人規模の労働者を雇用している潤沢なインフラを提供できる企業だけになるだろう。個人がマストドンのインスタンスを立ててももはやマストドン全体のデータを格納できるだけのトラフィックとストレージを用意することすら難しくなる。現在のマストドンは、個人でもインスタンスが建てられるような小規模な実装になっている。ユーザーが増えていくと、企業はマストドンを大規模なインフラ上でスケールさせるために実装を改善していくだろう。そのような大規模にスケールする実装は、個人でインスタンスを立てるのが難しくなってしまうだろう。

そして、自らが管理するインスタンスだけで何十万、何百万ものユーザーを獲得した企業は、もはや外のインスタンスと連携する必要すらない。自らのユーザーだけで自己完結できるのだから、検閲上、パフォーマンス上の理由も合わせて、外部との連携を断つ。これは企業として適切な判断ではあるが、結果としてユーザーは分断される。

その結果実現される未来は、現在のTwitterの実装が公に公開される程度の未来だ。誰でもTwitterと同じサービスを提供するサーバーを立てることは技術的に可能だ。ソフトウェア実装はすべて公開されている。ただしインフラの規模は個人で実現できる範囲を大幅に超えている。

結局、マストドンは思想的にも設計的にも、当初の目的である単一の企業からのSNS支配の解放を達成することはできないだろう。仮にマストドンがTwitterを置き換えたとしても、マストドンのインスタンス運営のためには十分な資本、労働者、インフラ、政治ロビー活動ができる企業が必要になり、現在のTwitterと同じ問題が発生する。ユーザーはマストドンが極めて抑圧的であると不満を持ち、やがて、「既存のマストドンの代替する分散型のSNS実装を公開する。これは単一のマストドンコミュニティにより我々のコミュニケーションが独占されるリスクを防ぐ!」などという運動が持ち上がることだろう。歴史は繰り返す。

唯一の救いは、マストドンのライセンスはAGPLであるので、その実装が公に公開されるということだろう。

追記:Winnyの金子勇が自著でプロトコルを公開したのは、金子勇が刑事裁判に巻き込まれてからであり、もはやWinnyは廃れて、競合の同等機能を提供する他のP2Pファイル共有ソフトウェアの方に人は移行していた。

2017-04-15

そろそろマストドンについて語っておくか

世間ではマストドンが流行っている。結論から言うとマストドンは思想的にも設計的にも失敗しているのでお祭りのように一時の話題になった後、急速に忘れ去られる運命にある。

マストドンを語るには、まずマストドンが実装しているプロトコルであるOStatusについて説明する必要がある。これはもともと、StatusNetというソフトウェアが提唱したプロトコルで、Twitterようなマイクロブログの更新通知のためのプロトコルだ。StatusNetは今は名前を変えてGNU Socialとして自由ソフトウェア財団の傘下になっている。

マストドンはいうなればGNU Socialの互換実装だ。その基本的な思想や設計はGNU Socialと同じだ。どちらも現在の大手ソーシャルネットワークサービスに共通の問題に対処しようとしている。

問題とは何か。権力の一極集中である。TwitterにしろFacebookにしろGoogle+にしろ、そして現在ブログの文章を主にホストしているBloggerやGitHubも、筆者より強い権限を持っている。もしこの文章の内容が、彼らの気に食わないものである場合、彼らの一存のよりこのブログは削除、改変、監視といった検閲を受ける。これはTwitterやGoogleが技術的にサーバーを管理しているために生じる問題だ。

この問題に対処するにはどうすればいいのか。我々全員がサーバーを運営できるようになればいい。インターネットの当初の目的は、全員がサーバーを運営できるようになることだった。残念ながら、ハードウェア資源の制約、IPv4アドレスの枯渇、NAT、不思議な日本国内の法律(プロクシーサーバーを運営する出稼ぎ中国人を日本国政府が都合よく別件逮捕するのに使われている通信事業者法)により、我々は自由にサーバーを運営できるようにはなっていない。しかし、少なくともサーバーの実装であるソフトウェアを提供し、サーバーの設置をかんたんにしてはどうか。

GNU Socialやマストドンはこのような思想で設計された。Twitter社の方針が気に入らないのであれば、別のサーバーに移住すればよい。どのサーバーも気に入らないのであれば、自分でサーバーを立ち上げればよい。

思想としては悪くはないのだが、技術的にはあまりよろしくない。GNU Socialの前身StatusNetは2010年から開発が始まっているが、一向に主流とならない。主流となっていないソフトウェアには主流になれない問題があるのだから、その互換実装を作っても主流となるわけがない。では一体何が問題なのか。

サーバーの設置は自由なソフトウェア実装が存在するだけではだめで、十分な性能を持ったコンピューターと十分なネットワーク帯域が必要になる。GNU SocialはPHPで実装されているし、マストドンはRuby on Railsで実装されている。実行には普通にWebサーバーを運営するのと同じだけの煩わしさがある。

これだけサーバーの実行が面倒だと、結局、既存のサーバーを利用するものが大半だろう。その結果、どこかの学生が1個人が運営している怪しげなサーバーに人が集中する。これはとても問題だ。

信用の話をしよう。Twitter社と一個の人間、どちらが信用できるだろうか。これは圧倒的にTwitter社である。何故かというと、邪悪に至るまでの障害の多さによる。

一個の人間が運営するサーバーで邪悪を為すのは簡単だ。一個の人間が邪悪になるだけでよい。一方、Twitter社は法人格として登録をしており、税金の支払いのために収支を国家に報告する必要がある。Twitter社には現在3000人以上の被雇用者がいる。Twitter社が邪悪をなして、それが露見しないようにするのはとても難しい。Twitter社内の一個の人間がなした邪悪は、速やかに発覚する。Twitter社が社をあげて邪悪をなそうとした場合、3000人以上いる社員のうちの少なくとも数十人から数百人はその邪悪が為されていることを知るだろう。そのうち、一人でも正義感あふれる人間がいて公に邪悪を暴露した場合、邪悪が露見する。

したがって、一個の人間によって管理されたサーバーより、何百人何千人もの人間が関わる法人の方が邪悪に至るまでの障害が多いという点で、信用できるのだ。

事実、マストドンの初期の主流サーバーでは検閲が行われている。どのような検閲かと言うと、ドイツやフランスの法律の法律に違反しないように、ナチ党のシンボルであるハーケンクロイツ、ホロコーストの否定といった内容が検閲されていた。マストドンはむしろ検閲をやりやすくするプラットフォームであると言える。権力を一個の人間に委ねると、その人間の裁量で検閲が行われるわけだ。もちろん、これは効率のいいハラスメント対策にもなるという主張もあるだろうが、それはつまり独裁政権は一人の独裁者の判断だけで政治が進むので効率的というのと同じだ。たしかに効率的だが、失敗に至る道も効率的にたどることができる。かの毛沢東も国力を増そうと大躍進政策を行い、かのポル・ポトも子供によりよい教育を施そうと子供を家庭から取り上げて国家が管理する完璧な教育を施そうとした。かのルーズベルトとトルーマンは日本に降伏させて日本の民間人を守るために日本を無差別爆撃し核爆弾を二回投下し、日本の民間人の虐殺に貢献した。地獄への道は善意で舗装されているというわけだ。

一個の人間がサーバーを管理する場合に憂うべきことは単に恣意的な検閲や改変だけではない。大半の人間はパスワードを再利用するという問題だ。

xkcd: Password Reuse

なんか適当に便利な利用に登録が必要なWebサービス作ったらユーザーIDとパスの組み合わせが大量に手に入るじゃん。やったね。さあ邪悪を行おうぜ。でもなにする?

そして、日本のマストドンのサーバーで注目を集めてユーザーの急激な増加を得た管理者が、某クラウドベンダーからホスティングを促されたり、別の某クラウドメンバーでホスティングしようと動いているなどという話をみるにつけ、もはや悪いとこ取りの様相を呈している。一個の人間が管理する上に、インフラは自分で所有していない。

マストドンとGNU Socialは残念ながら設計的に間違っている。結局、やっていることはTwitter風サーバーのソフトウェア実装を提供したというだけで、解決しようとした問題は何一つとして解決していないばかりか、大半のコンピューターリテラシーの低い者にとっては悪い結果になるだろう。

では、本当に技術的に正しい設計とは何か。まずすべての参加者はサーバーでもありクライアントでもある、完全にP2Pメッシュネットワークを構築し、その上にマイクロブログサービスを実装すべきである。自分のデータは全てローカルに保持する。

問題は、これは15年前、P2P技術が夢の技術のように叫ばれていた時代に試みられたことだ。あの当時は様々なP2Pメッシュネットワーク上に構築されたチャット、掲示板、ブログ、Webページ、ファイル共有などの実装が乱立していた。その実装はどれもすべての参加者はコンピューターの性能やネットワーク帯域を別にすれば平等であり、全員がローカルで同じソフトウェアを実行する作りであった。

そのような状況ですら、当時も今と同じ問題を抱えていた。ローカルでそのようなソフトウェアを実装するのは大変にコストがかかるので、大半のものは他人が実行しているサーバーにアクセスして、そのサーバー経由で参加していた。残念ながら当時のP2Pメッシュネットワークによる全員が平等なネットワークの構築は失敗した。当時の実装の殆どは秘密で不自由なプロトコルやソフトウェア実装で非効率なため打ち捨てられ、残ったのは、BitTorrentプロトコルのような詳細が公開されていて当時のソフトウェア実装も自由で使いやすかったものだ。BitTorrentプロトコルは大容量データの配信に都合がいいもので、これは今も自由なOSのISOイメージの配布とか、ゲームやサーバーのアップデートパッチの全コンピューターへの効率的な配布といった健全でまともな用途にも使われている。その他の当時の有象無象のP2Pプロトコルは、筆者の知る限り絶滅した。

筆者が思うに、真に自由な通信手段のためには、物理層からのP2Pメッシュネットワークの構築が必須だ。例えばコンピューターが無線通信装置を搭載して近隣のコンピューターと通信したり、ストレージをスニーカーを履いた足で運んだりして、物理層からのP2Pメッシュネットワークを構築し、その上にNamecoinのようなP2Pかつ計算資源の多いものが正しいという名前解決の仕組みを導入し、公開鍵署名によって特定の秘密鍵にアクセスできるものによって発信されたデータだと証明できる通信でチャットや掲示板やWebページやメールの仕組みを実装し、すべてのネットワーク参加者は平等である仕組みがほしいが、これとて最終的には計算資源とネットワーク帯域と電力の強いものが正しい弱肉強食の世界になることが予想されるので、世の中は難しい。

とりあえずの対策として、筆者はこのブログの内容をgitで管理している。そのgitレポジトリはGitHubでもホストしていて、GitHub Pagesでも閲覧できる。こうすることによって、BloggerとGitHubが同時に検閲された場合でもローカルに全て残っているので、私はデータを失わない。外部のホスティングサービスがすべて検閲され、かつ、私の所有するストレージが全て強奪、破壊されたときのために、今、誰でも簡単に"git clone git@github.com:EzoeRyou/blog.git"というコマンド一発で複製できるようにしておくのも重要だ。gitレポジトリの複製が存在する限り、私は最新のコミットの40文字のハッシュ値を覚えておけば改変されていないことが保証できる。

2017-04-06

もしスマートフォンが自由だったら今頃実現していた社会

CanonicalがUbuntuをスマートフォンに対応させることを諦めた。これで、スマートフォンにまともなOSを移植するという大きな資本が入っているプロジェクトは、ほとんど全部潰れたことになる。これは当然の話だ。現在のスマートフォンのハードウェアは極めて不自由なので、まともなOSを移植することは不可能なのだ。このため、筆者はスマートフォンの所有を拒否している。

スマートフォンの害悪について詳しくは以下を参照。

本の虫: インターネット端末のシェアでスマートフォンがPCを上回ったというディストピア

しかしもし、スマートフォンが自由だったら、今頃どうなっていただろうか。以下はスマートフォンのハードウェアが完全に自由なコンピューターの将来実現したであろう未来である。

江添亮は13時に目が覚めた。今日は比較的早起きをした方である。江添は眠たい目をこすりながら枕元のスマートフォンを操作する。そう、なんと江添亮はスマートフォンを所有しているのだ。

このスマートフォンは、ファームウェアを含めてあらゆるソフトウェアが自由なコンピューターである。江添亮は自由なファームウェアを使い、その上に自由なブートローダーを使い、自由なカーネルを起動し、完璧に自由なユーザースペースソフトウェアを実行している。もちろんベースバンドプロセッサーの仕様とファームウェアとOSも自由だ。当然だ。不自由で不便で修正されない既知の脆弱性、アメリカ政府が保有している未公開の便利な脆弱性とバックドアが満載のAndroidやiPhoneなどは、とっくの昔に自由競争に破れて滅んでしまったのだから。

今日は休日だが外出する用事があるので、江添は家を出る。歩きながら、公衆無線ネットワークに参加する。今や、無線周波数帯のほとんどは、国民の自由な通信のために開放されている。なぜならば、表現の自由を脅かされない分散型の強い障害耐性を持つ通信ネットワークは、今や電気や水道と並んで重要なインフラであり、基本的人権の一部だからだ。テレビやラジオのような一方的に情報を垂れ流すだけの情報格差の発生する用途に周波数帯が専有、浪費されることはもうない。十分に広い道路を確保すると物流を改善し経済を回す。ネットワークと道路は同じだ。すべての周波数帯は国民の通信ネットワークに再優先で割り当てるべきなのだ。不必要に強い電波を発射する悪意ある電波発信者さえ取り締まればよい。

かつて、日本がまだ不自由だった時代、スマートフォンの通信は中央集権的な仕組みで行われていたと聞く。個々のスマートフォンの発信する電波は微弱で、今のように近隣のスマートフォンと通信して分散型ネットワークを構築するのではなく、強力な基地局を中心とするツリー型のネットワークを構築していたそうだ。これは基地局の管理者に、ネットワークの監視、検閲といった不平等な強権を発生させる極めて危険なネットワークである。

移動中の江添は、もっぱら情報の消費のみをする。これは手のひらサイズのタッチスクリーンで操作するコンピューターだ。このような制限された非効率的な入力装置では、まともなコードや文章を書くことは不可能だ。

さて、江添は目的地についた。しかし待ち合わせの時間にはまだ早い。珍しいことだ。いつもの江添は待ち合わせの時間になった頃に家を出るというのに。どこかで時間を潰す必要がある。そこで江添は、近くにあったターミナルカフェに入る。

「粉末ティーライクひとつとダイミョクラスの入力装置」
「ハイ、ヨロコンデー!」

ターミナルカフェとはドリンクを頼めばコンピューターを快適に操作するための端末と個室も一緒にレンタルできる実際安い作業場だ。江添は端末としてスマートフォンを持っているので、入力装置だけをレンタルすることにした。大画面高解像度のディスプレイ、Cherry MSの青軸を採用したキーボード、そして高精度なマウスをレンタルした。所有しているスマートフォンとは極めて信頼性の高い低遅延広帯域の無線接続が行われる。

作業をしていたが処理能力が足りない。やはり128コアしかない上にメモリが1TBしかない貧弱なスマートフォンでは、基本的人権が保証されない。江添は自宅に設置してあるコンピューターにssh接続をした。これでいい。これでこそ人権があるというものだ。この時代における人権とは、計算力がモノをいう。計算力の強いものは正しい。

計算力、懐かしい言葉だ。そうだ、もう計算力の時代ではなかった。トゥーメニーコアが主流となった今では、もはや計算力は問題ではなくなった。実際、江添が自宅に設置しているコンピューターのコア数は3メガ個ほどある。いや、4メガ個だっただろうか。コア数が1メガを超えた辺りから、もうそのへんはどうでも良くなってしまった。昔、まだ江添が若かった頃、ひとつのコアの計算時間を複数の処理でシェアしていたものだ。今は違う。CPUコアは実質無料である。本当の計算コストは、電力だ。たしかに、江添が自宅に設置しているコンピューターをフル稼働させれば、理論上は、大昔のRSA-4096程度は一時間もあれば任意の秘密鍵に対する公開鍵が計算可能である。ただし、その計算にかかる電力で江添の家計はカーオンファイヤー(ブッダになれなかった死者を乗せる地獄行きの車、転じて家計が苦しい時に使う)になってしまう。

そうこうしているうちに、待ち合わ汗の時間になった。それにしても、今はいい時代になったものだ。後は物理肉体を物理場所まで運ぶという技術的制約を解決できればいいのだが。

Wandboxのスポンサーになるべく、めるぽんに肉をおごってきた

WandboxというWebサイトがある。これはコードを与えるとコンパイルメッセージと実行結果を返してくれるサービスを提供している。コードとコンパイルメッセージと実行結果を保存してURLで共有する機能もある。

ここまではよくあるサービスだが、Wandboxが他のサービスと差別化を図っているのは、コンパイラーの種類だ。様々な言語のコンパイラーをサポートしているのみならず、同じコンパイラーでも複数のバージョンを提供している。これにより、あるコードの挙動がコンパイラーのバージョンで異なる場合の特定ができる。

なぜそんなサービスが必要なのか。コードぐらい自分のローカル環境で実行すればいいではないか。リモート環境にしたって、今日びVPSなど月数百円から使うことができる。ブラウザーから入力する程度の短いコードをコンパイルして実行するぐらい低スペックの格安VPSでも足りるではないか。

問題は、バージョンの異なるコンパイラーの混在と切り替えはだるいということだ。

例えばGCCを3-stage bootstrapでビルドするには1,2時間はかかる。しかも、数GBものストレージを消費する。ということは、GCCの過去のバージョンを10種類用意しようと思ったら、数十時間と数十GBが必要になるということだ。

C++コンパイラーはGCCだけではない。Clangもある。Clangの過去のバージョンを10種類用意しようと思ったら、また別に数十時間の数十GBが必要になる。

プログラミング言語はC++だけではない。Javaは? PHPは? Pythonは? Rubyは? これらの言語にはそれぞれ複数の実装があり、実装ごとに複数のバージョンがある。全部ビルドするには何百時間、何百GBも必要になる。

ほんの数行のコード辺のバージョン間の挙動を、たまに確かめたい時に、ローカルにそんな環境を用意するのはやりたくない。Wandboxの価値はここにある。

さて、そんな便利なWandboxだが、最近スポンサーを募集している。ドワンゴもスポンサーになっている。

Wandboxにはとてもお世話になっているので、ぜひともスポンサーになりたいところだ。しかし、私はクレジットカードという匿名性のない上に不必要な第三者に記録される送金手段を使いたいとは思わない。思えば、Wandboxのめるぽんとは久しく会っていない。めるぽんは無頼の肉好きであるので、めるぽんに直接、肉をおごることでスポンサーになることにした。

さて、めるぽんはグルメでいらっしゃるので、粗悪な肉でもてなすことは大変失礼に当たる。銀座にあるような高級ステーキ店ならば、めるぽんの舌も満足することであろう。しかし、店を探すのは難航した。というのも、店がまともな食事を提供するには、終日全面禁煙であることがまず必要となるからだ。ニコチン中毒の客にまともな味がわかるはずがないから、そのような店は味で客を得る努力をしていないはずで、味による市場の淘汰を経ていない。

さて、結論から言うと、筆者による店探しは完全に失敗した。これは私が携帯電話を持っていないために店の予約ができなかったためである。しかたなくめるぽんの行きつけの店に行くことにした。はじめからこうすればよかったのだ。めるぽんは肉が主食であり、普段から肉を食べ慣れているので、どこにでも行きつけのステーキ店の一つや二つはあるはずだ。

目的の店に向かう道すがら、我々はコンパイラーのブートストラップ問題の話をした。

ブートストラップ問題とは、あるプログラミング言語のコンパイラーが同じプログラミング言語で書かれている場合に起こる問題である。あるプログラミング言語で書かれたソフトウェアをコンパイルするにはコンパイラーがいる。コンパイラーもプログラミング言語で書かれたソフトウェアである。コンパイラーをコンパイルするにはどうすればいいのか。

答えとしては、まずコンパイラーを別の言語で実装するかハンドアセンブルするなどして作成する。そのコンパイラーを使ってコンパイラーをコンパイルする。後は、コンパイラーが前のバージョンのコンパイラーでも正しくコンパイルできることを保証すればよい。

GCCは歴史が長く、かつ多くの環境で標準のCコンパイラーでもあることから、ブートストラップへの対応は極めて優秀だ。かなり昔のバージョンのGCCでも最新のGCCがコンパイルできる。GCCの標準的なコンパイルは、3ステージブートストラップと呼ばれている。まず、システムのC++コンパイラーを使ってGCCをコンパイルするための最小限のC++コンパイラーと周辺ツールをコンパイルする。出来上がったC++コンパイラーで1ステージGCCをコンパイルする。1ステージGCCで2ステージGCCをコンパイルする。2ステージGCCで3ステージGCCをコンパイルする。2ステージと3ステージのGCCをテストして挙動に差がないことを確認する。テストが通れば、3ステージGCCは最低限のテストは通過したコンパイラーということになる。

他の言語はどうか。まず、ブートストラップ問題のない言語がある。あるプログラミング言語のコンパイラーが同じ言語で書かれていない場合、例えばCやC++などで書かれている場合、これは簡単だ。なぜならばGCCは極めて安定したコンパイラーであるので、ある程度最近の安定バージョンのGCCでコンパイルすればよい。

ブートストラップ問題を抱えている歴史の浅いプログラミング言語は問題だ。歴史の浅い、まだ発展段階のプログラミング言語の実装はとても急速に変わる。そのため、古いバージョンのコンパイラーは最新のコンパイラーでコンパイルできないという自体に陥る。そのためソースコードからのビルドが難しく、Wandboxではあまりにも古いバージョンのコンパイラーを提供できない。

このような話をしていると、我々は目的のステーキ店についた。空いていてタバコの害もなく高級な肉を出す店だった。

肉を食べながら、我々の話は、いかにしてめるぽんはプログラミングを学んだかという話題に移った。

人がプログラミングを学ぶ方法は様々だ。プログラミングの教育法はまだ学問として完全に固まっておらず、したがって多くのプログラマーは独学で学んでいる。筆者は幼い時にコンピューターがない環境で育ったので、参考書を読んで言語の文法と意味を脳内で理解するという作業のみしていた。さて、後にコンピューターを手に入れて、コードを書き、そのコードが想定通りに動いた時、筆者は目標を失った。なるほど、私の理解は正しかった。私はC言語の文法とその意味を理解している。ソフトウェアを書くことができる。しかし、今の自分の技術力で完成することがわかりきっているコードなど書いて楽しいのだろうか。そこに学びは何もないし、やりがいもない。自分ができるかどうかもまだわからないことに挑戦してこそ、やりがいというものは生じるものだ。そこで私はC++の規格書を読み始めた。そして今に至る。

めるぽんの経歴を知らない読者には、めるぽんがどうやってプログラミングを学んだかということに対して興味を抱かないだろう。この業界は実力主義で、ほとんどのプログラマーは独学でプログラミングを学んでいる。この業界では中卒と博士が机を並べて仕事をすることだって珍しくない。めるぽんがコンピューターサイエンスの学位や博士号を持っていないのにプログラミングができるというのは不思議でも何でもない。そう思うことだろう。我々は義務教育を不登校気味だった中卒がバリバリコードを書き、コンピューターサイエンスの学位を得た者がFizzBuzzすら書けないという話はいくらでも聞いてきた。しかし、めるぽんのような例は聞いただろうか。

めるぽんは高校時代、アマチュア・レスリングで優秀な成績を収めた。高校卒業と同時に自衛隊に入った。自衛隊では体育学校にいた。自衛隊は数年でやめた。自衛隊をやめた数年後には、すでにフリーランスのプログラマーとなっていた。

いったいめるぽんはどうやってプログラミングを学んだというのか。

めるぽんは高校時代、アマチュア・レスリングで優秀な成績を収めた。つまり、めるぽんは高校生まで相当な量の運動をしていたはずで、ガチガチの体育会系の人間だったはずだ。もちろん文武両道な人間はいくらでもいる。しかし、問題はその後だ。

めるぽんは高校卒業と同時に自衛隊に入った。自衛隊では体育学校にいた。自衛隊の体育学校というところは、運動中毒の人間だけが生きていける特殊な世界だ。世の中には運動中毒の人間がいる。「自衛隊に入ったら毎日、一日中、好きなだけ走ることができて、しかも給料が出る。最高だ」などと発言する人間のいる世界である。そして、この発言をした自衛隊員は何百kmも走るウルトラマラソン大会の走者で、実際に、文字通り一日中走っている。

運動こそ人生。仕事は一日中体を鍛える訓練。そんな環境でプログラミングの勉強ができるだろうか。

めるぽんは中学生の一時期、怪我をして柔道の練習ができなくなったことがあるそうだ。そんなめるぽんに、中学校の教師は、ではコンピューターをやれ、といってPC88だか98とプログラミング雑誌を渡したそうだ。当時はN88BASICの世界で、コンピューターを使うということはBASICでプログラミングをするということであった。当時のコンピューターは単純だった。電源を入れるとBASICインタプリターのプロンプトが表示される。BASICで書く。実行される。それだけだ。当時のめるぽんは、意味もわからないままに雑誌に記載されたBASICコードを入力し、当然入力間違いによりシンタックスエラーを起こし、その「シンタックスエラー」というものが何を意味するのかもわからないままにコンピューターを使おうとしていたそうだ。そして、わからないことがあると中学校の教師に質問に行った。

めるぽん「その教師、図画工作の教師で、他にも当時CADを使った授業とかがあって」
筆者「その教師、当時としてはおかしくないか?」
めるぽん「そういえばおかしい気がしてきた。なんであんな教師がいたんだろう」

さて、高校生になっためるぽんは、家の中で偶然にもBASICの教科書を発見する。なぜそんなものが家にあったのかはわからない。これによってめるぽんは、これまで意味もわからずに写経していたBASICのコードの意味を理解することとなる。

高校を卒業後、自衛隊に入り、その体育会系の空気とあまりの運動中毒に、自分には合わない場所だと判断してやめて、ゲーム会社に一年半ほど雇われた後、フリーランスになった。

肉がやってきた。めるぽんは肉が主食であるが、サラダも注文しておいたので、多大な説得の末、多少の野菜を食べさせることにも成功した。なぜめるぽんは肉を食べるのか。

めるぽん「肉と野菜のどちらを食べるかという選択が与えられた場合、これは当然肉を選ぶに決まっている」
筆者「なるほど、そして肉を食べた後は、野菜を食べるわけだな」
めるぽん「いや、肉を食べる」
筆者「寿司ではトロに満足した後は光物がほしくなるように、肉に満足したら野菜を食べたくなるものでは」
めるぽん「肉を選ぶという選択肢は依然として残っている。選択肢にある以上、肉を選ぶのは当然だ」

肉を食べ終えた後、我々の話題はバージョン番号に移った。

バージョン番号はソフトウェアの開発者が勝手気ままにつけるものである。今ではSemantic Versioningなどと叫ばれているが、本当にバージョン番号には何らの規則性もなく、したがってソートできない。Wandboxでは、バージョンの新しい順にコンパイラーを表示しているが、これは手動で順番をハードコードしているのだという。

自動でソートをしたかったが、数値や文字列による比較を拒否するバージョン文字列が多すぎて、例外ルールだらけになるので、結局手でやるのと手間が変わらない。

バージョン番号の付け方にも謎のルールがある。例えば、PyPyはマイナー番号の偶数と奇数で、Python 3.0対応版とPython 2.7対応版を分けているらしい。他にも、リリース版にもかかわらずバージョン文字列にrcと書いてあるものもある。

肉を食べ終えた我々は店を後にした。久しぶりに本物の肉を食べた実感がある。。

ドワンゴ広告

ドワンゴはWandboxのスポンサーになった。Wandboxはドワンゴの社員がコンパイラーのバグと思われるものを見つけた場合に、バージョンごとの挙動の違いを調べるのに役立っている。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

UbuntuがUnityを捨てる予定

Growing Ubuntu for Cloud and IoT, rather than Phone and convergence | Ubuntu Insights

朝からなかなか衝撃的なニュースが飛び込んできた。結論から言うとこうだ。

Ubuntu 18.04ではデフォルトのデスクトップをGnomeにする。Unity8の開発は中止する。スマフォ対応は中止する。おそらくMirの開発もやめる。

CanonicalのMark Shuttleworthは、Ubuntuをスマフォ対応させて、どこでも同じ環境が実現できるという目標をやめて、UbuntuをクラウドやIoTに向けて発展させると発表した。

これはなかなか衝撃的だ。たしかに、Unity8とMirはこの長年開発しているが、さっぱり日の目を見ないソフトウェアだった。4年も開発していまだに実用化に至っていないデスクトップサーバー、コンポジター、デスクトップ環境は見切りをつけるのは当然だ。また、スマフォは根本的に不自由なコンピューターである。不自由なコンピューターに対応するためにリソースを割くのは無駄だ。

convergenceとやらも無意味だ。もしスマフォが本当にまともなデスクトップコンピューターと同じ使い心地であれば、iPhoneやAndroidのような不自由OSとてデスクトップコンピューターと同じUIを採用していたはずだ。それが採用していないのだから、スマフォは根本的に使いづらいコンピューターで、だからこそおもちゃのようなUIを採用しているのだ。

Canonicalがサーバー用に家事を取るのは当然だし、ぜひ鈍重なRHELを駆逐してもらいたい。すべてのコンピューターは最新の安定版のGCCを使えるべきであり、RHELは業界の癌だ。

さて、個人的な影響で言うと、Unityがなくなることだ。私はあまりデスクトップ環境にこだわらないので正直何でもよいが、Unityのデフォルトのキーボード・ショートカットは気に入っていただけに残念だ。

2017-04-04

インターネット端末のシェアでスマートフォンがPCを上回ったというディストピア

Report: Android overtakes Windows as the internet’s most used operating system | TechCrunch

最近の調査で、インターネット上の閲覧に使うOSのシェアにおいて、2017年3月現在、AndroidのシェアがWindowsのシェアを抜き去ったそうだ。

これはつまり、いまインターネットに接続している個人が使うコンピューターは、デスクトップやラップトップではなく、圧倒的にスマートフォン(AndroidかiPhone)であるということだ。

何というディストピアな世界だろうか。

私が子供の頃、世の中の大人の大半がコンピューターを使いこなせず、我々の社会の日常生活が極めて非効率的であることに不満を持っていた。

しかし、当時の私は物事を楽観的に考えていた。何故といって、我々の世代は個人でも安価にコンピューターが所有できる世代である。コンピューターの性能は年々上がり、価格は年々下がっている。すると、我々の世代が大人になる頃には、全員がコンピューターを使いこなせるようになるはずだ。将来、コンピューターを使えないのはしぶとく生き残っている死に損ないのジジババだけになる。すると、我々の社会はコンピューター利用が当然で、誰もがコードを書ける社会になるはずだ。

残念ながら、そのような未来は来なかった。

「スマートフォン」と呼ばれるものの誕生が、我々をバカにしてしまった。スマートフォンではコードが書けないのみならず、まともな文章も書きにくい。スマートフォンの利用者の大半はただ与えられた情報を消費するだけの愚かな存在になりさがってしまった。情報を与える特権を持った者は、キーボードという効率的な入力装置を使いこなせる者だ。

我々の世代と、我々の次の世代は、スマートフォンという名の毒物によって汚染されてしまった。この手のひらサイズのタッチパネルを搭載した貧弱なコンピューターは、今や大半の人間が使う唯一のコンピューターになってしまっている。

筆者はスマートフォンの所有を拒絶している。我々の社会はとてもスマートフォンの利用が当然な社会になってしまったので、スマートフォンを所有しないということは、日常生活において大変な不便を強いられる。しかし、筆者は利用者によるOSの入れ替えやOSの改変を妨害し、コードや文章を書くのが非効率的なコンピューターを所有するのは利便性を上回るリスクであると考えている。

何というディストピアな世界だろうか。

2017-03-27

C++標準化委員会の文書: N4643-N4661

また新たなC++標準化委員会の文書が公開された。

[PDF] N4643:National Body Comments for PDTS 19216, C++ Extensions for Networking

ネットワークライブラリに対するNBコメント

[PDF] N4644: National Body Comments for PDTS 21425, C++ Extensions for Ranges

レンジに対するNBコメントコメント

[PDF] N4645: WG21 Telecon Minutes

電話会議の議事録。

[PDF] N4647: Working Draft, Extensions to C++ for Modules

#includeに変わる機能、モジュールのドラフト

[PDF] N4648: Editor's Report for the Module TS

モジュールのドラフトの変更点。さほど変更はない。

[PDF] N4649:Working Draft, Technical Specification on C++ Extensions for Coroutines

軽量な実行媒体、コルーチンのドラフト。

[PDF] N4650: Editor's report for the Coroutines TS

コルーチンの変更点。目新しい変更はない。

[PDF} N4651:Working Draft, C++ Extensions for Ranges

レンジのドラフト。

N4652: Editor’s Report for the Ranges TS

レンジのドラフトの変更点。だいぶ変更があるようだ。

[PDF] N4653: 2017-02 Kona Record of Discussion ISO/IEC

内容はN4654とほぼ同じだがなぜか標準化委員しかみられないようにBASIC認証がかかっている。

[PDF] N4654:WG21 2017-02 Kona Minutes

Kona会議の議事録。

[PDF] N4656: Working Draft, C++ Extensions for Networking

ネットワークライブラリのドラフト。

[PDF] N4657:Networking TS - Editor's Report

ネットワークライブラリの変更点。それほど大きな変更はない。

[PDF] N4658:Alternative accommodation (student residence) for the 2017-07 Toronto WG21 Meeting

2017年7月のトロント会議のために近くのホテルに割引を交渉した。

Pros: 安くて近い。

Cons: クーラーがない。7月のトロントは暑くなります。

[PDF] N4659:Working Draft, Standard for Programming Language C++

ドラフトC++規格

[PDF] N4660:C++17 DIS Ballot Document

C++ DIS(Draft International Standard)。もうこれ以上の変更はほとんどないはず。これが実質C++17となる。

N4661 Editors' Report -- Programming Languages -- C++

C++ドラフトの変更点。std::byteが入った。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-03-23

4Kディスプレイを買った

出社中にふと思い立って秋葉原に立ち寄って27インチの4Kディスプレイを買った。今や、4Kディスプレイは5万円で買える時代だ。通勤途中にふらっと衝動買いできる程度の値段でしかない。

そして設置して今に至るが、もっと早く、10万円を切った頃に、いや買えるようになった時点で即座に4Kディスプレイを買っておけばよかったと後悔している。4Kディスプレイによってもたらされる圧倒的に快適な作業は素晴らしい。結局、我々健常者はコンピューターからの出力を目で得ているので、眼球にできるだけ多くのピクセルをぶち込むのが最も効率的な出力なのだ。

筆者の今使っているラップトップに内蔵のディスプレイは4Kなのだが、物理的な画面サイズが12.6インチしかなく、あまり4Kの恩恵を実感できていなかった。たしかに高いPPCMによりフォント描画は素晴らしい。フォントサイズを小さくしても、ピクセル数が多いので読むことは可能だ。しかし、物理的なサイズには限界がある。

そこで、今回は27インチとやや大きめのディスプレイを買うことにした。本当は33インチぐらいのディスプレイが欲しかったのだが、そのサイズのディスプレイは10万から15万ぐらいするのでやめておいた。

それにしても、10年前はひたすら高PPCMのディスプレイを待ち望み、サイズが小さくてもいいから高PPCMのディスプレイがほしいと思っていたのだが、まさかPPCMはもう十分だからサイズの大きなディスプレイがほしいと思う時代が来るとは思わなかった。

とにかく、27インチの4Kディスプレイを得たことでC++の規格書の閲覧がはるかに楽になった。C++の参考書執筆のためには必要な自己投資だ。

Ubuntuがブート時にmanual fsckが必要だとしてinitramfsで止まった時

Ubuntuが塊操作不可能になったのでREISUBでリブートしようとしたら、以下のようなメッセージを表示して止まった。

/dev/mapper/ubuntu--vg-root contains a file system with errors, check forced.
Inodes that were part of a corrupted orphan linked list found.

/dev/mapper/ubuntu-vg-root: UNEXPECTED INCONSISTENCY; Run fsck MANUALLY.
    (i.e., without -a or -p options)

fsck exited with status code 4.
The root file system on /dev/mapper/ubuntu--vg-root requires manual fsck

これはエラーメッセージの通りファイルシステムに不整合な問題が発生している。おそらく原因は先程正しくunmountできなかったためで、ストレージの故障ではないだろう。おそらくBを早く押しすぎたのだ。

この問題を解決するには、そのまま、fsck /dev/mapper/ubuntu--vg-root とコマンドを入力すればよい。そしてaと入力すると、運が良ければファイルシステムの不整合が修正される。

2017-03-20

パラノイアで遊んだ

最近、有名なTRPGのパラノイアを遊んでいる。すでに3回遊んだ。次はGMをやろうとルールブックを読んでいるところだ。この休みの月曜日を使ってだいぶ読み込んだので、パラノイアのGMがやれそうな気がする。パラノイアの世界観はだいぶ頭に叩きこんだが、TRPGのGMの経験はないので、まずは練習が必要だ。

私がパラノイアを遊んだ時のGMは、残念ながらパラノイアのルールブックを熟読してはいなかった。彼らの他の楽しくないTRPGでは十分なGM経験を積んではいるが、真に楽しいTRPGであるパラノイアのGMとしては未熟だった。ルールブックを確認するといかに彼らのプレイスタイルが極端なZapスタイルであったかわかる。

私が遊んだパラノイアでは、自分のセキュリティクリアランスより上の色を触ると即座に監視カメラが捉え、天井に設置されたレーザーにZAPされるルールになっていた。これは1,2時間の短いセッションならば面白いのかもしれないが、ゲームの大半は色の確認と色の迂回に用いられた。

さて、現在、私の手元にはパラノイアの25周年記念のトラブルシューターとインターナルセキュリティとレッドブックの日本語訳がある。アマゾンでインターナルセキュリティとハイプログラマーの原書を注文した。トラブルシューターの原書は、現在アマゾンでとても高いのでやめておいた。

古くてもいいのでサプリメントのルールブックやミッション集も欲しいところだが、なかなか入手が難しい。

2017-03-09

新しいラップトップRazer Blade Stealthの2016年版を中古で買った

タイトル通り、会社の同僚が買ったまま持て余していたRazer Balde Stealthの2016年盤を中古で買った。大まかなスペックは以下の通り。

  • 12.5インチ
  • 4Kディスプレイ
  • Skylake Core i7
  • DDR4 8GB
  • SSD 256GB
  • HDMIx1, USBx2

さっそくWindowsを無慈悲に消してUbuntuを入れる。特に問題なく入った。

Ubuntuの動作には問題がないので、後はこのラップトップのハードウェア的な評価になる。

まず4Kディスプレイなのは今更言うまでもない。もはや4Kディスプレイ未満の解像度のディスプレイの使用は基本的人権の侵害であり幸福で文化的な最低限度の生活を満たさない。

ディスプレイのサイズが12.5インチというのは一長一短がある。PCを持ち運んで様々な場所で作業したい場合、この大きさは悪くない。しかし、一カ所にとどまって長時間作業する場合、このサイズはやはり小さい。これでも4Kディスプレイなので、むしろppcmは大きい。したがってフォント描画もとても綺麗だ。それにしても人間の目には限界がある。物理的にディスプレイが小さいとつらい。

メモリ量は、VMを立ちあげず、主にターミナルエミュレーター上でvimを使ってテキストを編集するのであれば問題のない量だ。

外部ポートが乏しいのもつらい。Ethernetポートがないのはつらい。できれば外部画面出力は2つほしいし、USBポートも4つぐらいはほしいところだ。EthernetやUSBはUSBハブを使えばいいのだが、USBハブを持ち運ぶのは面倒だ。

充電はUSB Type-Cで行う。これによりACアダプターの紛失や破損の際に代替品をすぐに用意できるという利便性があるが、USB Type-Cの規格に準拠した充電器やケーブルの入手は一苦労すると聞いている。世の中には規格違反の粗悪で危険なケーブルが出回っている。

また、このラップトップの元持ち主によれば、Windowsで使っていたところ頻繁に熱によりCPUがダウンクロックされてスペック通りのパフォーマンスがでないのと、12インチという小ささと、8GBというメモリの少なさと、GPUを積んでいないことによりグラフィックパフォーマンスの悪さにより、使いみちがなく持て余していたそうだ。

多少の不満はあるものの、現在使っているIvy Bridgeのとても重たいゲーミングラップトップを置き換えるには十分だ。流石にこの2017年にIvy Bridgeを使うのは無理があり、あまりにも遅いため日々の作業にも支障が出ていたので、12インチという難点はあるが、この際メイン環境として置き換えることにした。

これで現在、筆者が日常的に使うラップトップは3台。Razer Blade Stealthと、Toshibaのdynabook T95/NGと、DellのLatitude E7470だ。

Toshibaのdynabook T95/NGは、中古で9万なので購入した。4Kディスプレイが付いていて比較的最近の製品なのにこの値段なのは、ディスプレイに縦一直線に常時白点灯ピクセルがあるからだ。とりあえず白背景にして黒文字でテキストを編集するとあまり気にならないので自宅で使っている。不思議なのは、東芝のWebサイトのスペック表を見ると、GPUにAMD Radeon R9 M265Xを使っているらしいのだが、Ubuntuからは認識されず、GPUはHaswell Mobileと表示される。HD GraphicやIrisなどではない不思議な表記だ。ただしlspciをしてみると、

01:00.0 Display controller: Advanced Micro Devices, Inc. [AMD/ATI] Venus PRO [Radeon HD 8850M / R9 M265X] (rev ff)

と表示される。factorioでしばらく遊んでいるとカーネルがエラーメッセージを吐いて停止する。ブラウザーでWebGLを動作するぐらいでは問題が無いようだ。

DellのLatitude E7470は私の所有物ではなく、会社の支給PCだ。私はこれにUbuntuを入れて使っているが、どうも具合が悪い。マウスやキーボードやタッチパッドといった入力を度々取りこぼす問題がある。内蔵のキーボードとタッチパッドが悪いのかと思い、他の環境で正常に動作するマウスやキーボードを繋いでみても、やはり入力を取りこぼす。ハードウェアかLinuxカーネルかXに問題があるように思われる。Unityは使えたものではなくGnomeだとだいぶマシになるが、やはりたまに入力を取りこぼす。Ubuntu 17.04のDaily buildをいれてLinux kernel 4.9を試してみたが、多少改善された程度でやはり入力を取りこぼす。4.10はまだ試していない。

私の理想のラップトップは、15インチ、4Kディスプレイ内蔵、USキーボード、メモリ16GB以上、内蔵Ethernetポート、ディスプレイ出力が2ポート、USBポート、ストレージが交換可能なこと、nVidiaのGPUを積んでいないこと、高パフォーマンス高消費電力なGPUを積んでいないこと、なのだが、なかなか条件にあったラップトップが見つからない。

5万円もするヘッドフォンATH-DN1000USBを買った話

オーディオテクニカのATH-DN100USBというヘッドフォンを買った。5万円した。

きっかけは、使っていた安物のヘッドフォンが壊れたことだった。そのヘッドフォンは値段を正確に覚えていないが、せいぜい5,6千円で買ってきた安物だったはずだ。故障は断線だ。断線が判明してから数週間ほど、だましだまし使っていたが、やはりたえられなくなったので新しい物を買うことにした。

筆者は長く金のない生活を送っていたせいか、あまり金を使わない生活をしている。たまには贅沢をしてもいいだろうと、ある程度の金を使うつもりでいた。思うに、ヘッドフォンは数年は使うものであるから、1万か2万の金をつぎ込んでもいいだろう。また、今のPCのマザーボードに内蔵のオーディオデバイスはあまりよろしくないので、新しいオーディオデバイスを買ってもいいかもしれない。オーディオデバイスにはPCIe接続のサウンドカードと、USB接続のオーディオデバイスがある。筆者はUSB接続の方が優れていると考えている。というのも、タダでさえノイズの多いPCのケース内にオーディオデバイスを設置するのは馬鹿げているからだ。

筆者は音楽をほとんど聞かない。聞くのはゲーム内の音と音楽だ。すると、USBオーディオとヘッドフォンが一体化したものでもいいのではないか。調べてみると、Bluetooth接続のヘッドフォンはたくさんあるが、USB接続のヘッドフォンはほとんどなかった。オーディオテクニカのATH-D900USBとATH-DN1000USBぐらいなものだ。ATH-D900USBは普通にUSBオーディオデバイスとヘッドフォンが一体化したものだ。これは安い。ATH-DN1000USBは変わっている。USBオーディオデバイスとして振る舞うヘッドフォンであることは変わらないのだが、その仕組みが変わっているのだ。

通常、音を鳴らすには、まずPCMデータを電流に変換してその電流で振動板を動かす。ATH-DN1000USBは、PCMから直接振動板を動かす。振動板は4つあり、PCMからどの振動板を組み合わせて動かすかを決定して動かすそうだ。

さて、実際に店頭に行っていろいろとヘッドフォンを聞いてみると、ATH-DN1000USBの音が気に入ってしまった。音が正確に聞こえる気がする。しかし値段は5万円。買うしかない。

帰宅後、まずはGNU/Linux機に接続してみる。何も問題なく使えた。ただし、PulseAudioの設定がデフォルトでは16Bit 48kHzだ。このUSBオーディオデバイスは24bit 192kHzまでの入力をサポートしているので、より良い音源を生成する場合には、PulseAudioの設定を買える必要があるだろう。どうやら/etc/pulse/daemon.confの内容を変更すればいいようだ。以下をコメントアウトして内容を変更する。

; default-sample-format = s16le
; default-sample-rate = 44100

いろいろと試してみると、ひどく圧縮された音源を再生すると、ホワイトノイズが聞こえる。これはアナログのヘッドフォンでも聞こえるのだが、このヘッドフォンでは特によく聞こえる気がする。

さて、不自由なWindows機に接続してみると、動かなかった。どうやら専用のドライバーをインストールする必要があるようだ。Windowsは実に不便だ。

新しいヘッドフォンでゲームをしてみると、音楽がくっきり聞こえる気がした。

たまには散財するのもいいだろう。

2017-02-28

C++標準化委員会の文書: P0550R0-P0601R0

興味深いものだけ解説。

[PDF] P0550R0: Transformation Trait uncvref

decayとよく似たtraits、uncvrefの追加。

uncvref<T>::typeはTからCV修飾子とリファレンスを取り除いた型になる。decay<T>::typeとは違い、配列からポインター、関数から関数ポインターへの変換は行わない。

あるべきだ。

[PDF] P0551R0: Thou Shalt Not Specialize std Function Templates!

std名前空間内の関数テンプレートはユーザーが特殊化してはいけないというルールを作ろうと言う提案。関数テンプレートはC++11から特殊化できるようになったので、これまで考慮されてこなかった問題が出てきた。

[PDF] P0552R0:enable_if vs. requires

既存のenable_ifを利用した関数テンプレートに制約を与えるコードを、Concept Liteのrequires実装に置き換えてみたところ、Conceptによる制約付きテンプレートは、制約なしテンプレートよりもpartial orderingで優先されるため、オーバーロード解決の結果に違いをもたらすという警告。

文書では、std::swapをenable_if実装とrequires実装したものを比較して既存のテストに失敗したときの挙動の違いが驚きだったとしている。

既存のコンセプトを使わないコードにコンセプトを使うコードを混ぜると思わぬ挙動の違いに出くわすかもしれない。

P0553R0: P0553R0: Bit operations

ビットイテレーターが提案されているが、それを実装するために必要な基礎的なビット操作関数の追加。

rotl, rotr, popcount, countl_zero, countl_one, countr_zero, countr_oneの追加

rotlとrotrは左右へのロテート。popcountは1のビット数のカウント。countl_zeroは左から連続した0のビットのカウント、_oneは1のビットのカウントcountrは右から。

P0556R0: P0556R0: Integral power-of-2 operations

符号なし整数型に対して適用できる2の累乗に関係したフリー関数を追加する提案。

ispow2, ceilpow2, floorpow2, log2の追加。引数は符号なし整数型でなければならない。

ispow2(x)はxが2の累乗である場合trueを返す。ceilpow2(x)はx以上の最小の2の累乗数を返す。floorpow2はx以下の最大の2の累乗数を返す。log2は2が底のxの対数を返す。小数部は切り捨てられる

[PDF] P0557R0:Concepts: The Future of Generic Programming

Bjarne Stroustrupによるコンセプトの解説。軽く解説(briefly explain)と言っておきながらこの分量はどうなのか。

[PDF] P0559R0: Operating principles for evolving C++

C++標準化の原則のガイドライン。

[PDF] P0562R0:Initialization List Symmetry

クラスのメンバー初期化子の末尾に余計なコンマがあっても許す提案。enumと似ている。

class C
{
    int a, b, c ;
public :
    C( int x, int y, int z ) :
        a(x),
        b(y),
        c(z), // 最後に余計なコンマが付いているが許す
    { }
}

まあ、入れてもそれほど問題にはならないだろうが、今更入れるべきことだろうか。

[PDF] P0563R0:Vector Front Operations

今は昔、賢者たる男女らは非効率的なコードを書く定めの卑しき我らを救い給うために標準テンプレートライブラリを作り給いき。しかるに、賢者は長生なる魔法使いにのみ許されたる危うげなる魔術を我らの前から隠し給いき。天旋り日転じて、田舎の若人に至るまで幾年もの魔術の鍛錬を積むこと久しく、まさに黒魔術をつまびらかにせんとする日、来たれり。何をいいたいかというと、vectorのpush_frontとpop_frontのことだ。

vectorにpush_frontとpop_frontがない理由は、O(N)の非効率的な操作だからだ。vectorへの先頭へのinsertやeraseは、残りの要素をすべて1つづつずらす必要がある。

ところで、最近のハードウェアの事情はすっかり変わってしまった。もはや見かけ上のオーダーより、データの局所性の方が重要になってしまった。局所性のあるデータを隣接するメモリにずらす操作より、メモリ確保の方がはるかにコストのかかる処理となってしまった。

実際、マイクロベンチマークでも先頭へのinsertやeraseは、vectorの方がlistやdequeより速い。

そこで、もはやvectorにpush_frontやpop_frontを付けない理由はない。

ちなみに、vectorにpush_frontとpop_frontをつけると、std::queueの内部コンテナーとして使うことができる。

P0564R0: P0564R0: Wording for three-way comparisons

operator <=>の文面案。

[PDF] P0565R0:Prefix for operator as a pack generator and postfix operator[] for pack indexing

pack-like(パック風)なものを生成するfor式と、packの中からインデックスで要素やサブパックを取り出す式の提案。


template < typename ... Types >
void f( Types ... args )
{
    // 4つめのパラメーターを取り出す
    std::cout << args[3] << std::endl ;
}


int main()
{
    // f(1,2,3,4,5,6,7,8,9)と同じ
    f( for( int i = 1 ; i != 10 ; ++i ) i... ) ;
}   

便利だ。最近、パラメーターパックを第一級市民として扱おうと言う提案が多く見られる。

P0572R0: p0572r0: bit_sizeof and bit_offsetof

ビットフィールドメンバーのビット数を取得できるbit_sizeofとビットフィールドメンバーのクラスの先頭アドレスからのオフセットを取得できるbit_offsetの提案。


struct Foo {
   uint8_t A : 2;
   uint8_t B : 4;
   uint8_t C : 1;
   uint8_t D : 1;
};

int main()
{
    bit_sizeof(Foo::B) ; // 4
    bit_offsetof(Foo::B) ; // 先頭アドレスからのビット数のオフセット
}

ほしい。

P0573R0: abbreviated lambdas

lambda式を使いやすくするために3つの機能を追加。

まず=> expr

// []( auto && x ) -> decltype(expr) { return expr ; }
// と同等
[]( auto && x ) => expr ;

引数の型名省略

// []( auto && x ) => x 
// と同等
[]( x ) => x ;

オーバーロード不可能な単項演算子>>

// static_cast<decltype(x)>(x)
// と同等
(>>x) ;

これはstd::forwardを楽に書くための記法。

[PDF] P0577R0:Keep that Temporary!

一時オブジェクトの寿命を延長するための機能の提案。registerキーワードを再利用する。

この提案は、register exprというregister式を追加する。register式によって、式の結果の一時オブジェクトの寿命はその書かれている文脈のブロックスコープの終わりまで延長される。register式はブロックスコープ内にしか書けない。

以下のようなコードが可能になる。


std::mutex mtx ;

void f()
{
    register std::lock_guard(mtx) ;
    std::string_view = register std::to_string(42) ;
}

lock_guardは変数を束縛するかムーブ代入しておかないと、一時オブジェクトの寿命が尽きてmutexがunlockされてしまう。問題はその変数自体は使わないので冗長な記述が必要になってしまう。

auto ref = std::lock_guard(mtx) ;

to_stringの結果は一時オブジェクトだが、これをstring_viewで受けてしまうと、直接参照で束縛したわけではないので、寿命が尽きてしまう。register式が役に立つ。

一時オブジェクトの寿命を延長する機能は以前にも提案されたが、ライブラリの実装にしか役に立たない仕組みだった。これならばユーザーも使うことができる。

[PDF] P0589R0:Tuple-based for loops

tupleの各要素にrange-based forの文法でアクセスできる機能の提案。ループというよりは展開だ。tupleコンセプトを満たしたものがrange-base forで展開可能になる。

今のConcept Liteが気に入らない。

P0592R0: To boldly suggest an overall plan for C++20

明らかにスタートレック信者が書いたらしきC++20の計画。以下の項目について注力する。

  • モジュール
  • コンセプト
  • レンジ
  • ネットワーク

筆者はコンセプトLite提案を気に入っていないのでコンセプトについては懐疑的だ。

そんなことよりUnicode対応が必要だと思うのだが。

P0593R0: What to do with buffers that are not arrays, and undefined behavior thereof?

mallocで確保したメモリにオブジェクトを構築したものは配列ではないので配列としてアクセスするとC++の規格上未定義の動作になるが、実際そのような処理は書かれている。どうすべきかという問題提起。

P0595R0:The "constexpr" Operator

constexpr演算子の提案。コンパイル時に評価されているかどうかを見分けることができる。

例えば、コンパイル時にはポータブルなコードで計算しないといけないが、実行時には実装依存の高速な方法で計算できるような処理があった場合に、constexpr演算子によってコンパイル時評価されているかどうかで条件分岐できる。


constexpr double power( double d, int x )
{
    if ( constexpr() )
    {
    // コンパイル時評価されているのでポータブルな実装
    }
    else
    {
    // 実行時に評価されているので最適な処理を実行時ライブラリに任せる
        return std::pow( d, static_cast<double>(x) ) ;
    }
}

P0596R0:std::constexpr_trace and std::constexpr_assert

コンパイル時printfとしてのconstexpr_traceとコンパイル時assertとしてのconstexpr_assertの提案。コンパイル時に評価された時にコンソールにメッセージを出力する方法が提供される。

constexpr_assertの存在理由はよくわからない。static_assertがあれば十分ではないか。

P0597R0: std::constexpr_vector<T>

コンパイル時計算の中でも使えるmutableなconstexpr_vector<T>の提案。もちろんpush_backもできる。

[PDF] P0599R0:noexcept for Hash Functions

std::hashの数値、ポインター、標準ライブラリに対する特殊化は例外を投げるべきではないのでnoexceptにしろというアメリカNBからの要求コメント。わかる。

[PDF] P0600R0:applying [[nodiscard]] for C++17

[[nodiscard]]を追加する標準ライブラリの策定。malloc, async, launder, allocateにつける。

これで興味深い文書はすべて解説した。リフレクション周りの文書は無視した。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-02-23

C++標準化委員会の文書: P0501R0-P0549R0

タイトルの範囲で興味深い文書だけ紹介。

[PDF] P0506R0: use string_view for library function parameters instead of const string & / const char *

string_viewで既存の標準ライブラリのstringやchar const *を引数に取る部分を全部置き換える提案。これにより規格の文面も標準ライブラリの定義もかなり短縮される。

ABI互換をぶち壊しそうだがそれに対する考察がない。

[PDF] P0515R0: Consistent comparison

operator <=>の提案。

これまで、様々な種類の比較(strong/weak/partial orderingやequality)について、それぞれstrong_order_less_thanとかweak_order_less_than

operator <=>はthree-way comparisonを提供する。

a <=> bを評価した結果の値rは、a < bの場合 r < 0。a > bの場合r > 0。a == bの場合r == 0となる。

operator <=>によって、比較の種類の問題が解決できる。戻り値の型によって種類を表せばよい。例えばある型がstrong orderingをサポートしている場合は、以下のように書く。

class X
{
    int a ;

public :
    friend std::strong_ordering operator <=>( X const &, X const & ) = default ;
} ;

weak_orderingしか対応できない型の場合は、以下のように書く。例えば、大文字小文字を区別しない文字列型は、weak orderingしか提供できない。


class CaseInsensitiveString
{
    std::string s ;
public :
    frined std::weak_ordering operator <=>( CaseInsensitiveString const & a, CaseInsensitiveString const & b )
    {
        // 大文字小文字を区別しない比較を行う関数
        return case_incensitive_compare( a, b ) ;
    }
} ;

比較の種類を型システムに載せることで、より強い比較を無理やり提供しようとするとコンパイルエラーになる。


class X
{
    CaseInsensitiveString s ;
public :
    // コンパイルエラー
    friend std::strong_ordering operator <=> ( X const &, X const & ) = default ;
} ;

同様に、partial orderingにしか対応できない型は、std::partial_orderingを返す。また、大小比較を提供できず、等価比較しか出来ない場合は、std::strong_equalityやstd::weak_equalityを返す。

さて、残りの比較演算子は、すべてoperator <=>から生成できる。

operator <=>をユーザーが使うこともできるが、通常はその必要はない。というのも、a < bを実現するには、(a <=> b) <0と書かなければならないからだ。

これは今までの提案よりだいぶマシな提案だ。

[PDF] P0533R0: constexpr for <cmath> and <cstdlib>

<cmath>と<cstdlib>の関数の内constexpr実装できるものの基準の考察

[PDF] P0534R0: call/cc (call-with-current-continuation): A low-level API for stackful context switching

call/ccを実現するライブラリの提案。

P0535R0: Generalized Unpacking and Parameter Pack Slicing

これは興味深い提案。

パラメーターパックのスライシングができる機能の提案。

template < typename ... pack >
struct X
{
    // 1番目のパラメーター
    using t1 = [0]pack ;
    using t1a = []pack ; 

    // 2番目のパラメーター
    using t2 = [1]pack ;
    
    // 最後のパラメーター
    using t_last = [-1]pack ;
    // 最後の一つ前のパラメーター
    using t_before_last = [-2]pack ;



    // 3番目から6番目までの3つのパラメーターを持つ新たなパラメーターパック
    using t3 = std::tuple<[2:5]pack> ;
    // 2番目から最後までのパラメーターを持つ新たなパラメーターパック
    using t4 = std::tuple<[1:]pack> ;
    // 1番目から5番目までの4つのパラメーターを持つ新たなパラメーターパック
    using t5 = std::tuple<[:4]pack> ;
    // packと同じパラメーターパック
    using t4 = std::tuple<[:]pack>
} ;

また、以下のような使い方もできる。


struct X
{
    int a ;
    int b ;
    int c ;
} ;

X x ;
[0]x = 1 ; // x.a = 1
[1]x = 2 ; // x.b = 2
[2]x = 3 ; // c.c = 3

興味深いし便利だ。

P0536R0: Implicit Return Type and Allowing Anonymous Types as Return Values

匿名型を関数の戻り値の型に記述できる提案。

struct { int id ; double value } f() ;

この関数の宣言に対して、後から定義を書く際には、以下のように書ける。


decltype(return) f()
{
    return { 123, 5.0 } ;
}

decltype(return)はすでに宣言された関数の戻り値の型を示す。したがって、以下のような例はエラーとなる。


int f(int) ;
float f(float) ;

// エラー、すでに宣言された関数と一致しない
decltype(return) f( double d )
{
    return d ;
}

すでに、関数の戻り値の型推定があるので、以下のようには書ける。


auto f()
{
    struct { int id ; double value ; } result( 123, 5.0 ) ;
    return result ;
}

この提案は、関数のシグネチャをあらかじめ宣言しておけるという機能を提供する。

どうもこのまま受け入れるには問題の多い曖昧な提案だ。

P0538R0: A Qualified Replacement for #pragma once

#pragma onceの機能を標準に追加する提案。

#pragma onceとは主要なC++コンパイラーが実装している非標準機能で、#pragmra onceを書いたヘッダーファイルの#includeを一回のみにする機能だ。

ヘッダーファイルの多重includeを防ぐために、伝統的に以下のようなinclude guardと呼ばれる方法が用いられてきた。

// foo.h
#ifndef _MYLIB_FOO_H_INCLUDED
#define _MYLIB_FOO_H_INCLUDED
...
#endif // _MYLIB_FOO_H_INCLUDED

今回提案されている#onceディレクティブは、ユニークな識別子が必要となる。

#once identifier [ <whitespace> version ]

識別子は::で結合することができる。これは名前空間的に使うことができる。また、識別子の後に空白文字に続けてバージョン番号を記述できる。

すでに一度#includeしたヘッダーと同じ識別子を使っている#onceディレクティブは、残りのヘッダーが無効化される。


// foo.h

#once mylib::foo

提案では、#forgetというディレクティブも提案している。これは既存の識別子を忘れることで、#onceの書かれたヘッダーを多重includeできるようにする機能だ。必要性が理解できない。

結局、一言でまとめれば、提案されている機能は伝統的なinclude guardのシンタックスシュガーだ。

P0539R0: A Proposal to add wide_int Class

wide_int<bytes, signed>型の追加。

long long int型の追加で、64bit長の整数型は表現できるようになったが、それ以上のビット長の整数型を扱いたい場合に標準で表現することが出来ない。そこで、ライブラリで任意のバイト長の整数型を表現できるものを入れようと言う提案。

template<size_t Bytes, bool Signed> class wide_int;

P0540R0: A Proposal to Add split/join of string/string_view to the Standard Library

split/joinをstringとstring_viewとregexに提供する提案。

splitとjoinはメンバー関数という形で提供される。

splitには3種類ある。splitsとsplitfとsplitcだ。これらはセパレーターを引数に取る。文字列をセパレーターで分割する。

セパレーターは、文字、文字列、regexのいずれかだ。セパレーターの文字数がゼロもしくはnull文字ひとつの場合、文字型ひとつづつでsplitされる。

int main()
{
    using std::literals ;
    auto str = "aaa bbb\nccc ddd"s ;

    auto r1 = str.splits(' ') ;
    // r1は{"aaa", "bbb\nccc", "ddd"}

    auto r2 = str.splits("bbb") ;
    // r2は{"aaa", "\nccc ddd"}

    auto r3 = str.splits( std::regex(R"(\s)") ) ;
    // r3は{"aaa", "bbb", "ccc", "ddd"}

    auto str2 = "abc"s ;
    auto r4 = str2.splits("") ;
    // r4は{"a", "b", "c"}
}

splitsは結果をvector<string>で返す。コンテナーをハードコードしている理由は、簡単なライブラリにしたいためだ。splitvは結果をvector<string_view>で返す。こちらは文字列をコピーしないでstring_viewの参照で返す。

vector<basic_string<CharT, Traits> > splits(const basic_string_view<CharT, Traits> &Separator) const
vector<basic_string_view<CharT, Traits> > splitsv(const basic_string_view<CharT, Traits> &Separator) const 

splitfは分割した文字列を関数オブジェクトに渡す。

template <class F>
void splitf(const basic_string_view &Separator,F functor) const

以下のように使う。

int main()
{
    using std::literals ;
    auto str = "a b c" ;
    str.splitf( ' ', []( auto s ) { std::cout << s << '\n' ; } ) ;
}

splitcは分割した文字列をコンテナーにemplace_backしていく。これにより、vector以外のコンテナーを使いたい場合に使える。

int main()
{
    using std::literals ;
    auto str = "a b c" ;
    std::list<std::string> c ;
    str.splitc( ' ', c ) ;
    // cは{"a", "b", "c"}
}

このコンテナーへのリファレンスを取る既存の標準ライブラリに似つかわしくないデザインについて提案著者に質問したところ、お手軽に使いたいからとのこと。あまりよろしくない動機だ。

P0543R0: P0543R0: Saturation arithmetic

C++で符号なし整数は演算結果が最低値、最大値を上回る場合、アンダーフロー、オーバーフローするが、最低値、最大値になって欲しい場合がある。そのためのsaturation演算を提供する提案。

具体的にはコードを見ると一目瞭然。

int main()
{
    // 7
    auto r1 = satadd( 3, 4 ) ;
    // 3
    auto r2 = std::numeric_limits<unsigned int>::max() + 4 ;
    // std::numeric_limits<unsigned int>::max()
    auto r3 = satadd( std::numeric_limits<unsigned int>::max(), 4 ) ;
}

便利だ。

多くのアーキテクチャのSIMD命令は、saturation演算を提供している。

P0544R0: User Injection of Filesystems

std::filesystemにユーザー側が独自の実装を追加することができる昨日の提案。

ユーザースペースによるファイルシステムの実装、例えばアーカイブファイルをファイルシステムとして扱うとか、メモリ内キャッシュをファイルシステムとして扱うような場合に、std::filesystemの実装をユーザー側が提供したいことがある。そのためにstd::filesystemの実装を追加できるようにする機能が必要だ。

また、filesystemの意図的にエラーを発生させることによるエラー時の処理のテストにも使える。

P0545R0: Supporting offsetof for Stable-layout Classes

クラスのメンバーのクラスレイアウト上のオフセットを求めるoffsetofは、standard layout classにしか使えない。しかし、standard layout classは制限が厳しすぎる。例えば、派生やコンストラクターやコピー代入演算子などがあるだけでもstandard layout classから外れる。

しかし、クラスのレイアウトを決定するのに、コンストラクターやコピー代入演算子の存在の有無が影響を与える必要はない。実際、Itanium ABIやWindows x64 ABIはそのようになっている。offsetofを適用できるクラスを増やすために、クラスのレイアウトがコンパイル時に決定できるstable layout classを新たに定義しようという提案。

ある型がstable layout class型となるためには、

  • virtual基本クラスを持たない
  • virtual関数を持たない
  • 非staticデータメンバーはスカラー型かstable layout型か、そのような型の配列型か、リファレンス型であること
  • 非stable layout classを基本クラスに持たない

virtual関数についても、主要な実装方法では、隠しデータメンバーとして実際の関数へのオフセットを保持するvtableを持つ。このメンバーのサイズと位置は固定なのでレイアウトはコンパイル時に計算できる。実際、GCC, Clang, MSVCではそうなっている。しかし、今回の提案では、virtual関数を持つ型がstable layout classを満たすことについてはconditionally supportedに留める。将来的には緩和を考える。

virtual基本クラスはvirtual関数と同じように隠しデータメンバーとして持つ。virtual関数とは違いそのサイズと位置は可変だ。最終的な最も派生されたクラス型がわかっているならばコンパイル時にレイアウトの計算ができるが、一般的にはコンパイル時に計算できないので、サポートしない。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-02-22

アンチウイルスソフトウェアの利用者は過失が問われるべき

Google and Mozilla's message to AV and security firms: Stop trashing HTTPS | ZDNet

GoogleとMozillaの調査によれば、世の中のほとんどのアンチウイルスソフトウェアは通信内容を傍受するためにブラウザーに対してMITMを仕掛けている。

MITM(Man In The Middle)とはTLS(HTTPS)接続の証明と暗号を無効化するための方法で、中間者攻撃とも呼ばれる。

HTTPSにはふたつの役割がある。通信内容の暗号化と、通信相手と通信内容の証明だ。

通信内容が暗号化されていない場合、秘密の情報(クレジットカード番号など)が途中で通信を傍受している悪意ある攻撃者に筒抜けになってしまう。それを防ぐために通信を暗号化したいところだが、それだけでは不十分だ。

まず、通信相手が本人である保証がないし、通信内容は本人のものである保証もない。通信経路の途中で傍受できるということは、当然書き換えもできるはずだ。

通信相手が本人であり、通信内容が途中で改変されていないことを示すための証明方法がある。これで問題は全て解決したかというと、そうでもない。

通信をしたい二者の間に中間者が挟まって、二者のどちらにもHTTPSで使われている証明を行うことで、どちらとも相手と通信しているように錯覚させることができる。これを中間者(Man in the middle)攻撃という。

ただし、この中間者攻撃というのは、通常はうまくいかない。何故ならば、中間者の証明書を信頼しなければならないからだ。

ところで、アンチウイルスソフトウェアは、コンピューターの中で管理者権限で動くソフトウェアである。アンチウイルスソフトウェアは自分の証明書を信頼させることができる権限を持っている。すると、アンチウイルスソフトウェアはMITMができる。

なぜアンチウイルスソフトウェアがMITMをするかというと、通信内容を傍受して、悪意あるソフトウェアが紛れ込んでいないかを監視するためだ。そのため、アンチウイルスソフトウェアの中間者攻撃の意図に悪意はない。しかし、その実装は雑である。

多くのアンチウイルスソフトウェアは、中間者攻撃の実装に不具合や脆弱性を抱えている。その結果、ユーザーのセキュリティが弱められる。

さらに、アンチウイルスソフトウェアは管理者権限で動作し、カーネルも含む他のソフトウェアにコード注入する。これも脆弱性をうみだす。

ましてや、現代の悪意あるソフトウェアは単にパターンマッチやヒューリスティックによる検出で対応しきれない。

アンチウイルスソフトウェアを実行することはセキュリティを高める事にはならず、逆に下げることになる。したがって、アンチウイルスソフトウェアを使った結果セキュリティを弱め、コンピューターに悪意あるコードの実行を許し、他人に被害を与えた場合、アンチウイルスソフトウェアを実行している人間は過失が問われるべきである。

アンチウイルスソフトウェアは詐欺なので直ちに使用を中止すべきである。

2017-02-15

C++標準化委員会の文書: 2017-02のまとめ

2017-02 Pre-Kona mailingsが公開されている。

#MAILING2017-0: ISO/IEC JTC1/SC22/WG21 - Papers 2016

参考書の執筆に注力したいため、この記事では改訂版の提案のうち興味深い文書を取り上げる。

[PDF] N4637: Working Draft, Extensions to C++ for Modules

モジュールのドラフト

[PDF] N4640: Working Draft, Standard for Programming Language C++

現在のドラフト。変更点はeditorial上のものにとどまる。valarrayの文面が最新の用語を使って書き直された。

[PDF] P0045R1:Qualified std::function signatures

constなstd::functionにconstではない関数オブジェクトを代入するとconstなオブジェクトが変更できてしまう問題がある。

struct delay_buffer {
int saved = 42;
int operator () ( int i ) { return std::exchange( saved, i ); }
};
// Small object optimization — no heap allocation.
const std::function< int( int ) > f = delay_buffer{};
assert ( f( 1 ) == 42 );
assert ( f( 5 ) == 1 );

この問題への対処として、std::functionのテンプレート実引数にconst修飾を書けるようになる。既存のconstなstd::functionは[[deprecated]]を利用してdeprecated扱いであることを明示した上でconst_castを使う

std::function< void() > const f = []() mutable {} ;
f() ; // [[deprecated]]警告付きで動作する

// コンパイルエラー
std::function< void () const > const g = []() mutable {} ;

これは便利だ。

[PDF] P0052R3: Generic Scope Guard and RAII Wrapper for the Standard Library

汎用RAIIラッパーライブラリ、だいぶ仕様が固まってきたので、これ以上大きな変更はなさそうだ。

[PDF] P0059R3: A proposal to add a ring span to the standard library

固定長リングバッファーを実装するring_spanの提案。ring_spanはストレージを管理せず、コンストラクターでcontiguous iteratorで渡されたストレージを使う。

この提案では、ring_spanからイテレーターを得るbegin/endが削除された。ring_spanはストレージを所有しないため、イテレーターを提供するのは好ましくないとのことだ。

[PDF] P0082R2: For Loop Exit Strategies (Revision 3)

繰り返し文を条件式がfalseになって抜けたのか、break文で抜けたのかによって、繰り返し文を抜けた後で条件分岐したいことがある。しかし、C++ではそれを直接表現する方法がないので、極めて冗長かつ非効率的な方法で書かなければならない。

bool did_break = false ;

for ( ... )
{
    if ( ... )
    {
        did_break = true ;
        break ;
    }
}

if ( did_break )
    ... ;
else
    ... ;

この提案はC++に繰り返し文のあとにbreakで抜けたかどうかで条件分岐する文法を追加するものだ。この改訂版では、既存のキーワードを使い回すのではなく、新しいキーワードを追加する設計に改められた。


for ( int i = 0  ; is_completed(i) ; ++i )
{
    if ( is_error() )
        break ;
}
on_complete
    do_normal_things() ;
on_break 
    do_abnormal_things() ;

キーワードはon_complete/on_breakだ。

だいぶわかりやすくなった。

P0091R4: Template argument deduction for class templates (Rev. 7)

deduction guideをdelete定義できるようにする提案。まあ、必要になる場合もあるかもしれない。

P0103R1: Overflow-Detecting and Double-Wide Arithmetic Operations

オーバーフローが検出できる整数の四則演算と左シフト演算のライブラリの提案。オーバーフローの有無がbool型の戻り値で、演算結果が実引数に渡したポインター経由で得られる関数と、ひとつの型で返す関数がある


template <typename T> bool overflow_add( T* result, T a, T b );

1つの型で返す関数の方は、split_lowerとsplit_upperで上位下位に分けることができる。

P0104R1: Multi-Word Integer Operations and Types

固定長整数ライブラリの提案

template<int words> multi_int;
template<int words> multi_uint;

演算子がオーバーロードされていて普通に組み込みの整数型のように使える。問題は、現在の文面では、1ワードが何バイトなのか実装依存だということだ。

P0105R1: Rounding and Overflow in C++

浮動小数点数の丸め方とオーバーフローの挙動を指定して演算できるライブラリの提案。

P0237R5: Wording for fundamental bit manipulation utilities

整数型をビットのコンテナーとみなしてビットへのイテレーターなどのアクセス方法を提供するアダプターライブラリの提供。おそらく規格に入る。

[PDF] P0267R3: A Proposal to Add 2D Graphics Rendering and Display to C++,

2Dグラフィックライブラリのドラフト。よくもここまでまとめたものだ。文字列描画機能はないようだ。

P0275R1: A Proposal to add Classes and Functions Required for Dynamic Library Load

shared libraryやWindowsのDLLのように、動的に関数やクラスの実装をプログラムにロードして使えるライブラリの提案。果たして標準化できるのだろうか。

P0316R0: allocate_unique and allocator_delete

指定したアロケーターでストレージを確保してunique_ptrを構築するライブラリallocate_uniqueの提案。すでにshared_ptrに対するallocate_sharedはあるので、その補完。

[PDF] P0352R1: Smart References through Delegation (2nd revision)

operator .ではなく派生を使ってスマートリファレンスを実装できる機能の提案。operator .よりよほどマシな文法と意味だ。こちらが採用されるべきだ。

P0355R2: Extending <chrono> to Calendars and Time Zones

<chrono>を日付に対応させる提案。これでようやくCライブラリを使わずにC++で型安全に日付が扱えるようになる。



int main()
{
    using namespace std::chrono_literals;
    auto date = 2016y/may/29;
    cout << date << "\n";
    // 2016-05-29
}

便利だ。

[PDF] P0447R1: Introduction of std::colony to the standard library

flat_mapと同じくらい注目している新しいコンテナーの提案、colony。

colonyはvectorのような連続したストレージ上に構築される要素に順番の概念があるシーケンスコンテナーだが、中間要素への削除が定数時間ですむ。

どのように実装しているかというと、要素の数だけのビットマップを持っていて、それぞれの要素が有効かどうかの情報をビットマップで保持している。これにより、要素をずらす処理が必要なくなる。そして、中間への挿入も無効な要素がたまたまあれば定数時間で終わる。

これはほしい。

P0479R1: Attributes for Likely and Unlikely Statements

分岐先が実行されると期待できる場合と期待できない場合にその情報をコード中に記述できる属性、[[likely]]と[[unlikely]]の提案。


if ( is_unexpected_error() ) [[unlikely]]
{
    // まず発生しないエラーの処理
}

while( is_program_exit() )
[[likely]]{
// 終了することがほとんどないプログラムの処理
}

深いパイプラインを持つ近代的なプロセッサーでは、分岐予測を外した時のペナルティは大きい。もし、プログラム中のある分岐先がほとんど確実に実行される、あるいは実行されないことがコンパイル時にわかっている場合、プロセッサーによっては分岐予測にヒントを与える命令を使うことによって分岐命令のパフォーマンスを上げることができる。そのような情報をソースコードに付加するための属性。

if, while, do while, for, range-based forに記述できる。

既存の提案の改訂版を片付けた。あとは新しい提案のうち興味のあるものだけをさっと解説して参考書の執筆に戻りたい。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-02-09

高度に発展した特許業界はヤクザと見分けがつかない

Azure IP Advantage – intellectual property protection | Microsoft Azure

Microsoft AzureがAzure IP Advantageなるサービスを始めた。

特許ゴロによる大量のゴミ特許を抱えたうえでどれかに抵触しているだろうと当たりをつけて手当たりしだいに革新的な製品、サービスを提供しているものに訴訟を仕掛ける商売はいい儲けになっている。

そのような特許ゴロ訴訟に対抗する手段としては、こちらでも大量のゴミ特許を抱えておき、特許侵害を訴えられたら相手も自分のゴミ特許のどれかに抵触しているだろうとあたりとつけて特許侵害で逆提訴するというものだ。訴訟は技術を全くわかっていない弁護士と裁判官が何年も言葉遊びを弄した挙句、和解に終わるという泥仕合を繰り広げる。

といっても、そんなことができるのは大量の特許を保有できる資本力のある世界的に有名な大企業だけであり、大多数の実際に世界に技術革新を起こしている中小企業としては、訴訟の費用と特許利用料を天秤にかけると、訴訟をしないほうが安上がりになることが期待できるので、特許利用料を支払ったほうがマシという納得できない選択が最善の状態になってしまう。

今回Microsoftが始めた商売というのは、特許ゴロ訴訟を起こされた場合、Microsoftが大量に保有するパテント・プールをもって特許ゴロを叩くというものだ。

しかしこれは、何か見覚えのある商売のように思えてならない。

世の中にはヤクザと呼ばれる圧倒的な暴力を保有した複数の団体がいる。ヤクザは暴力を行使してあなたから金を巻き上げていく。あなたはヤクザの一つにみかじめ料を支払うことによって、他のヤクザの暴力に暴力で対抗して守ってもらう。

ヤクザを特許ゴロに、暴力を特許に置き換えるとどうだろうか。不思議なほどの一致を見るではないか。これでは特許ゴロとヤクザの見分けがつかない。ヤクザのような見た目でヤクザのように鳴くならばそれはヤクザである。

そして今回のタイトルに繋がる。「高度に発展した特許業界はヤクザと見分けがつかない」

ヤクザのシノギを作り出すだけで技術革新を阻害する特許制度は廃止すべきである。

2017-02-07

「目撃!ドキュンはドキュンをバカにし過ぎでひどくない」と妻は言った

「目撃!ドキュンはドキュンをバカにしすぎでひどくない?」と妻は言った。

僕はその言葉の解釈に数秒悩んだあと、おもわずこみ上げる笑いこらえるのに苦労した。

それは午前二時の真夜中のことであった。僕と妻は非常に腹を空かせていたが、あいにくと冷蔵庫にはごぼうと生姜とにんにくしかなかった。さすがの僕でも、ごぼうの生姜とにんにくの炒め物などという何の腹の足しにならない料理を妻に提案することはしなかった。我々が村上春樹の信奉者であれば、ここでパン屋を襲撃しに行かなければならないところだが、幸い我々は村上春樹がそれほど好きではなかった。

家のすぐ近くにはすき家があるが、我々夫婦はすき家に行くのは最終手段であると考えていた。というのも、夜中に寝巻き姿で夫婦揃ってすき家に行くのは、いかにもDQNのやることであり、文化的に生きる我々にははばかられる種類の行いであるように思われたからだ。

しかし腹は空いた。食べるものが家にない。コンビニにめぼしい物も売っていない。残念ながら、今夜は最終手段としてDQNに成り下がる必要がある。

我々夫婦は最低限の防寒具を着て、DQNのようにすき家に向かった。

「何、DQNの語源を知らないのかい?」

妻はDQNという言葉を知っている上によく使うにもかかわらず、DQNの語源を知らなかった。DQNとはドキュンと読み、かつての2ちゃんねるで使われていたネットスラングが定着した言葉である。今はDQNと書くことが多いが、当時はドキュンとかドキュソと書くほうが一般的だったはずだ。そもそもの語源は、昔「目撃!ドキュン」というテレビ番組があり、いかにも教養のない家庭環境に問題を抱えている下層階級の親子を放送していたので、そのような低俗な人間を指す言葉としてDQNが使われるようになったのであった。

「・・・そういうわけで、ドキュンは2ちゃんねるで使われていたスラングだけれど、もともとは目撃!ドキュンというテレビ番組が・・・」

「なにその番組名? ドキュンをバカにしすぎでひどくない?」と妻は言った。

僕はすき家の中で、おもわずこみ上げる笑いこらえるのに苦労した。

「それは逆だよ。目撃ドキュンという番組名が作られたとき、まだドキュンはオノマトペとしての意味しか持っていなかったんだ。」

言葉の変遷とは不思議なものだ。語源によって新たに創りだされた言葉の影響で語源の意味が変わってしまう。

2017-01-31

GDBがC++コード注入をサポート

C++ Support Added To GCC's libcc1, Benefiting GDB - Phoronix

C++ support in libcc1: A comprehensive update – RHD Blog

最新のGCC 7では、GDBがC++のコード注入をサポートするようになった。

GDBは、デバッグ中のプログラムにC言語のコードをその場でコンパイルしてコード注入して実行する機能を持っている。これにC++が対応した。

この機能はlibcc1.soを通じてGDBとGCCが強調動作することによって実現されている機能だ。

CとC++は似ている言語ではあるが、名前空間など名前検索のルールが異なるので、シンボル名を探すにもGDBにC++の名前検索を実装しなければならない。また、テンプレートにも特別な対応が必要だ。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-01-30

xkcdで最近面白かった話

xkcd: Wifi

縦軸:来客がWiFiに接続できる確率

横軸:来客の技術力

グラフ中の表記、左から:

技術力低い:WiFi設定が見つけられない

技術力普通:使える

技術力高い:「ファームウェア」に原因がある

titleテキスト:右端を超えると正しく使える。ただし、その理由には「ファームウェア」が関係している"

筆者も今使っているラップトップの一台のWiFiの調子がUbuntuで悪くて苦労している。

xkcd: 職場チャット

2004年:うちの部署はIRCでやり取りしている

2010年:うちの部署はほぼSkypeを使っているが、一部の同僚はまだIRCを使っている。

2017年:ほぼ全員がSlackに移行した。しかし3人だけIRCをやめるのを拒否してIRCゲートウェイ経由で接続している。

2051年:宇宙シンギュラリティによりすべての知的意識は統合された。ただし一人だけIRCクライアント経由で参加している奴がいる。
「俺は自分の好きなようにやりたいんだ。わかるだろ?」
やれやれ

titleテキスト: 2078年:奴はようやくscreenとirssiからtmuxとweechatに移行しやがった。

たしかにこの2017年では職場内のチャットはSlackが独占した感がある。

もっと訳そうと思ったが飽きたのでこの辺で。

2017-01-24

GCCの実験的なfilesystemを使う方法

C++17には<filesystem>が追加される。GCCは実験的な実装として<experimental/filesystem>を実装している。

これを使えば、例えば以下のようにディレクトリを列挙できる。

#include <experimental/filesystem>

namespace fs = std::experimental::filesystem ;

int main()
{
    fs::directory_iterator iter("/usr/bin"), end ;
    std::copy( iter, end, std::ostream_iterator<fs::path>(std::cout, "\n") ) ;
}

GCCのfilesystemは、実験的な実装であるので、ヘッダーファイルが<experimental/filesystem>であることに加え、デフォルトではライブラリがリンクされない。

GCCのfilesystemを使うにはライブラリとして、libstdc++fs.aとリンクしなければならない。これは、gccに-lstdc++fsオプションを渡すとよい。また、libstdc++fsにshared library版はないので、安全のためにコマンドラインオプションの最後に書くべきだ。


g++ -std=c++1z その他のオプション... -lstdc++fs

libstdc++fsについては、極めてわかりにくい場所に申し訳程度にドキュメントがある。

Linking

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-01-22

最も日本人を多く殺す職について考察した結果、反医療主義という結論に至った

概要:この記事は最も多くの日本人を殺す職業について考察したうえで、最終的に意外だが確実に多くの日本人を殺している職業を特定したので書いた。結論を書くと反医療主義なのだが、考察の過程をたどっていこう。

今週の土日は何も予定がなく、かつ面白い本もPCゲームも見当たらないため、非常に暇である。そこで、最近執筆が滞っているブログのリハビリを兼ねて、何の意味もない文章を書いてみようと思う。お題はこれだ。

人を殺せる職につきたい

間接的に多くの日本人を殺せる職につきたい

絶望的に人望がないので政治家や起業家は難しい

スキルはITエンジニアの経験のみ

このクソみたいな人生の鬱憤を晴らすためだけに間接的に日本人を大量にぶち殺したい

どうすればいいのだろうか

なるほど、まず考察する内容を整理しよう。

  • この匿名ダイアリーの筆者を仮に増田とする
  • 増田は人を殺せる職につきたい
  • 人とは日本人である
  • 政治家と起業家以外の職である
  • 殺す人数は多くしたい

まず、「殺す」の意味を考えてみる。お題の文章を解釈すると、増田が自ら刃物や銃といった武器を使って人を殺す必要はない。間接的な殺人でよいのだという。すると増田は他人に殺人を命令する立場でもよいし、増田の意思決定の結果人が死ぬという状況でもよい。

死刑執行人はそれほど人を殺していない。日本で年間に行われる死刑執行の数は極めて少ない。大抵の年は0かひと桁であり、まれにふた桁の執行数があってニュースになるぐらいだ。

人を殺す機会のある職業と言われて警察、自衛隊、海上保安官を思い浮かべる読者もいるかもしれないが、これらの職業はあまり人を殺していない。自衛隊は国内の治安維持に出動した実績はまだなく、せいぜい訓練中に自衛隊員同士で殺しあったとか、事故の結果人を殺したことはあるとしても、あまりにも殺人数が少なすぎる。警察とて、治安維持に出動して暴徒と殴りあったり、犯人と交戦するような警官はほんのわずかであり、大多数の警官は窓口で非暴力的な一般市民と応対したりデスクワークをしたりしている。あとは「間接的」という言葉をどこまで拡大解釈するかの話でしかない。殺人をした警官を管理する立場にあるものは間接的に殺人をしたといえるだろうか。日本人を殺した警官の給与計算に関わっていた会計部署の警官も間接的に人を殺したと言えるのだろうか。すると、警察庁長官は警官による殺人の全件に関与したといえるのだろうか。この論法が行き着く先は内閣総理大臣が最も多くの殺人をしているということだ。いや、国家の象徴であり内閣に承認を与える天皇は内閣総理大臣を含む国内のすべての殺人を間接的に行っていると考えることはできるだろうか。しかし、現状では天皇は国民の総意と内閣の決定に従わなければならず自分の意志を表明することができない。それに、増田はおそらく天皇の職を得ることはできない。

間接的という言葉はいくらでも拡大解釈できる。

例えば、ラーメンは栄養のバランスが悪く、脂肪と塩分が過剰であり、健康に悪い。健康を損ねると人は死ぬ。すると、ラーメンの店主は殺人に貢献したことになるのだろうか。問題が塩にあるとすれば、塩の製造や販売を行う職業は殺人に関わっているのだろうか。

間接的をここまで拡大解釈していいとすると、結局日本人が最も摂取しているビールの販売元はどこか、タバコ農家は誰かということになってしまう。本来麻薬であり違法となるべき健康を害するたばこを製造、販売しているJTは極めて多数の日本人の殺害に貢献している。するとJTの多数の労働者を管理する人事部に職を得るべきだろうか。

しかし一般に、空腹の人間にラーメンをおごったり、アルコール分解能力がありビールを飲みたがっている車両を運転する予定のない人間に一杯のビールをおごったり、健康を損ないたがっている喫煙バカにタバコを一本差し出したりすることは殺人とみなされていない。

間接的な殺人を考えると、健康保険の範囲内の治療を定める職は、その意思決定によって大勢の日本人の生死を左右するだろう。政治家も間接的な影響力が大きい。しかし、これらの職は増田がつきにくい職業である。それに、これらの職業はできるだけ殺人を減らす目的があるので、判断を誤って殺人数が増えたとしても、全体的には殺人を減らす方向に貢献してしまう。

避妊具は妊娠を防ぐことによって本来生まれるべきであった人間を生まれさせないため、殺人とみなせるのではないか。すると増田は日本で最も売れている避妊具製造メーカーに勤務すべきである。しかしそのような間接的な可能性の殺人を考えるのであれば、避妊具が存在しないことによる間接的な殺人数も考えなければならない。

もし避妊具が存在しなければ、多くの望まれない子が生まれ、貧困で劣悪な環境で育てられることになる。避妊具の存在によって、そのような子供が成長して、人を殺す可能性が消されるので、避妊具は殺人件数の減少に貢献している。避妊具による未来に存在したはずの可能性の殺人を考えるのであれば、未来に存在したはずの殺人減少を差し引かなければならない。

事実、アメリカでは中絶が合法化されてからしばらくして、殺人件数が大幅に下がっている。

多くの職は、日本人の死亡に貢献している以上に、日本人の死亡を防ぐことにも貢献してしまっているのだ。

例えば、餅は毎年100人ほどの日本人を救急搬送しているが、餅を食べることは飢え死にを防ぐので日本人を生かしている。それに、窒息死の原因は餅ではなくおかゆのほうが多い。というのも、窒息死する日本人の多くは咀嚼力の著しく低下した人間であり、咀嚼力の低下した人間は日常的にお粥を食べているからだ。

そういう意味で、車も日本人を殺していない。交通事故では年間4000人ぐらいの日本人が死んでいるが、もし車がない場合、日本の物流は止まり、現在の人口を支えることができず、より多くの日本人が死ぬ。したがって、車の製造や販売の職業についた場合、殺した日本人の数より助けた日本人の数が大幅に上回ってしまう。

では非合法な職はどうか。この際、収入さえ発生していれば職業と認めてもいいだろう。例えば暴力団はどうか。残念ながら暴力団はあまり人を殺していない。というのも、日本における暴力団構成員が殺人、殺人未遂の容疑で検挙された件数は一年間にせいぜい200から300件程度なのだ。容疑者ですら3桁しかない。もちろん、検挙されていない殺人もあるだろうが、この程度の数では話にならない。コンビニ店員として酒と煙草と避妊具を売っていたほうがまだいくらか日本人の殺人に貢献できる。

とはいえ、日本全体の一年の統計上の殺人件数が1000件程度であることを考えると、暴力団による殺人は割合が高い。警察が認知する殺人件数に間接的に関わることを目的とするのであれば、やはり暴力団には所属しているべきだろう。しかし、警察に逮捕されて、勾留、懲役、禁錮の扱いを受けてしまうと、その最中はさすがに殺人に間接的にでもあれ関与したとはみなせないだろう。

警察に逮捕されずに暴力団との関係を続けて間接的に殺人に関与するには、増田は暴力団に脅されてやむを得ず金品をゆすり取られ続けるとか、暴力団の関与する高利貸しから金を借りて利子を支払うなどすればいいのではないか。こうすれば、増田は被害者であるので警察に逮捕されることはない。増田の提供した金銭は暴力団の利益となり、間接的に殺人にも使われる。しかし、これは職業ではない。しかもこのような状況は極めてクソであり人生の鬱憤を晴らすどころかますます鬱憤をためるだけだろう。

ここまで、具体的な統計を出さずに筆者の頭の中だけで考えていた。そのようなデータに基づかない考察を離れて、具体的な死因を見ていこう。

厚生労働省:死因順位(第5位まで)別にみた年齢階級・性別死亡数・死亡率(人口10万対)・構成割合

日本では、1年間に120万人ほどの日本人が死んでいる。死因の上位に来る理由を生じさせる原因となる職業につけば、最も効率よく日本人が殺せるだろう。

まず、0歳から4歳までの死因の第一位は、「先天奇形、変形、及び染色体異常」である。第二位以降もほとんどが病気によるものだ。

その後、10代の頃は病気が多い。

20代から30台になると自殺が死因のトップになる。

その後の死因のトップは癌だ。

なるほど、このことから、日本人の死亡に最も貢献できる職業が判明した。

反医療主義者である。

書籍や新聞やテレビやインターネットといった大衆に届く情報媒体を使い、反医療主義を煽って金を儲ける職業につけばよい。

乳幼児の死亡率を上昇させるためにワクチン摂取に反対する。がん死亡率を高めるために科学に基づかない、臨床試験で効果も認められていない代替医療を推奨する。

ホメオパシー、カイロプラクティック、菜食主義、反ワクチン、宗教、占い、何らかの植物やキノコを摂取すると癌が治るとの主張、タバコ、アルコール、これらの反医療主義を煽る本を書いて、テレビに出てさも効果があるかのように吹聴する職業。このような職業は実際に存在している上に、うまくやれば稼ぎもよい。

しかも、現代日本では、これらの行為を行うほとんどの職業は犯罪者とみなされていない。最悪の場合で薬事法違反程度の軽い罪だ。というのも、癌の治療を拒否するのは拒否した本人の責任であるし、抗癌剤の重い副作用について解説するのは違法ではないからだ。あとは薬事法に触れないように気をつければよいだけだ。増田は日本人さえ多く殺すことができれば、逮捕されたり懲役を受けることにはむとんちゃくかもしれないが、懲役を受けるとそれだけ反医療主義を煽ることができなくなる。

考察を始めた当初は、とてもくだらない記事になることを危惧したが、どうやらなかなか啓蒙的な結論に達することができた。この記事の教訓としては、反医療主義は危険だということだ。

2017-01-21

HoloLensを体験したが10年早かった

MicrosoftのHoloLensが日本でも入手可能になったようだ。さっそく入手した人が身近にいたので体験させてもらったが、結論をいうと、10年早かった。

HoloLensは、一見するとバカバカしいまでに巨大で無骨なサングラスだ。そのレンズに投影することにより、あたかも空間上に物体があるかのように錯覚させることができる。空間上のある場所にウインドウや3Dモデルを設置すると、その場所に固定される。HoloLens装着者は空間に固定された表示物を好きな距離、好きな角度から見ているように錯覚する。

HoloLensがどのように空間を把握しているかというと、主に赤外線による深度センサーを用いて回りの深度を把握しているようだ。それにしても装着者の動きに追随する性能がすばらしく、ズレを一切感じさせない。

HoloLens風のコンピューターの性能が上がれば、通常のコンピューターの補助的に使うのはありではないかと思う。つまり、椅子に座って通常のコンピューターを操作している中で、HoloLensも装着して、周囲に作業中に参照するひつようのあるドキュメントを貼り付けておく。回りを見回すとドキュメントを読むことができる。これの何がいいかというと、物理的なディスプレイがいらないということだ。物理的なディスプレイは物理的な空間を専有する。しかもコンピューターにはディスプレイの枚数分、物理的な出力ポートが必要だ。HoloLens風のディスプレイであれば、これがいらない。

ホロレンズの操作はハンドジェスチャーで行う。しかし、ジェスチャーを正しく認識させるのはなかなか大変だった。それに、VRでさんざん学んだことだが、人間はよほど鍛えていない限り、腕を心臓より高く上げたままの姿勢を長時間続けることはできない生き物である。これは大変に深刻な問題で、筆者は数十年後、VRが普及して普通のコンピューターのディスプレイがVRになった未来の採用面接では、エリートの求職者は体育大体操部出身のマッチョで、面接ではその鍛え上げられた肉体美を披露しつつ、「はい、私はこのようによく体を鍛えているのでVR作業を3時間連続でこなすことができますフンヌー」などと自己アピールをしているのではないかと予想している。

結論から言うと、ハンドジェスチャーは面倒で疲れる。Bluetoothが付いているそうなので、キーボードやマウスを接続することはできるのではないか。将来的には、HTC Viveのように物理的な入力装置を使う方向に進むのではないか。

HoloLensの残念な点としては視野が極めて小さいということだ。目の前に腕を伸ばして両手で長方形を作った程度の視野しかない。しかも、頭に固定したHoloLensがずれるとその視野の長方形が移動してしまう。

HoloLensを体験していると、かつてOculus RiftのDK1を体験した時のことを思い出す。荒削りではあるが未来を感じさせる先進的な技術だ。Oculus Rift DK1は、この2017年の標準では、もはや犬も食わないほどのガラクタに成り下がってしまった。かつ、Oculus VR社の方針は邪悪かつ排他的であり、HTC Viveに性能面でも劣っている負け犬と成り下がってしまった。

もうひとつ思い出すのは、Microsoftは一時期タブレットに注力していたということだ。まだ実用的なタブレットが夢物語の時代に、極めて無骨な弁当箱のような厚さのタブレットを開発していた。結果として、Microsoftはタブレットでは負けたが、HoloLensでも同じことになるのではないかと思う。初期の技術研究には多大な資金を継ぎ込むも、結局競合他社にあっさり負けてしまう、そんな未来が見える。

結局、HoloLensは荒削りな開発評価機という印象を受けた。10年後に期待したい。

2017-01-17

GCCのSVN trunkをビルドする方法

GCC 7がC++17のコア言語機能を完全に実装したので、ようやく参考書のサンプルコードが検証できるようになった。

C++ Standards Support in GCC - GNU Project - Free Software Foundation (FSF)

しかし、GCC 7はまだリリースされていない。少し試すだけならばwandboxが使えるが、本格的に使うにはローカルにほしい。

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

そこで、GCCを自前でビルドすることにした。ビルドは以下の手順に従う。

Installing GCC - GNU Project - Free Software Foundation (FSF)

GCCのコンパイルに必要なソフトウェア

Prerequisites for GCC - GNU Project - Free Software Foundation (FSF)

GCCのコンパイル環境を整えるには、有名なGNU/Linuxディストリビューションを使うのが最も手っ取り早い。筆者はUbuntuを使っている。

GCCはC++98で書かれているためにC++98コンパイラーが必要になる。ある程度最近の安定版バージョンのGCCを使うのが最も手っ取り早い方法だ。

POSIX互換シェルが必要だ。これにはGNU bashを使えばよい。

awkが必要だ。GNU awkの最近のバージョンを使っておけば問題ない。

GNU binutilsが場合によっては必要だ。とはいえ、GNU binutilsが入っていない環境でGCCを使いたいとは思わないだろう。

gzip, bzip2, GNU make, GNU tar, Perlが必要だ。

GCCはオプショナルではあるが、デフォルトで4つのライブラリを使う。GNU GMP、MPFR, MPC, islだ。DebianとUbuntuでは以下のようにして入手できる。

apt-get install libgmp-dev libmpfr-dev libmpc-dev libisl-dev 

この4つのライブラリは、主要なGNU/Linuxディストロならば十分に最近のバージョンがパッケージ化されているだろうが、GCCのソースコードには./contrib/download_prerequisitesというスクリプトがある。これを実行すると、4つのライブラリのソースコードをダウンロードしてGCCのビルド時にビルドして使うようにもできる。

flexが必要だ。GCCのリリース版のソースコードには、.lファイルからflexで生成したファイルは含まれているのだが、SVN trunkには含まれていない。configureスクリプトはflexが存在しないことを警告してくれないのでハマる。

GCCのソースコードのダウンロード

Downloading GCC - GNU Project - Free Software Foundation (FSF)

GCCのソースコードは様々な方法でダウンロードできる。最新のSVN trunkのソースコードを入手するにはSubversionを使うのが最も手っ取り早い。

svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc-trunk

一度チェックアウトしたソースコードから最新版への差分をダウンロードするには、svn updateを使う。

他にも、gitミラーやtarで固められたスナップショットもある。

Configure

Installing GCC: Configuration - GNU Project - Free Software Foundation (FSF)

GCCのビルドは、configureスクリプトを実行してMakefileを生成してmakeするという古典的な方法で行われる。configureスクリプトの実行は、GCCのソースディレクトリとは別の場所で行うことが強く推奨されている。そこでそのようにする。


svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc-trunk
mkdir gcc-build
cd gcc-build
../gcc-trunk/configure オプション

configureスクリプトには、いくつかのオプションを渡す。

今回、GCCをビルドする目的はC++17のコア言語機能を試すことだ。したがって、言語はCとC++しか必要がない。GCCはCとC++の他にも、Ada, Fortran, go, 醜悪なobjective-C, 太古の忌まわしきObjective-C++に加えて、LTOとJITも言語としてサポートしている。

言語をCとC++に限定するには、

--enable-languages=c,c++

をオプションに指定する。

この2017年では、ほとんどの読者はx86-64アーキテクチャのコンピューター上で自由なOSを実行しているはずだ。x86-64アーキテクチャは複数のビルドターゲットがある。GCCでは、32bitコードをm32、64bitードをm64、アドレスは32bitだがその他は64bitなコードをmx32としている。今回の目的はC++17のコア言語を試すことなので、複数ターゲットのコードを吐くことにしか興味がない。なので、multilibを無効にする。

--disable-multilib

GCCのビルドは、他のよくあるソフトウェアと違い、ややこしい。というのも、GCCはかつてCで、今はC++で書かれているからだ。システムのC++コンパイラーでGCCをビルドしたとして、システムのC++コンパイラーが壊れている場合、ビルドしたGCCも壊れてしまう。この問題を発見するため、GCCのビルドは3-stage bootstrapと呼ばれる方法で行われる。

  1. システムのコンパイラーでstage-1 GCCをビルドする
  2. stage-1 GCCでstage-2 GCCをビルドする
  3. stage-2 GCCでstage-3 GCCをビルドする
  4. stage-2とstage-3を比較して挙動に差がないことを確認する
  5. stage-3コンパイラーでランタイムライブラリをビルドする

今回はC++17コンパイラーを手っ取り早く試す目的なので、3-stage bootstrapは無効化する

--disable-bootstrap

結果として、configureスクリプトは以下のように実行する

configure --enable-languages=c,c++ --disable-bootstrap --disable-multilib

GCCのビルド

Installing GCC: Building - GNU Project - Free Software Foundation (FSF)

configureが成功したならば、configureを実行したディレクトリにMakefileが生成されているので、あとはmakeするだけでよい。

最適化を有効にして並列コンパイルもできる。

make BOOT_CFLAGS='-O' -j4

GCCのインストール

Installing GCC: Final installation - GNU Project - Free Software Foundation (FSF)

無事にビルドが終わればインストールできる。

make install

デフォルトではインストール先が/usr/local/下になっているので権限が必要だ。

筆者の体験では、flexをインストールしていない状態でconfigureが通り、makeに失敗した後、flexをインストールした後も途中からのmakeは失敗した。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2017-01-13

GCCがC++17のコア言語機能を実装完了

Hacker Newsで話題になっていて知ったのだが、GCCがいつのまにか、C++17の現ドラフトの全コア言語機能を実装している。

C++ Standards Support in GCC - GNU Project - Free Software Foundation (FSF)

とうとう、なかなか実装されなかったクラステンプレートのコンストラクターからの実引数推定も試すことが出来た。

#include <iterator>


template < typename T >
    struct X
    {
        X( T t ) { }
        template < typename Iterator >
        X( Iterator first, Iterator last ) { }
    } ;
// deduction guide
template < typename Iterator >
    X( Iterator, Iterator ) -> X< typename std::iterator_traits<Iterator>::value_type > ;


int main()
{
    // X<int>
    X x1(0) ;
    
    int a[] = {1,2,3} ;
    // X<int>
    X x2(std::begin(a), std::end(a))  ;
}

これが動く。感動だ。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2

2017-01-10

ボルダリングを初めて2年がたった

ボルダリングを初めて2年がたった。最初は7級すら苦労していたのだが、今は全く苦労せずに登れるようになった。現在のグレードは4級で、1ヶ月以上取り組み続けて簡単な3級が落とせる程度だ。

ボルダリングを初めてから体重が増えた。これは筋肉が増えたこともあるが、脂肪も明らかに増えている。運動により食事量が増えたためだろうか。ボルダリングを始める前は60kgであった体重が、いまは73kgほどになっている。体が重いと登りにくい。減量のため、食事量を意識的に減らし、通勤を電車から徒歩に切り替え、自宅から会社までの5kmほど歩くようにしている。5km歩くと50分ほどかかる。しかし電車で行くにしても自宅は駅から遠く、かつ乗り換えが発生するので結局40分かかる。通勤時間が10分しか変わらないのであれば、歩いてもよいということになる。一週間ほど徒歩通勤を続けたところ、体がなれたので特に疲れることはなくなった。一ヶ月ほど続けているが、痩せない。

ボルダリングでは特別な靴を使う。しかし未だに納得のいく製品に出合っていない。これまでは主にスポルティバの靴を履いてきたが、スポルティバの靴は3ヶ月ぐらいで潰れてしまう。スポルティバの中では、Geniusが一番気に入った製品だった。Geniusは9ヶ月履くことができた。今はFive TenのQuantumを履いている。この靴はFive Tenには珍しく、幅広の足でも履くことができる。3ヶ月ほど使ったが、つま先のソールが大分削れてきた。あと3ヶ月は持たないだろうと思う。Five TenのQuantumは相当に気に入ったので、次の靴もこれにするかもしれない。

ところで、クライミングジムでは、たまに白髪交じりの齢六十はとうに越していようと思われる翁が極めて動的な動きをしてグレードの高い課題を登っている。それをみて、なるほど、ボルダリングというのは歳をとっても問題なくできるスポーツなのだなと老後も頼もしく考えていると、ある人から、「果たしてそうだろうか。あの歳でなおあれだけ動ける強者のみ生き残っているだけではないだろうか」と生存者バイアスの可能性を指摘された。確かにそうだ。

2017-01-05

GoogleがGoによるPython実装、Grumpyを発表

Googleが既存の社内のPythonコードをGoで実行するためのPython実装を公開している。

Google Open Source Blog: Grumpy: Go running Python!

google/grumpy: Grumpy is a Python to Go source code transcompiler and runtime.

Googleの発表によれば、YouTubeのフロントエンドサーバーとYouTube APIはほとんどPythonで書かれているという。現在、YouTubeのフロントエンドはCPython 2.7で実行されているが、CPythonの制約により効率化には限界があるのだという。

GrumpyはPython 2.7のコードをGoのコードに変換するツールgrumpcの実装だ。grumpcはPythonで実装されていて、astモジュールでPythonをパースして、Goコードを吐く。Python 2.7系なのは、Google社内の既存のコードを実行するためだ。また、execやevalのようなインタープリター実装ならではの極めて動的な一部の機能は実装されていない。

Pythonの標準ライブラリのほとんどは、Pythonによって実装されているため、そのままGoコードに変換されてそのまま動く。

GrumpyにはGlobal Interpreter Lockが存在しない。リファレンスカウントのかわりにGoのGCにオブジェクトの生存管理を任せている。この設計のため、C extension moduleは使えない。この設計により、GrumpyはCPython実装よりスケールすると主張している。

Grumpyはインタープリターではない。Grumpyによって生成されたGoのコードは通常通りGoによってコンパイルされる。これにより開発やデプロイの柔軟性は下がるが、ネイティブコードへのコンパイルと静的解析により、より効率のよいコードを吐くことができるようになる。また、Grumpyで実行されるPythonコードは、Goのモジュールをimportして使うことができる。

興味深いツールだ。

2017-01-03

ディストピア小説のネタとして使える実話

事実は小説より奇なりとはよく言ったもので、ディストピア小説を超える実話が世の中に溢れている。

Automated book-culling software drives librarians to create fake patrons to "check out" endangered titles / Boing Boing

East Lake Country図書館のシステムは、貸出記録から人気のない本を破棄するようになっている。この図書館の司書は、フェイクの利用者情報を登録して、司書がお気に入りの破棄されてほしくない本を守るために、多数の貸出記録を捏造した。

Healthcare workers prioritize helping people over information security (disaster ensues) / Boing Boing

ある病院の医療システムのセキュリティは、一定期間の入力がないとパスワードの入力を要求する仕組みになっている。このために、看護師の医療システムの利用時間の大半は、パスワードを入力することに費やされている。刻一刻と病状が悪化する患者の情報を即座に入手しなければ患者の生死に関わる状況では、パスワードの入力にかかる時間は致命的である。そのため、ある病院では、新米の看護師を医療システムのキーボードを一定期間ごとに押し下げる係に割り当てている。

このような話をネタにしたディストピア小説が読みたいものだ。例えば監視社会で観測データから社会に不要な人間が自立型の機械によって自動的に破棄されていくディストピア世界において、人類の大半が破棄された荒廃とした世界で、生存のために観測データの捏造を続ける人類。

あるいは、電力や食料の生産が完全に自動化された世界において、生産量の調整のためにひたすら入力を一定間隔で叩き続ける不毛な仕事。

そういえば、年末にPixivのアカウントに対して大規模な他所から流出したIDとパスワードの組み合わせによるログイン試行が行われ、結果として何が行われたかというと児童ポルノ画像のアップロードだったという。これは、児童ポルノというのは法律で所有が違法なことにより、画像を投稿できるWebサイトに対する最も手っ取り早い嫌がらせの手段であるのだという。この事件から、児童ポルノを武器として利用するディストピアネタを思いついた。

例えば、児童ポルノは存在が違法であり、児童ポルノを記録するストレージも違法である。そこですべてのコンピューター機器はRFC 3751ストレージは児童ポルノを検出すると自動的に自己破壊し、また児童ポルノを検出して破壊する自律型ロボットがそこらじゅうを徘徊している。大規模な児童ポルノをばらまくマルウェアの影響によりコンピューターの大半がOmniscience Protocolにより文鎮化した世界で人類が生き残りをかけて児童ポルノを武器にロボットと戦う。児童ポルノが武器になる理由としては、児童ポルノだと判定されるものををロボットに観測させるとロボットはOmniscience Protocolを発動して自己破壊を行うからだ。