2016-09-29

C++17の標準ライブラリの参考書を書く

江添がドワンゴに入社してから、もうかれこれ3年目になる。そろそろ、「江添ごときがC++の規格で飯を食っているのはけしからん。俺はC++の規格にも詳しいしC++コンパイラーも実装できる。俺が代わりにやる」という強者が出てきて私の仕事が楽になって欲しいのだが、残念ながら、そのような状況にはなっていない。より一層のC++の啓蒙活動が必要だ。

ところで、2017年に制定される予定のC++17規格が迫っている。すでにドラフトには多くの新機能が入っている。C++17の参考書を書くのであれば今から始めるしかない。まだ紙の本として出せるかどうかはわからないが、とにかく書き始めることにする。

前回のC++11のコア言語の参考書の執筆と、Bjarne Stroustrupのプログラミング入門書の査読を経て、私はいくつかの教訓を得た。

  • 不必要に堅苦しく難しい文章を書くな。簡潔で必要最小限の文章を書け
  • 参考書のソースコードはファイルを分割しろ
  • 参考書のサンプルコードは自動でテストしろ

私の最初の本も、Bjarne Storustrupのプログラミング入門書も、必要以上に文章が堅苦しく複雑で読みづらかった。これは改善しなければならない。

私の最初の参考書のソースコードは、単一のXHTMLで書かれた。最終的にはファイルサイズが1MBを超えてしまい、テキストエディターでの編集が難しくなってしまった。

Bjarne Stroustrupのプログラミング入門書のサンプルコードは、数割がコンパイルすら通らないお粗末なものであった。これは一度書いたソースコードを手で修正したにもかかわらず、コンパイラーによるチェックを行わなかったためである。参考書は、何度もの修正編集を経て完成する。そのため、参考書の中のサンプルコードは、参考書のソースコードから自動で抽出して自動でコンパイルにかけてテストする仕組みを作る必要がある。

そこで今回、上の3つの教訓を元に、以下のような対策を講じた。

  • textlintを使って日本語の文章に制約をかける
  • Markdownで書いてPandocで他のフォーマットに変換する
  • 参考書のソースコードからサンプルコードを抽出してGCCとClangでコンパイルにかける仕組みを作る

textlintは、node.jsで書かれた日本語の文章を形態素解析して特定のルールに従っているかどうかをチェックするためのツールである。あらかじめ技術文書用のルールが用意されているので、今回はこれをそのまま使う。デフォルトのルールはやや厳しいと思うのだが、文章を簡潔にするための制約として甘んじて受け入れる。

PandocはMarkdownなどの様々な入力フォーマットから、更に多数の様々な出力フォーマットへの変換を行うツールだ。アスキードワンゴ編集部はtexを使っているが、作業用のtexを生成するのもMarkdownからPandoc経由で生成している。

参考書のソースコードからサンプルコードを抽出してコンパイルするテストは、適当なツールがなかったので適当に実装した。C++で書いて200行ぐらいだった。

あとは通常のプログラムと変わらない。参考書のソースコードはテキストファイルであるのでgitでバージョン管理できる。アスキードワンゴ編集部の編集者はgitもGitHubも使えるので、修正作業などはgitとGitHubのPRを経由して行うことができる。ソースコードから参考書のビルドにはMakeを使う。

思うに、すべての作家はgitを使うべきである。また、簡単なコードのひとつぐらいは書けたほうが執筆に必要な作業のやテストの一部を自動化できてよい。

さて、ここまでは理想通りだ。しかし、現実は理想通りには行かない。

私がこれから書くのは、C++17規格に準拠した参考書である。しかし、C++17は2017年の年末になるまで制定されない。当然、執筆中にドラフトの内容が変わっていくので、執筆当時のドラフト段階の規格は、正式な規格とは異なる可能性がある。もちろん、サンプルコードのテストは用意したので、規格準拠のC++17コンパイラーが出れば検証できる。しかし、ここに最大の問題がある。

現在、ドラフトに完全準拠しているC++17コンパイラーは存在しない。したがって、いま執筆している部分のサンプルコードは、コンパイラーによるチェックができない。私の予想では、C++17のコア言語の規格に準拠したC++コンパイラーのリリースには、まだ2年ほどかかると見ている。C++17の標準ライブラリの規格準拠の実装はさらに遅れるだろう。

状況は2009年ごろにC++11のコア言語の参考書を書いていた時と同じだ。ただし、当時と違って今はClangがある。Clangの規格準拠度と実装速度は素晴らしいので、当時よりはマシだ。例えば、Clangは最新の構造化束縛を不完全ながら実装し始めている。

std::tuple< int, float, double > f()
{
    return { 1, 2.0f, 3.0 } ;
}

int main()
{
    auto[ a, b, c ] = f() ;
}

ただし、コンストラクターからのクラステンプレートのテンプレート実引数推定はまだ実装していない。

// std::tuple<int, float, double>
std::tuple t( 1, 2.0f, 3.0 ) ;

そして、ライブラリの参考書の執筆はコア言語以上に難しい。

ドワンゴ広告

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

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

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

XKCD 1739: 問題の修正

xkcd: Fixing Problems

問題の修正

「何をしているんだい?」

「問題を修正しようとして作り出した問題を修正しようとして作り出した問題を修正しようとして作り出した問題を・・・」

titleテキスト:「修正しようとしている問題の最初のきっかけとなった問題は何だったんだ?」、「えっとね、使ってたツールが非効率的で時間の無駄だったんだ」

ついに来たか!

2016-09-25

新しく買ったバリカンが素晴らしい品質だった

バリカンという言葉の語源は、日本に輸入されたバリカンの製造元の社名、バリカン・エ・マール製作所に由来する。社名がそのまま製品名として普及し、一般名詞化してしまったものだ。

私は頭を定期的に剃る習慣を有していたが、この半年ほど剃髪を怠っていた。その理由は自身の怠惰でもあるのだが、現在使っているバリカンが、もう購入してかれこれ7,8年はたっており、すっかりくたびれてしまったからだ。あのジャストシステムの一太郎に対してヘルプアイコン特許訴訟を起こした悪名高いパナソニックのER510Pというバリカンで、髪の毛を吸引する機能が付いている。買った当初は、まだもう少しまともではあった覚えがあるのだが、今となっては剃り味も悪く、吸引機能も著しく劣化している。

とはいえ、髪は伸びている。髪を伸ばしていいことはひとつもない。髪があると夏暑く、汗フケ臭いの元となり、洗髪も煩わしく、なかなか乾かず、寝癖も尽くし、ヘッドフォンを装備するにも邪魔であるし、メガネをかけるにあたってもみあげがメガネのツルに当たる。およそ機能的と言える利点が一つとしてない。

世の中のコンベンショナル・ウィズダムに染まりきった浅はかで非科学的な人間は、髪は防寒の用に立つとか、頭を強く打ち付けた時あるいは物が頭に強く打ち付けられた時髪があることによって衝撃を吸収し怪我を緩和させる、という機能を挙げる。自分の頭髪を剃って比較実験をせず、また科学的に検証された研究結果を出典として参照することなしにそのような主張を行う。

もし、首をマフラーのごとく2,3回も巻けるほど長い頭髪を有しているのであれば、なるほど防寒の用にも立とうが、大抵の人間はそこまで頭髪を伸ばさない。頭髪による頭部への衝撃の緩和の効果はきわめて小さい。

我々近代的な人間は、防寒用の帽子や、防御用の帽子を発明している。まだ石器すら使わない文明レベルの人間ではないのだから、より強力な機能を提供する方法を用いるべきである。

人間は進化の過程で体毛を薄くしたが、頭髪を失わなかった理由はなぜだろうか。自然淘汰は、生存と生殖に有利な特性をひいきする。頭髪は生存の有利な機能を提供していない。しかし、我々の人間社会を観察するに、頭髪の有無は生殖の機会に大きな影響を与えているのではないか。これを科学的に実証するには、千人ほどの被験者に、頭髪を伸ばした状態と剃り落とした状態で、多数の異性に対して生殖活動を行う交渉を持ちかけさせ、その交渉結果を集計して比較すればよい。残念ながら、筆者はそのような科学的な検証が試みられたかどうかを知らないので、この説はまだ証明できない。

それはさておき、近日、たまたまネット上で以下のようなブログ記事を読んだ。

はてなインターンで優勝して,高級バリカン買った - 人権真骨頂

それによると、フィリップスのQC5580というバリカンが、坊主頭にするのにとても性能がよいということであった。@hitode909氏もおすすめの製品であったので、買ってみることにした。

私が買ったのは、マイナーアップデートがされたと思しきQC5582という型番で1万円もした。ヘルプアイコン特許訴訟を起こしたパナソニックのバリカンは、当時8千円ほど支払った記憶があるので、吸引機能というギミック付きのバリカンに比べてもお高い高級バリカンである。そして吸引機能はない。

買ってからも一週間ほど、髪を剃るのが煩わしく使っていなかったが、今日、意を決して髪を剃ってみた。なるほど、この製品の性能はたしかに素晴らしい。あれだけ長かった髪を一瞬で刈り終えることができ、しかも頭皮への損傷が感じられない。これはとてもよいバリカンだ。1万円の価値はある。

ひとつ疑問点を上げると、このフィリップスのバリカンには刃の角度を変えられるギミックがあるが、この機能の必要性はわからなかった。

2016-09-24

カプコンのPC版ストリートファイター5にチート対策として誰でもカーネルモードで任意のコードを実行できるルートキットが仕込まれている問題

Double KO! Capcom's Street Fighter V installs hidden rootkit on PCs • The Register

カプコンのPC版ストリートファイター5のアップデートで、チート防止機能の実装に、rootkitが含まれている問題。

PC版ストリートファイター5のアップデートに含まれているカーネルドライバー、capcom.sysは、IOCTLでサービスを提供する。その挙動は、まずSMEPを無効にし、呼び出し元の指定したポインターの参照するユーザーモードのアドレス空間上のコードを実行し、SMEPを再び有効にする。

とんでもない脆弱性で、ユーザーモードからカーネルモードでの任意のコード実行を可能にするので、rootkitに分類できる。

Supervisor Mode Execution Protection(SMEP)とは、カーネルモードからユーザーモードに割り当てられたアドレス空間のコードの実行を防ぐCPUの保護機能。

この実装者がヤクでもキメていたかのようなイカれた挙動は、ストリートファイター5でメモリ書き換えのチートを防止する機能のために使われているようだ。

カーネルドライバーを実装できるほどMSのドキュメントを辛抱強く読める能力を有したプログラマーが、この挙動がいかにヤバイものであるかを認識できないというのはにわかに信じられないのだが、一体どうなっているのだろう。

なお、カプコンは公式Twitterアカウントで近いうちに修正を出すと発言している。

xkcd: データセンターのスケール

xkcd: Datacenter Scale

「RAIDコントローラーは私どもの規模では無意味ですね。すべてはより上位で冗長性を確保しています。ディスクドライブが一つ故障したら、マシン1台を丸々破棄しています」

「マシン1台? うちではラックごと破棄しているぞ」
「そうよ。誰がサーバーを1台交換する作業をするっていうの?」

「うちのところは、部屋ごと交換しているよ。うちの規模では、ラック単位で何かをするのは経済的ではない」
「すげぇ」
「Googleみたいだ」

「うちなんかスプリンクラーとか消化剤噴出機なんてものは用意していないわ。データセンターで火災が発生したら、自然鎮火するまで待って、町ごと作り変えることにしてるわ」
「合理的だな」
「避難はしごとか設置する必要、本当にあるのかな」

titleテキスト:アシモフの宇宙ACは超空間中のデータセンターを接続したものだが、実際よく出来ている。エントロピーを逆転させることはない。寿命が来たら、単に宇宙を廃棄して、新しい宇宙を注文するだけだ。

titleテキストを翻訳するためだけにアシモフのThe Last Questionを読んだが、なかなか良く書けている。

The Last Question -- Isaac Asimov

2016-09-22

LenovoのWindows 10 Signature EditionがSATAがRAIDモードに固定されているのはIntelのせい

本の虫: LenovoのWindows 10 Signature Edition PCにLinuxのインストールを妨害する機能が発覚

前回、LenovoのコンピューターのSATAがRAIDモードに固定されているため、Windows以外のOSをインストールすることができないと書いたが、この真の原因はIntelだそうだ。

mjg59 | Microsoft aren't forcing Lenovo to block free operating systems

mjg59 | Skylake's power management under Linux is dreadful and you shouldn't buy one until it's fixed

IntelのSkylake世代のCPUの省電力機能を完全に使うためには、SATAも省電力機能に対応していなければならない。SATAを省電力機能に対応させる方法を、Intelは現在、公開していない。IntelのAHCIドライバーはSATAの省電力機能に対応しているが、MicrosoftのAHCIドライバーは対応していない。そこで、IntelのAHCIドライバーを確実に使わせるために、MicrosoftのAHCIドライバーが対応していないRAIDモードを有効にしているのだという。

RAIDモードに固定する嫌がらせのような仕様にしている理由は、通常のユーザーがうっかり変えないようにするためなのだろう。

この件における真の悪役はIntelであり、IntelにSATA省電力機能のための情報公開を迫るべきであるそうだ。

2016-09-21

LenovoのWindows 10 Signature Edition PCにLinuxのインストールを妨害する機能が発覚

Warning: Microsoft Signature PC program now requires that you can't run Linux. Lenovo's recent Ultrabooks among affected systems. : linux

BaronHK comments on Warning: Microsoft Signature PC program now requires that you can't run Linux. Lenovo's recent Ultrabooks among affected systems.

LenovoのSignature Edition for Windows 10のPCに、GNU/Linuxがインストールできない問題がある。

問題は、LenovoのSignature Edition PCでは、ストレージがプロプライエタリなFake RAIDモードになってる。Fake RAIDとは、物理的に複数のストレージを、ファームウェア側であたかもRAID0を使っているかのように一つのストレージに見せかける機能である。真のハードウェアRAIDとは違い、完全にハードウェア側でRAIDを実現しておらず、ソフトウェアによる対応が必要である。つまり、特別なドライバーが必要になる。

一時期、見かけ上のストレージ性能を上げるために、Fake RAIDで2つのSSDをRAID0で一つのストレージに見せかける構成のラップトップが流行したが、最近は下火になっている。

そもそも、ソフトウェアによる対応が必要なRAIDならば、すべてソフトウェアで行うべきである。Fake RAIDでやっているのは、複数のストレージをまとめる設定が事前に行われていて、ユーザー側がソフトウェア上で意識しなくてもよいというだけの話だ。

ましてや、RAID0を組むと、片方のストレージの故障で、ストレージ全体が壊れるので、安定性の面から極めて心配だ。

それはさておき、LenovoのWindows 10 Signature Edition PCでは、プロプライエタリなFake RAID構成になっていて、しかもBIOS設定でRAIDモードからAHCIモードに切り替えることができなくなっている。UEFI変数を直接変更してAHCIモードにしても、即座にRAIDモードに設定を戻す嫌がらせのような仕組みが施してある。

この嫌がらせのような仕組みに対して、Redditユーザーが、Best Buyのレビュー欄でLenovo社員を自称する人間から受けた返信として、LenovoとMSは秘密の契約をしていて、Windows以外のOSのインストールを妨害するためにこのような嫌がらせのような仕様にしているのだと明かされたというコメントがある。

なお、この嫌がらせのような妨害措置を回避したというユーザーが現れている。

Re: Yoga 900-13ISK2 - BIOS update for setting RAID... - Page 15 - Lenovo Community

それによると、基盤にプログラマブルチップをハンダ付けしてBIOSを書き換え、AHCIモードに切り替えたところ、Linuxのインストールに成功したとのことだ。

LenovoとMicrosoftのブランドは地に堕ちてこれ以上堕ちることはないと思っていたが、まだ地面にめり込むほど堕ちることができるらしい。

不自由なソフトウェアを使った当然の報いである。

追記

mjg59 | Microsoft aren't forcing Lenovo to block free operating systems

mjg59 | Skylake's power management under Linux is dreadful and you shouldn't buy one until it's fixed

どうも、これはIntelの省電力化のためであるらしい。というのも、IntelのSkylake世代のCPUの省電力機能を完全に使うためには、SATAまで省電力機能に対応させなければならない。IntelのAHCIドライバーははこの省電力機能を使っているが、MicrosoftのAHCIドライバーは使っていない。そこで、省電力機能を確実に有効にするため、RAIDモードを有効にして、Microsoftのデフォルトのドライバーが使われないようにしているらしい。

IntelはSATAの省電力サポートの方法をドキュメント化していない。SkylakeはPC8までのレベルの省電力をサポートしているが、GNU/LinuxではPC3レベルまでの省電力しか使えない。Intelのドキュメントによれば、Skylakeの省電力機能に完全に対応しないまま使うと、CPUに損害を与える可能性があると書いてある。とても心配なことだ。

面倒なことに、SATAを使わない状態でも、SATAの省電力機能に対応しない場合、PC3までの省電力機能しか使えないそうだ。

そのため、この件における真の悪人はLenovoやMicrosoftではなく、Intelであるとのこと。

2016-09-20

レールに沿わない人生を送っていたら、未だにレールに乗れていない人間のお話

レールに沿うの沿わないのという話題が、ここ数日ブログ界隈でもちきりだ。どうも背景事情には、「ブログを開設して稼ぐ方法を教えます」というセミナーを開いて稼いでいるマルチ商法もかくやと思われるブロガーの存在が出てくる。いつの世にも、本当に儲かるのは、金鉱掘りではなく、ツルハシやジーンズを売る者たちだ。

そもそも、ブログは登場してからもう15年以上は立っている赤錆びた存在であり、ブログで稼ぐというのも、すでにレールに沿った人生ではある。

普段なら、そのようなマルチ商法まがいの、速やかに忘れ去られる短命な話題には乗らないのだが、あのchokudai氏も流行にことよせてブログを書いているのを見て、私もひとつ、ブログを書いてみようと思い立った。

大学院在学中にレールに乗ったまま起業した話 - chokudaiのブログ

省みるに、私の人生はまったくもって世間の一般大衆の想定するレールに沿っていないから、あるいは誰かの参考になるかもしれないからだ。もっとも、結論で書く通り、何の参考にもならないし、(今のところは)幸運に恵まれた人生でしかないのだが。

私は誰だ。

江添亮君はプログラマーが職業である。

プログラマーという概念には、何かコードを書いているということが伴う。江添君はプログラマーが職業であるにもかかわらず、なんにもコードを書いていない。10代の頃にはWin32 APIを直接使って、必要な自動化のための処理に無駄に車輪の再発明をした挙句、GUIのフロントエンドソフトウェアを書いていたそうだが、今ではGUIなどまったく触っていない。むしろ最近はGUIを煩わしいとさえ思っており、このブログも、適当なシェルスクリプトで雛形を生成したうえで、Vimで編集し、gitでバージョン管理している。昔ならエディトウインドウに記事を執筆して投稿ボタンを押せば投稿を済ませてくれるGUIのWindowsネイティブのプログラムを自作していたところだろう。

つまり、今では自分でスクラッチから実装するよりも、出来合いのツールを組み合わせてハックする古き良きUNIX的なやり方を好むようになっている。

にもかかわらず、世間では、江添を優秀なプログラマーであると誤解している人間がいる。これは不思議なことだ。というのも、ほとんどの人間は、江添の書いた職業プログラマーが扱うほどの大規模なコードを読んだことがないはずだ。ある人間のある能力の優劣を評価する情報がない場合、その人間は平均的な能力を持っているのだろうと推定するのが最も確率的に正しい行動であるにもかかわらず、人間の評価は、相関性すらない他の評価に引きづられる。

「ビル・ゲイツは大金を持っているので、能力、人格、発想のすべてが、大金を得るに値する超人的に素晴らしいものであろう」と期待するようなものだ。

さて、前置きが長くなったが、江添亮という人物を理解するために、その歴史を追ってみよう。

幼少期

江添亮は兵庫県神戸市の垂水区にある旭ヶ丘病院で生まれた。神戸の記憶は一切ない。ただ、その後引っ越して、奈良に住んでいたことはわずかに覚えている。

その後、静岡の田舎に引っ越し、幼稚園に2年ほど通った。そして、高校を卒業するまで、静岡で暮らすことになる。

小学校と中学校には、あまりよい思い出がない。高校は、通学に片道10kmほど自転車を漕ぐ必要があったことと、平和だったことぐらいしか特徴がなかった。

江添は小学生の頃からプログラミングがしたいと思っていたが、自分のコンピューターを所有していなかった。この制約は、江添の現在につながる習慣の元となった。コンピューターを所有していなかったために、江添はプログラミングの参考書を読んで、脳内でプログラミング言語の文法を把握する必要があった。

また、当時の江添は、プログラミングには英語の習得が必要であると信じていた。そのため、英語を学んでいた。

言語を学ぶということは、江添にとって楽しいことであった。言語能力は遺伝するのだろうか。あるいは、後天的な環境によるものであろうか、江添の両親も言語の解釈を好んでいた。家には和文や漢籍がいくらでも転がっていた。

高校生になり、貴重な一夏を時給800円程度の労働に費やす代償を支払って、コンピューターを買った。そして、何年も本だけ読んで脳内で把握していたプログラミングの文法が、実際のコンピューター上で、解釈通りに動くことを確認した。そしてしばらくはMSDNによるWin32 APIの英語ドキュメントを読んで解釈して、コードを書き、解釈が正しいことを確認していた。しかし、GeForce 4 Ti 4200を積んだそのコンピューターは、ゲームに使われることのほうが多かった。

江添は、たいていのプログラミング言語のドキュメントを読んで文法と機能を解釈できたが、唯一、C++だけはなかなか理解できなかった。これは、日本語で書かれたC++の参考書は、C++を理解した者によって書かれていないためであった。そこで、江添はC++の標準規格を読み始めた。

さて、高校を卒業する頃には、江添はすっかりC++の膨大な規格の解釈という作業にとりつかれていた。高校を卒業後の進路については、何も考えていなかった。江添は高校時代をC++とゲームとゲーテに費やしていたため、大学に入るのに必要な基礎的な学力の工場を怠っていたし、親が京都への引っ越しを計画していて、親の負担を考えるに、一体どこの大学に入ればいいのか、皆目見当がつかなかった。

京都でニート生活9年間

さて、高校を卒業して、京都に引っ越した。江添の親は、モラトリアム期間の延長の方便として、京都コンピューター学院という専門学校を受験するように提案した。

京都コンピューター学院には端的に言って私が学ぶべきものはひとつとしてなかった。C++の講師はC++標準規格を理解していなかった。駅前の後者には、現在存命中の理事長であるオバハンの銅像が立っていた。生きている人物の銅像を立てるというのは天にも届くほどの醜いエゴであり、いやしくも心ある者の行うことではない。ちなみに、その理事長のオバハンはCOBOLぐらいなら書いたことはあるのではないかと思われるような演説をよくしていた。

京都コンピューター学院の入学式では、「君たちは大学に入れなくて落ちこぼれたと思っているかもしれないが本専門学校は就職率もよく教育も行き届いており最高である」などと講師が主張していた。また、謎の外人が出てきて、英語で謎のスピーチを行っていた。その内容は技術的ではなく、しかも無駄に難解な言い回しで、ポストモダンの論客がよく使う手法である、聴衆をけむにまくためにわざと難解に話しているのではないかと思われた。

ただ、これでもまだ専門学校の中では相対的にマシな部類であるそうだ。

さて、程なくしてレベルの低い専門学校をやめた江添は、京都で9年間ほどニート生活に入る。ニート期間中は何をしていたのか。もちろん、表立って見える活動としては、ブログを書いていたり、C++の規格を学んだりしていたようにみえる。しかし、大部分の時間は、睡眠、料理、運動、ゲーム、古文漢文の読解に費やされた。特に、平家物語の諸本の比較や、文覚上人について研究していた。京都は平家物語を最適な場所だ。なぜならば、平家物語の舞台だからだ。平家物語では、何万余騎と書いてある場面を、実際の土地に照らし合わせてみると、数百人も入らないだろう狭い場所であったりした。また、天皇か法皇を幽閉から開放して安全な場所に移す場面では、幽閉場所から避難場所までの直線距離が、たったの5,6kmぐらいしか離れていないなどの、文章とは違う規模の小ささに唖然としたりした。

さて、ニート期間中に、C++の参考書の執筆の話がやってきたが、出版社と著作権の代行管理と電子書籍出版に対する価値観の相違によりお流れになってしまった。その本は、いま、アスキードワンゴ編集部から「C++11/14のコア言語」として出版されている。

ブログ

江添はブログを書いている。しかし、それほどたくさんの記事は書いていないし、ひとつの記事あたりの平均のPV数は少ない。これは、江添の専門とするC++の読者の数に限りがあるということだ。江添は、その時点で話題になっている技術界隈の話の解説記事を書くこともある。しかし、そういう記事は、ほとんどの場合、PV数を稼げない。ブログで直接に広告収入で稼ぐ場合、PV数が正義である。どのような広告を貼るか、どこにどのくらいの数を貼るかなどという些細な違いは、PV数を上げて物理で殴ることより無視できる。

PV数を稼げる記事とは何か。それは対象となる読者の数が多い話題である。「朝早く起きるための7つの方法」とか、「今日から忘れ物をしないためにできる3つの対策」のような、くだらない記事がPV数を稼ぐ。問題は、この手の内容は大量にある他のブログとの差別化が一切できないため、過酷な競争に晒される。しかし、差別化のために専門的な内容にすると、対象となる読者の数が減る。また、調査に時間がかかるため執筆速度が下がる。

これは、YouTuberでも同じだ。稼いでいるYouTuberは、皆一様に同じ作り笑い顔をして、やれカップラーメンやカップ焼きそばを食べただの、やれ危ない火遊びをしただのといった、誰でもできることをしている。もちろん、基礎的な能力を満たしたうえでのことである。基礎的な能力とは、まともな高品質の撮影機材を使い、高度で手間のかかる映像編集を行い、しかも毎日新しい動画を公開するという数をこなした上でのことだ。果たして、それは好きなことで生きていると言えるのだろうか。

こうして、ブロガーやYouTuberも、レールに沿った稼ぎ方をするようになる。

ブロガーやYouTuberが稼ぐ方法はもうひとつある。元締めである。

ブログで稼ぐ方法を教えるサロン。動画投稿で稼ぐ方法を教えるセミナー。そういった教育、情報商材、元締めで稼ぐ方法である。相当に有名なブロガーやYouTuberの多くは、この元締め業に切り替えることでさらに稼ぎを増やしている。しかし、これはねずみ講やマルチ商法に似ていて、稼ぐ方法を教えると称して報酬を取り、肝心の稼ぐ方法とは、究極的には、「私と同じことをしない」と言うに過ぎないからだ。

江添は、そのようなレールに沿った行き方をしたくなかったので、ブログで稼ぐことはできなかった。

未だにレールに沿っていない現在

さて、ブログで稼ぐことができなかった江添はどのような方向に向かったのか。江添は意外にも、企業に雇用されるという、一般的にレールに沿っていると思われる選択をした。

そろそろ貯金も尽きてきたという2013年になって、ドワンゴが連絡をしてきて、成り行きで雇われて今に至る。雇われてはいるが、特に仕事はない。なので、C++の最新の規格の動向や、次の規格に入れるべく提案されている新機能をこのブログで紹介したりしている。そして、いつの間にかドワンゴ社内に出版社ができているので、ニート時代に書いていたC++の参考書も出版できた。今は次のC++17に向けた参考書の執筆を進めている。

さらに話を面白くするために事実を記述すると、女が家にやってきていきなり結婚をしたいと言ったので、結婚をしてから1年立つ。

レールに沿わない人生を歩んできた結果、未だにレールに沿っていない。

レールに沿わない人生を送るために必要なもの

レールに沿わない人生を送るにあたって必要なことはなんだろうか。努力だろうか、才能だろうか。家柄だろうか。

答えは運である。

世の中の多くのことには、乱数が関係している。リチャード・ファインマンがかつて言ったように、人間の脳は乱数を理解できるように作られてはいない。人間は乱数を理解できない。

人間は規則性のない乱数を作り出すことができない。人間は乱数にパターンを見出す。人間は、ランダムに明滅するランプと、そのランプを制御できるとされているダミーのボタンを提示された時、ボタンを押してランプの明滅を制御できたと信じる。

江添は特に努力はしていないし、才能もない。C++よりは運動や料理や古文漢文やゲームにかける時間のほうが長い。江添が現在に至った理由は、単に親が息子に9年間もニートを許すほど経済的に恵まれていたことと、たまたまドワンゴがC++の啓蒙を必要としていたこと、たまたまドワンゴに出版社ができたこと、たまたま結婚相手を探していた女が近くにいた事という、完全にランダムな結果にすぎない。そして、今はうまく言っているように見えるかもしれないが、所詮は運次第なのだから、将来はどうなるかわからない。

そもそも、数ある可能性の中で、現在が最高だという保証もないのだ。もし、江添が普通に業務用のコードを書くプログラマーを最初から目指していたならば、いまよりよい結果になった可能性もある。

結局、世の中は運次第であれば、希望はないのだろうか。そうではない。乱数は理解できるし、理解したならば、利用することもできる。

デビュー前のビートルズは、レコード会社から、「今時はやらない古臭いバンド」と言われた。ハリーポッターの著者のJ.K.ローリングは、何十もの出版社に持ち込みをかけては断られた

成功が乱数に従うということは、どんなに低い可能性であったとしても、試行回数を増やせばいずれは当たるかもしれないということだ。もちろん、大多数は当たらずに日の目を見ずに沈んでいく。

スティーブン・キングは自分の作品が知名度で売られているのではないかという思いから、作品を変名で出版したところ、全く売れなかった。ビル・ゲイツの思想は、天文学的な大金を所有しているにもかかわらず、常人からそれほどかけ離れたものではない。

ある共通の製品を提供する各社のうち、運によって一つがたまたま抜きんいでて、競合他社に対して大した優位性を持っていないにもかかわらず、運の影響によって僅かに市場シェアが高いがために、そのまま市場を独占してしまうことはよくあることだ。

世の中で大成功したと言われている人間も、最初の起爆剤となる運が少し良かっただけかもしれないのだ。

ドワンゴ広告

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

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

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

2016-09-19

Librebootの開発者Leah Rowe、自由ソフトウェア財団がトランスジェンダーを理由に人を解雇したと糾弾、自由ソフトウェア財団は否定、ポップコーンを用意されたし

Corebootからバイナリブロブなファームウェアを取り除いたdownstream forkであるLibrebootの開発者であるLeah Roweが、LibrebootはGNU傘下から撤退すると宣言した。

[Libreboot] libreboot is not GNU Libreboot anymore

その理由として、自由ソフトウェア財団がトランスジェンダーであることを理由として人を解雇したためとしている。また、メールの文末はFSFとGNUに対するFuckで終わっている。

また、LibrebootをGNU傘下から外すことによるLeah Roweのgitコミットメッセージは、"fuck GNU"である。

fuck GNU · b204a20ba7 - NotABug.org: Free code hosting

RMSの返信で、解雇は性別に関係するものではないと書いている。

Re: [Libreboot] [gnu-prog-discuss] libreboot is not GNU Libreboot anymor

自由ソフトウェア財団の公式な声明では、そのような事実はないとしている。

Free Software Foundation statement on 2016-09-16 — Free Software Foundation — working together for free software

Leah Roweは、LibrebootのWebサイトにおいて、以下のように声明を出している。

Libreboot opposes the Free Software Foundation and the GNU project

読んだところ、この文章は極めて感情的であり、しかも何らの証拠をも提示していない。しかし、自分でたれ込んだPhoronixやRedditへの白熱した議論へのリンクは張っている。また、解雇された人物の特定は、個人攻撃を防ぐため避けるとしながら、自由ソフトウェア財団側の責任者の名は挙げている。これまでにLeah RoweがFSFに寄付した金を返せとも書いてある。

なお、この文章は、gitのコミットログを見る限り、おそらくLeah Roweによって書かれたと思われる。しかし、文章は三人称で書かれていて、Librebootプロジェクト全体を「我々」と呼称し、Leah Roweも一人称ではなく名前で参照している。

statement regarding libreboot and GNU · 9050375b30 - NotABug.org: Free code hosting

Librebootの他の開発者の一人は、この状況に対して憂慮している。

Libreboot screwup

Librebootプロジェクトの主要な貢献者の一人として、私はMinifreeから2種類のチップセットのサポートの仕事を請け負っている。

現在の騒乱について、Librebootに貢献することで利益を得ることを継続したい身ではあるが、現在のLibrebootプロジェクトとlibrebootコミュニティの事実についていくつか書いておく必要がある。

  1. 最近気がついたことだが、Leah RoweはWebサイトlibreboot.orgにgitコミット権を持つ唯一の人物にして、、Librebootのコードベースに対するコミットアクセス権を持つ唯一の人物である。現在、これは問題になっている。
  2. コードベースは、corebootレポジトリのブロブ除去版であり、librebootの貢献者のパッチを含み(ただし、コミットしているのはLeahだ)、それから利用を楽にするためのインストールスクリプトが多少ある。
  3. 我々(貢献者)は、Leahが見切り公開したlibreboot.orgのWebsiteに掲載されている意見について事前に何も聞かされていない。

したがって、Webサイト上にかかれている、「我々が信ずるに・・・」、とか、「我々が主張せんとすることは・・・」について、Leahは現在、librebootプロジェクトを完全に支配下においている。明らかに、この人物は支配下においているプロジェクトを不適切に利用して、プロジェクトには直接関係のない個人的な意見を、「librebootコミュニティ」に存在する人間全体の意思として見せかけ・・・つまりは、その人物はLeah Roweだ。

私はLeahの幼稚な行動に呆れている。何人もの我々(librebootを保守するほどの時間のない者達)、つまり実際のlibrebootコミュニティは私の意見に同意するだろう。すなわち、Leahはlibrebootプロジェクトを主導するにあたって以下のような極めて不適切な振る舞いをしているということを。

  • プロジェクトの主導的な立場と個人的な意見を混同させていること
  • librebootの名において、「我々」と呼称することにより、個人的な意見を、コミュニティ全体の総意であるかのように詐称していること
  • 自分の意見に同意しないものに対して、幼稚にもIRCチャンネルを検閲していること
  • プロジェクトのWebサイトに無関係の個人的な意見を掲載したこと

-- Damien Zammit(CC BY-ND)

この騒動はSJWやHugh Mungusに相当するという意見が見られる。

SJW(Social Justice Warrior)は、過度のポリティカル・コレクトネス、差別是正主義者による、些細な言動の揚げ足取り行動を言う。Hugh MungusはBlack Lives Matter運動家のZarna Joshiが警察署の建設に反対する抗議で、たまたま警察署を通りがかった公聴会で証言するために来た白人の男にインタビューを試み、関心のないインタビューに苛ついた男に、「俺の名はHugh Mungus(ドデカイ)だ」と返されたことを、「ドデカイとは何だ。これはセクハラか。ドデカイとは男性器の暗喩か」などと揚げ足取りで詰め寄った炎上騒動のことをいう。

そもそも、特定の団体に属する一部の人間が差別主義者であったとして、その団体全体が差別主義であると主張するのは、LGBTの一部の人間の問題を取り上げてLGBT全体が問題であるとするLGBTフォビアと何ら変わりない行動である。

そういうわけで、筆者はポップコーンの用意にとりかかる次第である。

2016-09-15

Five TenのQuantum Blueを買った

前回、クライミングシューズとしてAndrea Boldriniのアパッチライトを買った。この半年ほどは、アパッチライトだけを履いて登っていた。

アパッチライトは平凡な靴だった。あえて特徴を上げれば、とても足入れがしやすく、長時間履ける靴だということぐらいだろうか。ソールは固めで、当然ながら摩擦は劣る。ではその分、丈夫かというと、それも疑問だ。ヒール部分は完全に剛性がなく、ヒールをかけると足が痛む。

そして、そろそろつま先が傷んできたので、新しいクライミングシューズを買おうと思い立った。見ると、ファイブテンから比較的新しい靴が出ている。Quantum Blueという靴で、ファイブテンにしては珍しく幅広の靴だ。しかもレースだ。これならばファイブテンは足型が合わなくて諦めていた私の足でも入るのではないかと試着してみたところ、問題なく履くことができたので購入した。

さて、クライミングシューズとしてのQuantum Blueは、これまた平凡な靴だ。レースは珍しいし、ファイブテンにしては幅広の形なので、長時間快適に履くことができる。ファイブテンの靴は初めてなので、ファイブテン特有のソールも初めてだ。ソールは柔らかめではあるがVibram Gripよりは硬い感じがあるものの、摩擦はよさそうだ。

現時点では、この靴はなかなか良いと思っているものの、実際の感想は、やはり数カ月は使わないとわからないだろう。

2016-09-12

C++標準化委員会の文書: P0411R0-P0417R0

P0411R0: Separating Library Requirements and Preconditions

現在、標準ライブラリの関数にはrequires paragraphに関数の呼び出し元が満たすべき条件が記述されている。これは、17.6.4.11で規定されている。「requires paragraphに記述されたpreconditionsに違反すると挙動は未定義」とされている。

ところで、現在のrequires paragraphには、preconditionsの他にも、様々な制約が書かれている。中にはコンパイル時にメタプログラミングでチェックできるものもあり、実際にメタプログラミングでコンパイル時チェックをしてコンパイル時エラーを出すことを規定している部分もある。これらが全て未定義の挙動であるとすると、せっかくコンパイル時チェックをしているのに意味がない。

そこで、requires paragraphを、requires paragraphと、preconditions paragraphに分割する。requiresに違反した場合はill-formedとなる。preconditionsに違反した場合は、未定義の挙動となる。

文書はすでに、標準ライブラリのすべてのrequiresに対する文面案を完備している。たいへん地道な作業が行われたのだろう。

[PDF] P0413R0:

Parallerism TSが規格入りしたが、すでにTSの方では修正されている識別子の変更は、自動的に反映されずに、明示的にCDに対して変更を提案しなければならない。その変更のための提案文書。

P0414R0: Merging shared_ptr changes from Library Fundamentals to C++17

Library Fundamentals TSを規格にマージするにあたって、shared_ptr周りの変更案が現行の規格の文面とコンフリクトを起こしたため変更を保留されていた。現行の文面に対する変更案を作りなおして提案。

[PDF] P0416R0: Operator Dot (R3)

operator .の改定案。指摘された問題を認識して修正したようだが、文面案がない。文面案がないと評価しようがない。

P0417R0: ISO 10646:2014

C++標準規格が参照しているUCS規格であるISO/IEC 10646-1:1993をISO/IEC 10646:2014に変更する提案。

ISO/IEC 10646は、Information technology — Universal Coded Character Set (UCS)で、いわゆるUnicodeとそのエンコード方式(ISO規格ではUnicodeという名称は使っていない)。1993年のUCS規格では、まだエンコード規格はUCS-2とかUCS-4と呼ばれていて、UTF-8, UTF-16, UTF-32という用語は存在しなかった。そのため、C++規格は参照先の規格で定義されていない用語をこれまで使っていたことになる。

ドワンゴ広告

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

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

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

C++標準化委員会の文書: P0400R0-P0409R0

P0400R0: P0400R0 2016-06-25

C++17では式の評価順序が、関数の引数を除いて固定された。関数の引数の順序は未だに不定だが、その部分の文面がわかりにくく書かれているため、書き直しの提案。

P0401R0: Extensions to the Allocator interface

アロケーターに確保したストレージの実サイズも返すallocate関数の追加の提案。

アロケーターの実装として、32バイトとか64バイトなどの固定サイズごとのチャンク単位でメモリを管理して、要求されたサイズに最も近いチャンクサイズに切り上げてメモリを返す方法がある。

そのような戦略を取るアロケーターに対して、例えばvectorが36バイトのメモリを要求して、実際には切り上げて64バイトが割り当てられたとする。その後、vectorは52バイトのメモリを要求する。アロケーターは64バイトの別のチャンクメモリを返す。vectorは既存の36バイト要求に対して割り当てられた64バイトのメモリの値を、新しい52バイト要求に対して割り当てられた64バイトのメモリにコピーして、古い方の64バイトのメモリを開放する。

この時点で気がつくように、vectorのこの操作は、メモリに実際に割り当てられるサイズを知っていれば、本来不要であり、除去できるものである。しかし、現行のアロケーターには、メモリの実サイズを得る方法がない。

そこで、以下のような関数を新たに追加する。

pointer allocate(size_type n, size_type& result, const_void_pointer hint = {});

resultに対して、実際のサイズが書き込まれる。

これは純粋にアロケーターだけでの対応方法だ。reallloc風の機能には、コンテナー側での対応も必要になるので、この提案では取り扱わないとしている。

P0404R0: Matching Types: 404 Syntax Not found

文書番号がHTTP標準レスポンスコード404と偶然に同じで、文書のタイトルにも404へのリファレンスがある。

constexpr ifが追加された今、C++に必要なのは型パターンマッチだ。ということで極めて不自然な文法で型に対するパターンマッチを提案している。文法が既存のC++からみると違和感がありすぎる。

これはダメだ。

P0405R0: Wording for Networking TS changes discussed in Kona

ネットワークTS、ネットワークライブラリに対する細かい修正案

[PDF] P0407R0:Allocator-aware basic stringbuf

stringbufに近代的なアロケーターサポートを追加する提案。

stringbufはC++の歴史の上でもかなり早い段階で追加されたライブラリのため、近代的な設計になっていない。アロケーターはテンプレートパラメーターとしてしか渡すことができず、オブジェクトとして渡すことができない。このため、stringbufのオブジェクトごとのアロケーター指定ができない。

この提案では、basic_stringと同等のアロケーターサポートを追加する。

iostreamの設計は根本的に失敗なので、iostreamを改良する労力は無駄であると思う。

[PDF] P0408R0: Efficient Access to basic stringbuf's Buffer

stringbufとstringstreamには、内部のバッファーをコピーせずに参照する方法が一切ない。そのため、本来不要なコピーが発生していた。

std::stringstream ss ;
// コピーが発生する
ss << "hello" ;

std::string result ;
// コピーが発生する
ss >> result ;

そのため、この提案ではコピーを回避してstringbufと、stringbufを使うstringstreamの内部バッファーを直接アクセスする方法を提供する。

まず、コンストラクターにbasic_stringへのrvalueリファレンスを取るオーバーロードが追加される。これによって、初期値をコピーなしで与えることができる。

std::string const initial_value("hello") ;

// ムーブされる
std::stringstream ss( std::move( initial_value ) ) ;

std::string const another_value("123 456 789") ;

// ムーブされる
// 後でコピーを回避して値を変えることもできる
ss.str( std::move( another_value ) ) ;


// string_viewを返す
// コピーせずにリードアクセスできる
auto view = ss.str_view() ;

// stringを返す
// コピーではなく内部バッファーがstringにムーブされる
auto str = std::move(ss).str() ;

確かに有益だが、iostreamをこれ以上付け焼き刃で改良するのに労力を咲くのはやめて、もっとまともな文字列処理ライブラリと入出力ライブラリを作るべきだ。

P0409R0: Allow lambda capture [=, this]

[=,this]を許可する提案。

lambda captureのdefault captureに=が指定された場合、後続するキャプチャーには、リファレンスキャプチャーしかかくことができない。thisはthisポインターの値キャプチャーなので、当然書くことはできない。

int x{} ;
// エラー
[=, x] { } ;

class C
{
    C()()
    {
        // エラー
        [=,this]{} ;
    }
} ;

問題は、C++17には、thisポインターの参照先、つまり*thisを値キャプチャーするための文法が入った。

[*this] { } ;

これにより、クラスへのポインターではなく、クラスオブジェクトである*thisがクロージャーオブジェクトにコピーされる。

つまり、以下のようなキャプチャーが書ける。

[=,*this]{} ;

このような記述が増えると、[=,*this]と区別して、]thisポインターをキャプチャーすることを明示するために、[=.this]と書きたくなる。これは基本的に良い作法であると思われるので、そのような記述を出来るように制限を緩和する。

ドワンゴ広告

<meta name="description" content="ここに変な文字列を突っ込みながら特定のWebサービスについて運営で参考にされるほど真面目に考察することで、運営の使っているURL先のmetaタグを読んで埋め込み表示するチャットシステムのログにシュールな雰囲気をもたらすハック">

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

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

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

2016-09-09

なぜターミナルにBを表示するのは#に比べて遅いのか

java - Why is printing "B" dramatically slower than printing "#"? - Stack Overflow

Stack Overflowに、ターミナルに、'B'を多数出力するコードは、'#'を多数出力するコードに比べて、桁違いに遅いが、なぜかという質問が上がっている。

不思議なことに、ideone.comで試すと速度に違いはないらしい。

その理由は、ターミナルがword-wrap(単語ごとの行折り返し)を行っているので、#を表示する際にはword-wrapは行う必要がないが、Bを出力した場合、後続の文字が単語を区切る文字かどうかを判定するための処理が入り遅くなるというものだった。

よくぞ答えを当てたものだ。

2016-09-08

C++標準化委員会の文書: P0390R0-P0399R0

P0390R0: ISO/IEC JTC1/SC22/WG21 p0390r0

shared_ptrにムーブ対応のキャスト関数を追加する提案。

クラスBaseと、Baseから派生するクラスDerivedがあり、Derivedのオブジェクトを指し示すshared_ptr<Base>を返す関数get_ptr()があるとする。この時、shared_ptr<Base>からshared_ptr<Derived>に安全に型変換できる。


class Base { } ;
class Derived : public Base { } ;

std::shared_ptr<Base> get_ptr() ;

std::shared_ptr<Derived> p = std::static_pointer_cast<Derived>( get_ptr() ) ;

問題は、std::static_pointer_castは、引数としてconstなlvalueリファレンスしか取らないため、shared_ptrの参照カウンターのアトミックなインクリメントとデクリメントが発生する。

そこで、static_pointer_castにrvalueリファレンスの引数を取り、ムーブに対応させる。

P0391R0: P0391R0: Introducing the term "templated entity"

templated entity(テンプレート化されたエンティティ)という用語を定義する提案。

templated entityとは、テンプレートと、テンプレートの中で宣言されたエンティティのことだ。

[PDF] P0392R0:Adapting string_view by filesystem paths

filesystemをstring_viewに対応させる提案。

P0393R3: Variant: relational operators.

どこぞの大統領候補が言いそうな題名の文書。

内容は、variantの各種比較演算子を、variantの内部の値による比較にデリゲートする提案。

P0394R4: Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling

タイトルはHotel Californiaへのリファレンス。冒頭に、歌詞の最後の部分を改変した、"You can throw any time you like, but the exceptions can never leave."と書かれている。

並列アルゴリズムに渡した要素アクセス関数が例外を投げた時は、投げられた複数の例外がstd::exception_listに格納されて返されるという仕様になっている。しかし、実行ポリシーがpar_unseqの時だけはstd::terminate()を呼び出すとなっており、一貫性がない。

これを考えるに、一律std::terminate()を呼び出すことで統一したほうがよい。そのほうが生成されるコードも簡単になるし、exception_listに持ち上がっている数々の問題への対処も不要になる。

という変更をする提案。

P0396R0: P0396R0: C++ Concepts Active Issues List (Snapshot of Revision 4)

コンセプトに対する問題集

P0397R0: C++ Standard Library Priority 1 Issues Resolved Directly In Oulu

Oulu会議で解決されたライブラリ問題の一覧

P0398R0: P0398R0: Core issue 1518: Explicit default constructors and copy-list-initialization

デフォルトコンストラクターがexplicitか、継承コンストラクターを使っているクラス型は、アグリゲートから外すよう文面を変更する提案。

厳密には意味の変更になるが、文面の解釈揺れや間違いを修正する変更。

ドワンゴ広告

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

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

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

2016-09-06

C++標準化委員会の文書: P0380R0-P0389R0

[PDF] P0380R0: A Contract Design

contract programmingの議論のたたき台になった実験的実装の紹介。属性でcontractsを指定する。

void push(queue & q)
    [[ expects: !q. full () ]] // there must be room for another element
    [[ ensures: !q.empty() ]] // q can’t be empty after adding an element
{
    // ...
    [[ assert: q.is_ok() ]]; // q’s invariant is (re)established at this point
}

contractsには、3段階の契約履行レベルを指定できる。defaultとauditとaxiomだ。defaultは最小の実行時コスト、auditは大きな実行時コストのかかる契約、axiomは人間のためのソースコード内ドキュメントと静的解析ツールのためのコンパイル時チェックのレベル


[[ expects: ...]] // 暗黙のデフォルト
[[ expects default : ... ]] //明示的なデフォルト
[[ expects audit : ... ]] // audit
[[ expects axiom : ... ]] // axiom

契約違反はプログラムの終了になる。契約違反の際の挙動も指定できる。無効、デフォルト、audit(デフォルト+audit契約チェック)

関数の宣言時に契約を記述した場合、すべての同じ関数の宣言は同一の契約を記述しなければならない。

まあ、言ってみればコア言語による高級assertだ。

P0381R0: Numeric Width

<cstdint>のジェネリック実装ライブラリの提案

<cstdint>には、int16_tやuint16_tなどといった、符号とビット長を指定した整数型があるが、この実装はジェネリックではない。ジェネリックコードから符号やビット長を指定したい。

そのために、width<T>とset_width<T, N>を提案する。

width_v<std::int16_t> ; // 16
width_v< char > ; // 少なくとも8以上
width_v< wchar_t > ; // 少なくともワイド文字以上
width_v< long long int > ; // 少なくとも64以上

set_widthは、指定した型と同じ符号で、指定したビット長以上の整数型を返す。

set_width_t< int, 8 > a ; // int8_t相当
set_width_t< unsigned, 32> b ; // uint32_t相当
set_width_t< char, 32 > c ; // 符号付きか符号なしの32bit長の整数
set_width_t< signed, 10 > d ; // 大抵の実装ではint16_t相当

charの符号は未規定なので、cの符号がどうなるかは実装に依存する。

set_widthは使いづらいように見えるが、テンプレート実引数として渡された型と互換性のある符号でビット長保証のある型を得るための設計となっている。

P0382R0: Comments on P0119: Overload sets as function arguments

P0119R1でテンプレート内で関数名からオーバーロード解決するために、関数名からクロージャーオブジェクトを合成する気嚢が定庵されているが、この機能は既存のコードにも将来のコードにも悪影響を及ぼすという反論。

確かにそうだ。

P0384R0: Core "tentatively ready" Issues

コア言語に入る予定の修正案

[PDF] P0385R0: Static reflection: Rationale, design and evolution

静的リフレクションについて、これまでの議論の経緯や推移を解説する82ページもある文書。

[PDF] P0386R2: Inline Variables

inline変数の提案。C++17のドラフトに入っている。

inline変数は、複数の翻訳単位で定義できる。定義は同一でなければならない。inline変数は、あたかもひとつの変数のオブジェクトがあるかのように振る舞う。

inline int x ;

extern宣言して、変数定義用の翻訳単位を用意する必要がなくなる。

constexpr staticデータメンバーは暗黙にinlineとなる。名前空間スコープのconstexpr変数は暗黙にinlineにはならない。

P0387R0: P0387R0: Memory Model Issues for Concurrent Data Structures

現在、Concurrent queueやdistributed counterといった、並列データ構造の提案が上がっている。並列データ構造のメモリーモデルはどうすればいいのか。

  1. memory_orderを引数に渡して指定する
  2. まともなコードでは観測不可能にする
  3. 非決定性であると規定する

1.について、並列データ構造をロックフリーにすることにパフォーマンス上の意味がないのであれば、memory_orderを指定する必要はない。2.について、現在、非現実的なコードで無理矢理にメモリーモデルの違いを観測することができるが、規格はそのような非現実的なコードについてはまともに取り合っていない。3.について、現在、規格はtry_lockを非決定性であるとしている。

P0388R0: Proposal: conversions to arrays of unknown bound

Core issue 393を解決する上で、関数の引数は要素数が未束縛の配列へのリファレンス型を使えるようになった。

void f( int (&)[] ) ;

問題は、要素数が束縛された配列型を、要素数が未束縛の配列へのリファレンス型で束縛することができないということだ。


int main()
{
    int a[1] ;

    int (&ref)[] = a ; // エラー
    f( a ) ; // エラー
}

このような制限は不要であるから緩和する提案。

現在、Clangは実装している。GCCはまだ実装していない。そのため、互換性の問題もない。

P0389R0: Proposal: template keyword in unqualified-ids

unqualifed-idがtemplate-idであることを示すためのtemplateキーワードを記述できるようにする提案。

メンバーテンプレートがテンプレートであることを示すために、templateキーワードが使える。

template < typename T >
void f()
{
    T::f<int>() ; // エラー、fはtemplate-idとはみなされない。<は演算子

    T::template f<int>() ; // OK、fはtemplate-idとみなす
}

同様のことを、名前空間スコープ内のtemplate-idに対して行いたい。そして、ADLによってname lookupされるようにしたい。

namespace N {
 struct A { };
 template <typename T>
 T func(const A&) { return T(); }
}

void f() {
 N::A a;
 func<int>(a); // エラー、funcはtemplate-idではない。
}

このコードがill-formedである直接の理由は、名前funcが見つからないためではない。ADLによって名前funcは見つかるのだが、template-idであるとみなされず、<は大小比較演算子であるとみなされてしまう。

N::func<int>と書くと、この問題は解決するのだが、それでは意味が変わってしまう。修飾名なのでADLが働かない。

そこで、非修飾名に対してtemplate-idであることを示すtemplateキーワードを記述できるようにする。その結果、以下のように書ける。

template func<int>(a) ;

一部のライブラリ作者が幸せになる機能だ。

ドワンゴ広告

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

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

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

2016-09-05

江添ボドゲ会@9月18日開催のお知らせ

以下の通り、9月18日に筆者の自宅でボドゲ会を開催します。ボードゲームに興味のある人はご参加ください。

江添ボドゲ会@9月18日 - connpass

2016-09-02

C++標準化委員会の文書: P0370R1-P0379R0

P0370R1: Ranges TS Design Updates Omnibus

Range TSに存在する問題を修正する提案。

P0371R1: P0371R1: Temporarily discourage memory_order_consume

タイトル通り、memory_order_consumeの利用を一時的に非推奨にする提案。

Linus Torvaldsも激怒していたように、現行のmemory_order_consumeには問題が山ほどあり、大抵の実装はその実装困難性からmemory_order_aquireと同じにしているのみならず、至るところでkill_dependencyや[[carries_dependency]]を明示的に使わなければならないので、不便なことこの上ない。

そこで、memory_order_consumeは改良が必要だが、それには時間がかかるので、それまでの間非推奨扱いにする。

P0372R0: P0372R0 - A type for utf-8 data

UTF-8の1単位を表現するchar8_t型の提案。

char8_tからcharへの標準変換はできるが、逆はできない。

C++11のときにchar8_tが必要だと訴えたら、charは古典的にバイト列を表現する型なので十分だ。char型以外の型があるのは混乱する。などと理解のないUnicodeの世界に生きていない名だたる委員達から散々に批判された。その委員達も、今では、「やっぱりchar8_tがないのは失敗だったなぁ」とぼやいている。それ見たことか。

[PDF] P0373R0: Proposal of File Literals

ファイルリテラルの提案。ファイルパスを指定すると、コンパイル時にそのファイルの内容が値として得られるリテラル。

例えば、hello.txtの中身が、

Hello,World

であるとすると

int main()
{
    // "Hello,World"と出力
    std::cout << tF"hello.txt" ;
}

プログラム中にデータを埋め込む需要がある。データを埋め込む方法は、C++の文法に従う方法や、実装依存の方法まで、様々ある。データはデータとしてファイルで独立させたい場合、実装依存の移植性のない方法を使わなければならない。

ファイルリテラルは、ファイルパスで指定されたファイルのデータを、コンパイル時に値として返す。その文法は

F"file pah"

を基本としてFの前にfile-encoding-prefixがつく。file-encoding-prefixは、b, t,L, u8, u, Uのいずれかだ。

bは、ファイルをバイナリデータとして扱う。ファイルリテラルの値は、ファイルをバイナリモードで開いて読み取ったものと同じ値で、その型はunsigned charの配列となる。null終端はされない。

例えば、hello.txtの中身が、UTF-8でエンコードされた

hello

であり、改行はないものとする。

auto data = bF"hello.txt" ;

この例では、dataの型はunsigned char [5]であり、その値は、{u8'h',u8'e',u8'l',u8'l',u8'o'}となる。null終端はされない。

tは、通常の文字列エンコードで、L,u8,u,Uはそれぞれの文字列のエンコードだ。この場合、コンパイル時にファイルの中身が対応する文字列のエンコードであると仮定され、生文字列リテラルに書かれたものと同じ扱いになる。

auto text = u8F"hello.txt" ;

これは、以下のコードと同じ意味だ。


auto text = u8R"(hello)" ;

ユーザー定義リテラルは、現状では問題があるので、将来の拡張案として保留するそうだ。

なるほど、需要はあると思う。

[PDF] P0374R0: Stream parallelism patterns

ストリーム並列パターンをサポートするための提案。Parallerism TSで、ある程度有名な並列アルゴリズムはあるが、ストリーム並列パターンへの対応が欠けているという。

P0375R0:[[exhaustive]] attribute for enums

enum名に対する[[eustive]属性の提案

以下のようなenumがあるとして、

enum color 
{
    red, green, blue  
} ;

コンパイラーは、以下のようなコードに警告を発することがある。

switch ( color c = get_color() ; c )
{
    case red :
        break ;
    case green :
        break ;
    case blue :
        break ;
}

なぜか。unscoped enumはenumerators以外の値になることもなるからだ。

そこで、この提案はコンパイラーの警告を抑制するための属性、[[exhaustive]]を提案している。

enum [[exhaustive]] color 
{
    red, green, blue  
} ;

これで、enumeratorsのみが使われることを明示的に指定するので警告を抑制できる。

素直にscoped enumを使えばいいと思うのだが。

P0376R0: A Single Generalization of std::invoke, std::apply, and std::visit

std::invoke, std::apply, std::visitを一般化したtupleの展開までできるstd::callの提案。

便利だが使うのが面倒な気がする。汎用性のために利用方法が面倒になっているし、ドキュメンを参照せずに記述するのが難しいほど煩雑だ。

P0377R0: std::integral_constant with a Deduced Value Type

C++17の非型テンプレートの推定機能を使ったstd::integral_constantのエイリアステンプレート、std::constantの提案。

実装

template <auto V>
using constant = integral_constant<decltype(V), V>;

使い方

using answer = std::constant<42> ;

便利だ。悪影響もない。入るべきだ。

P0379R0: Why a joining thread from P0206 is a Bad Idea

デストラクターが自動的にjoin()を呼ぶスレッド、std::joining_threadが提案されているが、これは問題があるとする文書。

例えば、並列処理に使うスレッドを管理するために、std::vector<std::thread>に対してpush_backでstd::threadのオブジェクトを追加していくようなコードでは、push_backが失敗して例外が投げられると、std::threadのオブジェクトのデストラクターが走り、まだjoinableなのでstd::terminateが呼ばれる。

問題は、並列処理の最初ですべてのスレッドがお互いに最初に必要な処理が終わるのをロックで待っている場合、push_backが失敗しても処理が終わらないのでロックが解放されず、デッドロックになる。

デッドロックは未定義だが、std::terminateが呼び出されるのは十分に意味が定義されている。失敗するなら速いほうがいい。デッドロックよりはterminateが呼び出されるほうがいい。

ドワンゴ広告

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

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

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

2016-08-31

C++標準化委員会の文書: P0360R0-P0360R9

[PDF] P0360R0:SG14: Low Latency Meeting Minutes 2016/02/17-2015/05/25

SG14 低レイテンシー会議の議事録

[死んで欲しいPDF] P0361R0: Invoking Algorithms asynchronously

Parallelism TSで提案されたアルゴリズムの並列実行を拡張する形で、アルゴリズムを非同期実行を追加する提案。

従来のシーケンシャル実行のアルゴリズムの使い方は以下で、

Container c ;

sort( begin(c), end(c) ) ;

Parallelism TSによって、以下のようにかける。

Container c ;


// シーケンシャル実行
sort( seq, begin(c), end(c) ) ;
// 並列実行
sort( par, begin(c), end(c) ) ;
// 並列ベクトル実行
sort( par_vec, begin(c), end(c) ) ;

この提案は、Parallelism TSを拡張する形で、アルゴリズムの非同期実行版を追加する。

Container c ;


// シーケンシャル非同期実行
auto f = sort( seq(task), begin(c), end(c) ) ;
f.get() ;

// 並列非同期実行
auto f = sort( par(task), begin(c), end(c) ) ;
f.get() ;

// 並列ベクトル非同期実行
auto f = sort( par_vec(task), begin(c), end(c) ) ;
f.get() ;

非同期実行版の選択は、実行ポリシーのoperator ()にtaskシングルトンを与えることで行える。非同期実行版のアルゴリズムは、通常の戻り値の型をTとした場合、future<T>を戻り値の型として返す。

戻り値に対してメンバー関数getを呼び出すと、非同期処理の完了に同期する。

なかなかいい提案だ。自然に拡張できている。

例えば以下のようなコードがあったとして

template<typenameBiIter, typenamePred>
pair<BiIter, BiIter>
gather( BiIterf, BiIterl, BiIterp, Predpred )
{
    BiIter it1 = stable_partition( f, p, not1(pred) );
    BiIter it2 = stable_partition( p, l, pred );
    return make_pair(it1,it2);
}

これを非同期実行版に書き換えると、以下のようになる。


template<typenameBiIter,typenamePred>
future<pair<BiIter,BiIter>>
gather_async(BiIterf,BiIterl,BiIterp,Predpred)
{
    future<BiIter>f1=stable_partition(par(task),f,p,not1(pred));
    future<BiIter>f2=stable_partition(par(task),p,l,pred);
    return when_all(f1,f2).then(
        [](tuple<future<BiIter>,future<BiIter>>p)
        { return make_pair(get<0>(p).get(),get<1>(p).get());}
    );
}

これはわかりにくいが、現在提案中のコルーチンを使えば、


return make_pair( co_await f1, co_await f2);

こうできる。

[PDF] P0362R0: Towards support for Heterogeneous Devices in C++ (Concurrency aspects)

SIMDやGPGPUのようなHeterogeneousなデバイスを利用するには、現在のところOpenMPやOpenCLのように、C++ではないプロプライエタリな言語を用いている。C++はこのようなデバイスをサポートする力があり、プロプライエタリな言語を使わずに標準規格で定められた言語のみを使って移植性の高いプログラミングできるのは価値が高い。

ホストCPUと、Heterogeneousなデバイスを、単一のC++のソースファイルで利用したい。OpenCLのように分離されている場合、型システムなどのエラーチェックが行えない。

この提案では、KhronosのSYCLを元に、デバイスをサポートする方法について考察している。文書中でサポートするにあたって興味深い問題がふたつある。

lambda式のABI問題。

デバイスで実行するコードを渡すのには、lambda式が最も都合がよい。ただし、lambda式のABIは規格で定められておらず、複数のC++コンパイラーを使う場合に問題になる。

lambda式は規格で名前が規定されていないので、名前マングリングが実装ごとに異なる。lambda式がキャプチャーした変数に対する、クロージャーオブジェクト内でのデータメンバーのレイアウトも規格で規定されていないので、実装ごとに異なる。

このために、コア言語で規定するか、静的リフレクションが必要だとしている。

非フラットなアドレス空間の問題

CPUはメモリに対してフラットなアドレス空間を持っている。ところが、GPUのメモリはフラットではなく、特性の異なる複数のメモリがあり、アドレス空間も複数ある。どうやってC++でサポートすればよいのか。

コア言語でアドレス空間を型システムに含める方法。アドレス空間を表現するクラスライブラリを経由してアクセスする方法。非効率的だがフラットなアドレス空間に見せかける方法などが考察されている。

[PDF] P0363R0: Towards support for Heterogeneous Devices in C++ (Language aspects)

HeterogeneousなデバイスをC++でサポートする際のlambda式のABI問題について少し深く掘り下げているが、基本的に内容はP0362R0からそれほど変わっていない。

[PDF] P0364R0: Report on Exception Handling Lite (Disappointment) from SG14

ゲーム、組み込み、金融分野が低レイテンシーについて議論するSG14から、例外処理の報告書。

例外にはオーバーヘッドがある。プログラムが実行中に例外を投げないとしても、依然としてオーバーヘッドがある。

例外のオーバーヘッドは確かに存在するのだが、現実的なソフトウェアにおけるコストが計測されたことは一度もない。このために、ソースコードが入手できるQuakeなどのエラー処理を例外を使うものに書き換えて計測する実験が行われてほしい。

ともかく、例外による予測できない処理時間の増加の可能性を避けるために、ゲームをコンパイルするときは、慣習的に例外は無効化されている。このために、例外を使わない設計のEASTLのようなものが開発されている。例外が使えないので、多くのC++ライブラリがゲーム業界では使えない。これによりC++利用者は分断され、C++の発展によろしくない。

文書は、SwiftやRustにおける例外は既存の言語の問題を認識したうえで改良がなされているとして、比較している。例外を外に投げる関数を呼び出すには、明示的な文法が必要となる。C++の例外をそのようにするのは利益が大きいが、何十年もの移行期間が必要だ。

また、組み込み業界からは、例外なき例外(exceptionless exception handling)という要望が出ている。これは、例外によるstack unwindingは行う者の、例外オブジェクトは扱わないというものだ。

例外オブジェクトが存在すると、そのオブジェクトのためのストレージを確保しなければならない。例外ハンドラーでは、オブジェクトの実行時に型に対して派生関係を比較するコードが必要だ。これは組み込みでは支払うことができないコストである。

[PDF] P0365R0: Report on SG14, a year later and future directions

SG14の設立経緯と注目している提案と将来性についての報告書。

SG14は、ゲーム、金融、組み込みの業界人がC++の低レイテンシーについて議論するために設立された。

その発端は、2014年のCPPCONで、筆者であるMichael Wongがパネルを務める議論において、カナダのゲーム会社の人間からC++をゲーム対応を改良することについて質問を受けたのがきっかけだ。

SG14は、市場初めて、ゲーム業界がその名前を名乗って業界を代表してC++に意見を表明する場所になった。というのも、C++標準化委員会は定期的に会議に参加して、会社、団体を代表して意見を表明し、提案し、議論し、コンセンサスを持ち帰って伝える役目を果たす人間が必要なのだが、ゲーム業界は厳しい納期に追われているために、そのような活動ができなかった。

SG14の目的は、制約のあるリソース、リアルタイムグラフィック、低レイテンシー、といった、ゲーム開発、金融、組み込みによくある要求の追求だ。

文書では、現在までにSG14が提案した文書を示している。

[PDF] P0366R0: Extending the Transactional Memory Technical Specification with an in_transaction Statement

トランザクションメモリーにトランザクション中かどうかを判定する機能を追加する提案。

トランザクショナルメモリーではトランザクションメモリーによる実行ができる関数とできない関数を型システムで区別している。transaction_safeな関数からtransaction-unsafeな関数を呼び出すことはできないし、transaction-unsafeな処理を行うこともできない。

問題は、ある関数が、トランザクション安全な実装をされているが、トランザクションの外で実行されたならば、もっと効率のいい実装ができる場合がある。このような実装を許可するために、トランザクションを実行中かどうかで実行時に条件分岐する機能がほしい。

この機能をどのように提供するかについて、提案は3つの案を示している。

ひとつ目の案はコア言語によるものだ。

何らかのキーワード(例えばin_transaction)を使う。

void* memcpy(void* dest, void* src, size_t n) transaction_safe {
    in_transaction {
        return memcpy_safe(dest, src, n);
    } else {
        return memcpy_asm(dest, src, n);
    }
}

in_transaction文のelseに続く文では、transaction-unsafeなコードを記述できるというものだ。

ふたつ目の案は、ライブラリによるものだ。

std::in_transaction()のようなboolを返す関数を使う。そして、falseが返った時に評価されるブランチでは、transaction-unsafeなコードを記述できる。


void* memcpy(void* dest, void* src, size_t n) transaction_safe {
    if (std::in_transaction()) {
        return memcpy_safe(dest, src, n);
    } else {
        return memcpy_asm(dest, src, n);
    }
}

3つめの案は、トランザクション実行の判定字体はふたつ目の案と同じくライブラリによるものだが、transaction-unsafeなコードを実行するには、コア言語に頼る。何らかのキーワード(例えばnot_in_transaction)で文を囲むことによって、transaction-unsafeなコードを記述できる。 


void* memcpy(void* dest, void* src, size_t n) transaction_safe {
    if (std::in_transaction()) {
        return memcpy_safe(dest, src, n);
    } else {
        not_in_transaction { return memcpy_asm(dest, src, n); }
    }
}

ふたつ目の案が最も良いように思われる。

[PDF] P0367R0: a C++ standard library class to qualify data accesses

汎用的なアクセッサーライブラリの提案。アクセッサーはラッパークラスとして提供される。

int x = 0 ;
auto ax = std::make_accessor< ... > ( x ) ;

// 元の型と同じように使える。
ax = 0 ;
int r = ax ;

このアクセッサーを通して、様々なアクセス方法の指定が行える。

例えば、1TBものdouble型の配列を初期化するとしよう。このような巨大な配列に対して先頭から最後まで値を書き込んでいく場合、わざわざそのストレージの極一部をキャッシュするのは無駄である。そこで、アクセスは一時的なものではないと指定することで、キャッシュを行わせないヒントを与えることができる。

// 1 TBもの配列
double a [2 < <37];
auto ac = make_accessor < non_temporal , write >( a ) ;
// 先頭から最後まで、42で始まるインクリメントされる整数値で初期化
std :: iota ( std :: par_vec , ac . rbegin () , ac . rend () , 42) ;

ある関数some_io()は、とても遅いI/O処理を行うので、値を返すのに時間がかかるとする。ただし、その値は、ほとんどの場合42であるとわかっているとする。

auto result = f( same_io() ) ;

その場合、f( 42 )をまず計算しておいて、some_ioが42以外の値を返した場合、関数fを計算し直すという投機的な実行が行える。そのためのヒントを出すことができる。

auto result = f ( make_accessor < likely > { some_io () , 42 }) ;

このように、様々なデータへのアクセスに対して、アクセス方法の指定を行える。

提案されているアクセス方法は極めて多岐にわたる。具体的なアクセス方法や、特定のパターンや特定のハードウェア機能に特化したアクセスの際のヒントを指定することができる。

異なるメモリ間のアクセス、read/writeアクセス、一時的ではないアクセス(キャッシュ回避)、エイリアシング、シーケンシャルアクセス、プリフェッチ、バーストモード、パイプラインアクセス、DMA、バスタイプ、アクセス幅、アドレスモード、アドレス変換、modulo addressing、アドレスビット設定(アドレスに使わないビットを指定できる)、トランザクショナルメモリー、予測。

だいぶ野望のある提案だが、ライブラリベースではなくてattributeではダメなのだろうか。

[PDF] P0369R0: 2017-07 Toronto ISO WG21 C++ Standard Meeting information

2017年7月に開催されるトロント会議の現地情報。

ドワンゴ広告

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

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

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

2016-08-24

npm、一見無意味なパッケージを消したら1000件ものパッケージが依存するパッケージであったことが判明

npmが一見無意味に思えるfsというパッケージをSPAMとみなして削除したところ、1000件ほどのパッケージが依存するパッケージだったので、削除を取り消した。

npm, Inc. Status - "fs" unpublished and restored

今日、数分ほど、"fs"というパッケージが、ユーザーからSPAMであるという報告を受けて、レジストリから非公開にされた。これは現在復旧されている。これは私(@seldo)による人為的なミスである。私は非公開が安全であるかを確認する内部のガイドラインに従っていなかった。ビルドが阻害されたユーザーに謝罪する。

詳細:"fs"というパッケージは、無意味なパッケージである。これは単に"I am fs"をログに残して終了する。このパッケージが何らかのモジュールの依存に含まれるべき理由は一切ない。しかし、1000件ほどのパッケージが、誤って"fs"に依存している。おそらく、"fs"という組み込みのnodeモジュールを使おうとしているのだろう。この理由により、我々は同モジュールを非公開ではなく、ガイドラインに従って、deprecated扱いにした。

もし、既存のモジュールが"fs"に依存しているのであれば、安全に消すことができる。実際、消すべきである。仮に消さなかったとしても、今後も問題なく動作はする。

npmやnodejsが悪いのか、nodejs界隈のユーザー層が悪いのか判断に苦しむが、いずれにせよnode.jsはクソであることがわかる。

2016-08-23

C++17ドラフトのiostreamに入った変更点

C++17のドラフトには、現在までに、iostreamへの変更点として、以下のような変更が加えられている。

P0004R1.HTML#0: Remove Deprecated iostreams aliases

C++98の時点でdeprecated扱いだった一部のメンバーが、とうとう削除された。最初の正式なC++規格の時点ですでにdeprecated扱いだったライブラリが、ようやく削除されたことになる。

ios_baseからは、以下のメンバーが削除された。

class ios_base {
       public:
         typedef T1 io_state;
         typedef T2 open_mode;
         typedef T3 seek_dir;
         typedef implementation-defined streamoff;
         typedef implementation-defined streampos;
       };

basic_streambufからは、stosscが削除された。これは以下のように実装できる。

       template<class charT, class traits = char_traits<charT> >
       class basic_streambuf {
       public:
         void stossc() { sbumpc() ; }
       };

その効果は、ストリームの場所を一つすすめるというものだ。

他にも、実装が自明すぎて意味のないメンバー、重複するメンバーがいくつか削除された。たとえば、basic_iosからはclear。basic_streambufからはpubseekoff, pubseekpos。basic_filebuf/basic_ifstream/basic_ofstreamからはchar const *を引数に取るopenが削除された。

N3654: "quoted" proposal

iostreamにquotedマニピュレーターが入った。サンプルコードを引用すると以下の通り。

std::stringstream ss;
std::string original = "foolish me";
std::string round_trip;

ss << original;
ss >> round_trip;

std::cout << original;   // outputs: foolish me
std::cout << round_trip; // outputs: foolish

assert(original == round_trip); // assert will fire

iostreamでは空白文字で入力が区切られてしまうので、空白を含む文字列を入力した良い場合に問題になる。これに対処するために、デリミタ文字にはバックスラッシュを付与して出力し、入力にあたってはバックスラッシュを取り除く処理をする、quoted manipulatorを追加する。これにより、以下のようにかける。

std::stringstream ss;
std::string original = "foolish me";
std::string round_trip;

ss << quoted(original);
ss >> quoted(round_trip);

std::cout << original;     // outputs: foolish me
std::cout << round_trip;   // outputs: foolish me

assert(original == round_trip); // assert will not fire

ドワンゴ広告

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

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

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

公益財団法人日本生産性本部のヨーゼフ・ゲッベルスが平成28年度の新入社員のタイプは「ドローン型」であるとの報告書を発表した

世界に冠たる優れた人種であるアーリア人の中でもナチ党の国民啓蒙宣伝大臣であるパウル・ヨーゼフ・ゲッベルスは、平成28年度の極東の新入社員(極東における同年に学位を得て同時に雇用契約を結ぶ労働者の謂)は、ドローン型であるとの報告書を発表した。

公益財団法人日本生産性本部の「職業のあり方研究会」(座長 ライズコーポレーション株式会社 代表取締役 岩間 夏樹)は、平成28年度の新入社員の特徴をまとめた。「職業のあり方研究会」は、若年者の就労支援や教育の専門家などで構成され、多くの企業や学校等の就職・採用関係者の協力を得ながら、新入社員の特徴や就職・採用環境の動向などについて調査研究を行っている。

公益財団法人日本生産性本部 - 平成28年度 新入社員のタイプは「ドローン型」

ドローン型というのはよくわからない表現である。座長 ライズコーポレーション株式会社 代表取締役の岩間 夏樹なる人物がまとめたとされているが、報告書を調べてみたところ、実際に文章を執筆したのは別の人物らしい。

報告書はPDFフォーマットで公開されている。

http://activity.jpc-net.jp/detail/lrw/activity001472/attached.pdf

本当の作者名を得るために、そのPDFのinfo情報をみてみると、


$ wget http://activity.jpc-net.jp/detail/lrw/activity001472/attached.pdf
$ pdfinfo attachd.pdf
Title:          プレスリリーステンプレート
Subject:        プレスリリース虎の巻
Author:         Paul Joseph Goebbels
Creator:        Microsoft® Word 2010
Producer:       Microsoft® Word 2010
CreationDate:   Thu Mar 24 10:53:49 2016
ModDate:        Thu Mar 24 10:53:49 2016
Tagged:         yes
UserProperties: no
Suspects:       no
Form:           none
JavaScript:     no
Pages:          3
Encrypted:      no
Page size:      595.32 x 841.92 pts (A4)
Page rot:       0
File size:      814714 bytes
Optimized:      no
PDF version:    1.5

このPDFの作者はパウル・ヨーゼフ・ゲッベルスであることがわかる。奇しくもドイツ、ナチ党の国民啓蒙宣伝大臣と同姓同名である。偶然だろうか。

ヨーゼフ・ゲッベルス - Wikipedia

とはいっても、歴史上有名な方のパウル・ヨーゼフ・ゲッベルスは1945年5月1日に自殺したはずである。仮に生きていたとしても114歳になっている計算だ。

いかにプロパガンダの天才と称されるゲッベルスであっても、極東の事情はわからなかったので、やはりその報告書も精彩を欠くものと見える。

2016-08-15

C++標準化委員会の文書: P0350R0-P0359R0

[PDF] P0350R0: Integrating datapar with parallel algorithms and executors

P0214で提案されているベクトル型、dataparを並列アルゴリズムに対応させて、専用の実行ポリシーを追加する提案。そこまで明示的にする必要があるのは本末転倒な気がする。

[PDF] P0352R0: Smart References through Delegation: An Alternative to N4477's Operator Dot

operator .をオーバーロードすることによりスマートリファレンスを実装可能にしようと言うのがN4477の提案だが、operator .の現在の提案は極めてややこしい。オーバーロード解決のルールにめちゃくちゃ複雑な新ルールを導入するものだ。

この提案では、派生機能を拡張した移譲機能を追加することにより、スマートリファレンスを実装可能にしようと言うものだ。

例えば、以下のように

template < typename T >
class shared_ref : public using T
{
    std::shared_ptr<T> ptr ;
    operator T &() { return *ptr ; }

public :
    // auto x = shared_ref<T>{}のxの型はTになる
    using auto = T ;
    // sizeofの結果はsizeof(T)の結果になる。、
    using sizeof = T ; 

    explicit shared_ref( shared_ptr<T> ptr ) : ptr(ptr)
    { }

    // X::funcをhidingする。
    void func() { }
} ;

このように、既存の派生と継承の上に作ることで、すでによく知られたルールを適用できる。文法はXから派生しているようだが、shared_refのオブジェクトはXのサブオブジェクトを持たない。Xへのリファレンスは、変換関数で取得できるようにしておくことで、shared_refをXとして使いたい場合には、変換関数が使われる。

この拡張によって、スマートリファレンスを実装できるほか、pimplイディオムなども、より自然に実装できる。

これはいい提案だ。operator .のオーバーロードよりはるかに気が利いている。派生と継承のルールはすでによく知られているのでわかりやすい。

入るべきだ。

P0353R0: Unicode Encoding conversions

UTF-8/UTF-16/UTF-32の間の相互変換ライブラリの提案。現在でもC++標準ライブラリで可能ではあるが、極めてクソなライブラリしかない。

using std::literals ;
auto u8str = u8"hello,world"s ;
auto u16str = std::to_u16string( u8str ) ;
auto u32str = std::to_u32string( u8str ) ;
u8str = std::to_u8string( u32str ) ;

UTF-8文字型にはcharではなくて独自の型がほしい。

[PDF] P0354R0: default == is >, default < is < so

P0221で提案されているデフォルトの大小比較演算子に対して、デフォルトの大小比較演算子は有害だと主張する文書。

クラスに対して、デフォルトの==と!=を生成するのはわかる。しかし、<はわからない。多くのクラスは大小比較可能ではない。大小比較がデフォルトで生成されるようになった場合、筆者はコーディング規約でデフォルトでオプトアウトするように支持し、そのためにマクロを使うことも吝かではない。そのような機能はデフォルトで有効にすべきではない。

その上で、文書はデフォルトの大小比較演算子について、以下のいずれかを取るべきだとしている。

  1. 採用しない
  2. デフォルトでオプトインにして、明示的な利用宣言を必要とする
  3. std::orderingのようなカスタマイゼーションポイントを提供して、特殊化することでオプトインにする
  4. 新しい演算子を追加する

文書は、採用しないことが最も望ましく、オプトインもカスタマイゼーションポイントや新しい演算子で行われるべきだと主張している。

P0355R0: Extending to Calendars and Time Zones

にグレゴリオ暦を追加する提案

int main()
{
    using namespace std::chrono_literals ;

    auto date = 2016y/8/10 ;
    std::cout << date ;
}

まあ、ある程度便利だ。日付、曜日、タイムゾーン、うるう秒などに対応している。

P0356R0: Simplified partial function application

std::bindに変わる単純なbindの提案。

bind_frontとbind_backは、関数オブジェクトfと、任意個の実引数を取り、関数オブジェクトを呼び出す際に、実引数の先頭か末尾に受け取った引数を付け加える。

auto front = std::bind_front( f, a, b, c ) ;
front( d, e, f ) ; // f( a,b,c,d,e,f )

auto back = std::bind_back( f, a, b, c )
back( d, e, f ) ; // f( d,e,f,a,b,c) 

std::bindと違い、引数の順序変更や、引数の無視はできないが、この機能で実需要のほとんどは満たせるとしている。

個人的には、lambda式があるのでbind自体がいらないのではないかと思う。

P0357R0: 'reference_wrapper' for incomplete types

reference_wrapperを不完全型に対して使用可能にする提案。

P0358R0: Fixes for 'not_fn'

C++17に入るnot_fnの文面に問題があり、ref-qualifierを無視してしまうので、その修正をした新しい文面案の提案。

[PDF] P0359R0: SG5: Transactional Memory (TM) Meeting Minutes 2016/02/22-2016/05/23

SG5、トランザクショナルメモリーの会議の議事録

ドワンゴ広告

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

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

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

2016-08-09

C++標準化委員会の文書: P0340R0-P0349R0

P0340R0: Making std::underlying_type SFINAE-friendly

underlying_typeに対して非enum型を渡した時にクラスが定義されるように変更することで、SFINAEフレンドリーにする提案。

入るべきだ。

P0341R0: Leveraging parameter packs outside of templates

この提案は素晴らしい。

テンプレートパラメーターパックは素晴らしい。しかし、その利用はテンプレートに制限されている。実にもったいないことだ。パラメーターパックはもっと使われるべきだ。

そもそもパラメーターパックを、そのまま変数にしたい。

template < typename ... T >
struct X
{
    T ... t ;// 認められるべきだ。
} ;

template < typename ... T >
void f( T ... a )
{
    T ... fa(f(a)) ; // 認められるべきだ
}

パラメーターパックはテンプレートの外からでもアクセスできるべきだ。例えばi番目パラメーターパックの値を得るために、以下のようなコードが書けるべきだ。

template<typename ...T>
struct easy_tuple {
 template<typename U> easy_tuple(U &&u) : t{u}... {}
 T ...t;  // パラメーターパックをそれぞれデータメンバーとして持つ
};

template <int i, typename ...T> auto ith_argument(T && ...t) { /*i番目のパラメーターパックを返すコード*/ }
 
template<typename int i; typename ...T> auto get(easy_tuple<T...> tup) {
 return ith_argument<i>(tup....t& ...);  クラスの外側からパラメーターパックのデータメンバーアクセス
}

さて、これはほんの基本だ。本題は、パラメーターパックはテンプレートの外でも扱えるようになるべきだ。そのために、パックリテラルを追加する。

template<typename...T = <double, double> >
struct euclidean_space { /* ... */ };

パックリテラルがあるからには、パック値が存在する。例えば、以下のようなコードは、現在ill-formedである。

auto f()
{
    return { 2, "foo"} ;
}

{}で囲まれた式は何らかのリテラルのように見えるが、現在はそのような扱いを受けていない。パックリテラルが導入されれば、braced-init-listは第一級式として扱えるようになる。すなわち、型は<int, char const *>というパックとなる。z

パックを返すのは、pairやtupleで包んで返すより自然だ。

<double, double> calculateTargetCoordinates();
double distanceFromMe(double x, double y);
 
void launch() {
 if(distanceFromMe(calculateTargetCoordinates()...))
  getOuttaHere();
}

名前付きパックリテラル

<string topSong, person president, double avgTemp> someFactsAboutYear(int year) {
  if(year==1962)
    return {"Stranger On The Shore", Presidents.get("Kennedy"), 14};
}

パックリテラルはtupleよりも直感的な型リストを実現できる。

template<typename L, typename R> struct append;
 
template<typename ...Ls, typename ...Rs>
struct append< <Ls...>, <Rs...> > {
 using type = <Ls..., Rs...>;
};

パラメーターパックは型だけではなく非型も入れられるので、値リストも作れる。

template<typename theoretical, typename actual> struct accuracy;

template<double... predictions, double... measurements> 
struct accuracy< <predictions...>, <measurements...> >) { /* ... */ };

この提案は素晴らしい。パラメーターパックが第一級市民になる。夢が広がる。ぜひとも入るべきだ。

P0342R0: Timing barriers

パフォーマンスの計測は高速なコードを書くために重要だ。パフォーマンスを計測するには処理の前後で時間を取得して差分を得る。

int main()
{
    auto start = std::chrono::high_resolution_clock::now() ;
    do_something() ;
    auto end = std::chrono::high_resolution_clock::now() ;

    auto elasped = end - start ;
    auto millisec = std::chrono::duration_cast<std::chrono::milliseconds>( elasped ) ;

    std::cout << millisec.count() << std::endl ;
}

問題は、C++実装は規格上、as-ifルールにしたがって、処理をリオーダーできるということだ。そのため、C++実装はdo_something関数の呼び出しをstartとendの間からどこか別の場所に移しても、規格上全く問題ない。

このas-ifルールはとても強力で、現在、C++規格には移植性のある方法であるコード辺の処理時間の計測をする方法がない。mutexやスレッドの使用はリオーダーを妨げないし、分割コンパイルですら、プログラム全体の最適化やリンク時最適化の前では通用しない。

そこで、この文書では、std::timing_fenceというコードをそのブロックを超えてリオーダーしないフェンスを追加することを提案している。

確かに入るべきだ。

[PDF] P0343R0: Meta-programming High-Order Functions

メタプログラミングのためのライブラリを追加する提案。MetaとBoost.MPLとboost.Hanaを参考に設計されている。

meta::id

引数をそのまま返すメタ関数。いわゆるidentity。

meta::eval

typename T::typeをしてくれるメタ関数

Meta-Callables型

メタ呼び出し可能型は、ネストされたテンプレートエイリアスinvokeを持つ型である。Booste.MPLならばapplyに相当する。

struct identity
 {
 template <class T>
 using invoke = T;
 };

meta::invoke

meta-callablesのinvokeを呼び出すメタ関数

その他、様々なメタプログラミングを助けるためのライブラリがある。

P0345R0: Allowing any unsigned integral type as parameter type for literal operators

ユーザー定義リテラルの仮引数の型に任意のunsigned integer型を許可する。また、縮小変換を禁止する。

std::uint8_t operator "" _foo ( unsigned long long int x ) { return x ; }

// 縮小変換がかかるが、ユーザー定義リテラルの定義を見なければ縮小変換が起こることがわからない。
auto a = 1024_foo ;
// 縮小変換がかかることが明らかなので警告できる。
std::uint8_t b = 1024 ;

[PDF] P0346R0: A <random> Nomenclature Tweak

Uniform Random Number Generatorは誤解しやすい用語なのでUniform Random Bit Generatorに改名する。

P0347R0: P0347R0 Simplifying simple uses of <random> u

乱数ライブラリを使いやすくするラッパー、random_genrator<T>の提案

現在の乱数ライブラリは初心者には使いにくい。まずUniform Random Number Generatorのオブジェクトを作り、seedを初期化して、望みのdistributionクラスのオブジェクトを作り、URNGとdistributionの2つのオブジェクトを組み合わせて乱数を作る。

提案されているライブラリは、以下のように使える。

#include <random>
#include <iostream>
int main()
{
    std::mt19937_rng rng; // nondeterministically seeded, convenience typedef for std::random_generator<std::mt19937>
    std::cout << "Greetings from Office #" << rng.uniform(1,17) // uniform integer in [1, 17]
              << " (where we think PI = "  << rng.uniform(3.1,3.2) << ")\n\n" // uniform real in [3.1, 3.2)
              << "We " << rng.pick({"welcome",
                                    "look forward to synergizing with",
                                    "will resist",
                                    "are apathetic towards"})
                       << " our management overlords\n\n";

    std::cout << "On the 'business intelligence' test, we scored "
              << rng.variate(std::normal_distribution<>(70.0, 10.0))
              << "%\n";
}

mt19937_rngは、random_generator<mt19937>へのtypedefである。random_generatorは、テンプレート実引数て指定されたURNGのオブジェクトを作り、非決定的な方法でseedする。メンバー関数のuniform(a, b)に整数か浮動小数点数を渡すと、aからbまでの範囲の乱数が生成される。pickを使うと引数に渡したコンテナーの中の要素から一つが選ばれて返される。variateは非一様分布を渡すことができる。

同等のコードをrandom_generatorを使わずに書くと、以下のようになる。

#include <random>
#include <iostream>
int main()
{
    std::random_device rd; // assume unsigned int is 32 bits
    std::seed_seq sseq {rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()};
    std::mt19937 engine(sseq); // seeded with 256 bits of entropy from random_device

    auto strings = {"welcome",
                    "look forward to synergizing with",
                    "will resist",
                    "are apathetic towards"
                   };

    std::cout << "Greetings from Office #" << std::uniform_int_distribution<>(1,17)(engine) // uniform integer in [1, 17]
              << " (where we think PI = "  << std::uniform_real_distribution<>(3.1, 3.2)(engine) << ")\n\n" // uniform real in [3.1, 3.2)
            << "We " << *(strings.begin() + std::uniform_int_distribution<>(0, std::size(strings) - 1)(engine))
                       << " our management overlords\n\n";

    std::cout << "On the 'business intelligence' test, we scored "
              << std::normal_distribution<>(70.0, 10.0)(engine)
              << "%\n";
}

ただ、このライブラリは、uniformメンバー関数を呼び出すたびに対応するdistributionクラスのオブジェクトが作られるので、効率が悪い。このライブラリは効率と引き換えに手軽さを提供するライブラリなのでこれでいいのだとしている。

P0348R0: Validity testing issues

immediate contextによるエラーはハードエラーではないというのがSFINAEの基本となっている。では、immediate contextとは何かという問題が残っている。

この文書は、現在解釈が揺れている例をいくつか上げて、委員会はこの例に対する回答を示すべきであるとしている。

deleted定義を宣言以外の方法で参照するとill-formedであると規定されているが、別の場所では、ハードエラーにはならないと規定されている。どちらが優先されるべきなのか。ハードエラーにはならないほうがSFINAEによる利用ができて好ましい。

GCCもClangも、変数テンプレートの初期化子はimmediate contextにはならないと解釈している。

関数のデフォルト実引数の中の式はimmediate contextかどうかClangとMSVCは一貫してimmediate contextではないとするが、GCCは一貫していない。

他にもまだ問題提起はある。

[PDF] P0349R0: Assumptions about the size of datapar

P0214でdataparというベクトル型の提案をしているが、size()がコンパイル時定数になっている。しかし、世の中には可変長ベクトル型をサポートしたアーキテクチャもある。ベクトル超を可変長にするのは、将来性も見込まれている。size()をコンパイル時定数にする設計は将来の足かせになると主張する文書

ドワンゴ広告

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

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

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

2016-08-08

お気持ち表

国民、某、言さく。国民聞く、かけまくもかしこき天皇、皇位の維持につき、お気持ちを御公開遊ばされると云々。これ日本国の一大事にして、一都一道二府四十三県の貴きと賤しきとを問わず、日本国民の耳目を集むるところなり。

そもそも、天皇は日本国の象徴なり。その地位は、主権の存する日本国民の総意に基くと日本国憲法、かく言へり。天皇は国事行為のみを遊ばされ、国政に関与すること能はざるなり。これをもつてこれをみるに、天皇の皇位の進退、御意に如くに遊ばさるること能はず。就中、真の天皇の御意、公にせられること久しくなし。世にすでに発せられたる詔は、国民の総意なり。御意に非ざるなり。天皇、国政への関与を禁ぜられたるため、僅かにも国政に影響を及ぼす御意は、公にせられざるなり。

昭和天皇、千九百四十六年の一月一日に詔を発して曰く、天皇は現人神に非ずと。これをもって世は天皇は人間なりと宣言したとみなせり。畏くも天皇たりといへども、一個の人間たることはこれ明らかなり。

而して、天皇は日本国民なりや。国民某、これを知る能はざるなり。ただし、密かに思ふよう、天皇は日本国民にあらざるなり。日本国憲法より天皇は、

  1. 天皇の地位は日本国民の相違に基づく
  2. 天皇は国政に関する権能を有しない

と定義されたり。一方、日本国民は、

  • 日本国民は基本的人権を持つ
  • 日本国民は法の下に平等である。華族その他の貴族の制度は、これを認めない。
  • 日本国民はいかなる奴隷的拘束も受けない

今、試みに天皇を日本国民とす。日本国民は国政に関する機能を有する。これは天皇の定義と矛盾する。他の天皇の定義と日本国民の定義もそれぞれ矛盾するが自明のため省略。ゆえに天皇は日本国民に非ざるなり。

国民某、思ふよう、たとひ天皇は国政への参加を否定されたりといへども、一個の人間なり。人間はお気持ちを公開して可なり。お気持ちの公開は国政への関与にあらざるなり。お気持ちを国政に反映させるや否やの判断は日本国民に委ねられたり。

伏しておもんみるに、畏くもかたじけなき天皇のお気持ちを正しく流通せられること、これ重要なり。世にはびこる悪鬼外道、天皇のお気持ちをいささかの敬いの心もなくして改変すること、これ恐れあり。

ラジオは、お気持ちの流通手段として不適なり。何となれば、ラジオの発信者、お気持ちを改変する恐れこれあり。電波はいかに賎しの山賤といえども任意の周波数の発信が容易なり。

テレビは、お気持ちの流通手段として不適なり。何となれば、テレビは技術的に劣つたインターレース、技術的に劣つている上に特許汚染されたMPEG2、特許汚染されたAACを使ひ、かつ設計上の欠陥にして人道上の罪なるDRMを用ひたればなり。

天皇はお気持ちをデジタルデータに符号化するにあたって、よろしく自由なる動画符号化形式、自由なる音声符号化形式、UTF-8で符号化されたるプレインテキストを用い遊ばされたまえ。

流通は、天皇のお手元から末端の取得者までの経路がTLSで暗号化されていることが肝要なり。しかし、これとても認証局を信用せずんばあらざるなり。

幸いにして、国民某、改変を検知する算の法を知りたり。算の法の妙によりて、流通経路に不信ありとも改変の有無を検知できる神秘の法なり。

ハッシュ値は、多大なビット列を元に計算した値なり。ハッシュ値を表現するには数百ビットもあれば足る。セキュアなハッシュ関数を選択することこれ肝要なり。CRC、MD1, SHA1のごときは、既知の脆弱性があるため御避け遊ばされたまえ。天皇はよろしくSHA-2かSHA-3を御使い遊ばされるべきなり。

公開鍵暗号による電子署名は、事前に公開鍵さえ信頼できる方法で流通すれば、お気持ち発信者の秘密鍵による署名を、公開鍵所有者が検証し、お気持ちに改変がないことを検知できるものなり。天皇、よろしくGPGにて御公開鍵を御生成の上、御公開遊ばされたまえ。

国民某、思ふよう。天皇、思慮知恵、常の人にすぐと言へども、お気持ちの過ちすることこれ恐れあり。誤りは修正さるべきなり。かるがゆえに、天皇、よろしく御自らgitをお使い遊ばされて、お気持ちをバージョン管理遊ばされたまえ。

次に天皇、よろしく御自らGitHubの御アカウントを御取り遊ばされ、お気持ちレポジトリに御git push遊ばされたまえ。これにて、日本国民、もし、かたじけなくも天皇のお気持ちに誤字脱字などの誤りを発見した時は、恐れながらローカルにてお気持ちを編集させていただき、畏くもforkしたお気持ちレポジトリにgit pushしたうえで、恐れながらPull Requestなど発行させていただき、而して、天皇、かたじけなくも御自らPull Requestを叡覧あって、御マージ遊ばされたまえ。

国民某、伏して惟んみるに、天皇、御多忙につき、ハッシュ値、電子署名、中間者を介することなく配布、途中の経路をTLSで暗号化を、御自ら行い遊ばされることは煩わしからん。国民某、つらつら既存のソフトウェアを眺めるに、右のこと、電子署名以外ならば行うソフトウェアこれあり。BitTorrentプロトコルとそのクライアント、すなわちこれなり。天皇御自ら流通、ハッシュ値計算、途中の経路はTLS暗号化までは自動で行うソフトウェアなり。

国民某、また思わく、天皇、御身分を御隠し遊ばされたまま、お気持ちを御公開遊ばされたきこと、定めてこれありなん。世に、Torとて多重中継を経て匿名性を高めるソフトウェアこれあり。よろしくお使い遊ばされたまえ。

謹んで表を奉り以聞す。国民某、誠惶誠恐頓首頓首死罪死罪。

2016-08-06

アウティングは違法か?

以下のようなニュースがある。

「ゲイだ」とばらされ苦悩の末の死 学生遺族が一橋大と同級生を提訴

内容を要約するとこうだ。

同性愛者の男Aは、厳格な異性愛者の友人Bに好意を打ち明けた。Bは否定した。Bは周囲に、Aは同性愛者であることを暴露した。Aは心療内科に通院するほどの精神的苦痛を受けた。Aが籍をおく大学の相談室は、Aの相談に対して、同性愛問題を正しく把握せず、見当違いの性同一性障害を専門とする病院を紹介した。この対応にAは精神的苦痛を受けた。Aは精神的苦痛を理由として自殺した。

Aの遺族はBを訴えた。理由は、Bが周囲にAが同性愛者であることを暴露したことによる精神的苦痛は損害賠償を請求するに足るからだ。

Aの遺族は大学を訴えた。理由は、「同性愛者、うつ病、パニック発作についての知識・理解が全くなく、模擬裁判の欠席は前例がない、卒業できないかもしれない、などとプレッシャーをかけた」ことによる精神的苦痛は損害賠償を請求するに足るからだ。

Bは、「恋愛感情をうち明けられて困惑した側として、アウティングするしか逃れる方法はなく、正当な行為だった」と主張した。

大学は、「大学の対応に問題はなかった。個別の事故は防げない」と主張した。

この裁判は興味深いので、有名な判例となるはずだ。この記事では、アウティング(同性愛者であることを周囲に暴露すること)の是非について論じているが、この件は同性愛者とは切り離して考えるべきだ。というのも、

「ホモではない男がホモの男から言い寄られたので拒否したうえで、気味悪く感じ周囲に吹聴した。ホモは自殺した。」

と書けば、なるほど、ホモフォビア(ホモ恐怖症)の男による理解のない行動が悩める男を自殺に追い込んだ。悪だ。と思えるかもしれない。しかし、同性愛者という文脈から切り離すと、

「人Aは人Bから言い寄られたので拒否したうえで、気味悪く感じ周囲に吹聴した。Aは自殺した。」

となる。では、ここに別の文脈をつけてみよう。

「20代の若くて美人な女子大生が、40代でハゲでデブでキモいオッサンに言い寄られたので拒否したうえで、気味悪く感じ周囲に吹聴した。オッサンは自殺した。」

これはどうだろうか。当然の結果だろうか。それとも、ルッキズム(Lookism、人を見た目の良し悪しで判断する美貌主義)とジェロントフォビア(Gerontophobia、加齢恐怖症)の女による理解のない行動が悩める男を自殺に追い込んだ。悪だ。と思うだろうか。

文脈を取っ払うと、どちらもやっていることは同じだ。そして、現実を見ると、同性愛者の男性カップルと同じ程度には、40代の男と20代の女の年齢差カップルは存在するのではないか。もしそうであるならば、後者と前者は同じ程度に起こりうる問題であり、当然同じ判断が適用されるべきである。残念ながら、具体的な統計が見つからないので、カップルの比率は感覚でしかないのだが。

言い寄られた立場から考えると、どちらも言い寄られたことに対して不快感を持ったとしてもおかしくはない。厳格な異性愛者が同性愛者から言い寄られたら不快感を持つであろうし、20代の若い女性が40代の性的魅力のない男から言い寄られるのも不快感を持つだろう。その不快感の解消方法として、周囲に相談をすることは悪であろうか。

と考えていくと、私はこの問題の善悪を判断できかねる。納得の行く説明付きの判決が出て欲しいのだが、おそらくどちらに転ぼうとも私の常識では納得できないだろう。

大学に関しては、私は責任がないと考える。というのも、私は「無知が罪」となることはおかしいと考えているからだ。大学の相談室に同性愛に対する高度な医療知識がなかったために、間違った診療科を紹介したことは罪ではない。また、クラス替えや留学の希望に対する対応でも、同性愛が絡まない他の事例と代わりがないのであれば、特別に差別されていたとは言えない。それに、大学は学生の私的な生活に踏み入るべきではない。

Bjarne Stroustrupのプログラミング入門書の査読の感想

アスキードワンゴ編集部からBjarne StroustrupのProgramming -- Principles and Practice Using C++という本の第二版の邦訳が出版される。初版は翔泳社が出していたが、C++14に対応した改訂版の第二版の版権が空いていたので、アスキードワンゴから出すための作業をしていた。私は邦訳の査読をした。

今年になってから半年は、ずっとこの本の査読をしていた。このためにC++標準化委員会の最新の文書を把握する作業が数ヶ月ほど滞った。そして、この仕事は、私がドワンゴに入社して以来、最悪の仕事であった。ただし学びはあった。それについて書いていこうと思う。

Bjarne Stroustrupは、ご存知の通りC++の最初の設計者にして最初の実装者である。現在、Texas A&M Universityで教鞭をとっている。この本はStroustrupの講義のための教科書として書かれた。対象読者は、入学して最初のセメスターで初めてプログラミングを学ぶ学生である。

結論から言うと、この本は極めて悪く書かれている。およそ悪書の見本のような本だ。悪文の集大成といってもよい。プログラミング言語入門用としても悪い。

先に、この本の査読の仕事は、私がドワンゴに入って以来最悪の仕事だと書いたのは、この本が極めて読みづらく不必要に難解で、しかもその内容が噴飯物の間違いだらけであったからだ。学びがあったというのは、この悪書の見本を網羅している本を査読することで、「いかに本を書いてはいけないか」について実感できたからだ。かのLinus Torvaldsは言った(どこかで読んだ記憶があるのだが、出典が見当たらない)

「迷いが生じた時は、Subversionの逆をやることにした」

-- Linus Torvalds、gitを開発することにおいて

今回、この本の査読という貴重な体験ができたことで、今後私がプログラミングの参考書を執筆するときは、反面教師として逆張りを行うようにする。

さて、ここからは、Stroustrupのプログラミング入門がいかに悪書であるかを、具体的に書いていく。

本の文章量が多すぎる。

Stroustrupのプログラミング入門第二版の原書は1312ページある。邦訳も同じ程度のページ数がある。本書の担当の編集者は、「僕が担当した本のなかでも最大の記録を更新しましたね」と言った。私はこの本を鈍器と呼んでいる。理由は、人が殴り殺せるほどの重さがあるからだ。

これが、Stroustrupのプログラミング言語C++のような本であれば、どれだけ文章量が多かろうと問題はない。そういう本だからだ。しかし、これは初心者への入門書である。

本書の翻訳は、第一版と同じ翻訳者が新たに行った。翻訳の質は、概ね原書に忠実だ。一部変な翻訳を発見したし、まだ未発見の問題もあるだろうが、これだけの文章を翻訳したにしては、かなり一貫している翻訳だ。

問題は翻訳ではなく原文(英語)にあるというのも原文は極めて読みづらく関係詞(thatとかwhichとか)や接続詞(andとかorとかyetとか)で文章を遠慮無く一文一文を長大にしている上に括弧の多用(こういうやつ)で更に文章の長さを水増ししているからであって決して翻訳の質が低いからではなく概ね原文に責任がある。

文章はしばしば話が脱線する。「Aをするのは良い作法であるとされている」、「Bは悪い作法であるとされている」などの妥当ではあるが冗長な話への脱線がよくある。

そして中でもひどいのは、わざと間違ったソースコードを提示したうえで、「これが私たちの考えた最初の解法だ。しかしこれは動かない。なぜだろうか考えてみよう。一見すると動くように見える。何が間違っているのだろうか。ひょっとしてAだろうか。いや違う。Bだろうか。そうでもない。実は・・・」といった自問自答の文章が延々と続くものだ。

この本は、筆者と読者をひっくるめて「私たち」と表現している。これはこの本の独特の表記法であり、わざわざ、「なぜ私たちは私たちという表記を採用するに至ったか」という説明まで書いてある。

xkcd: Manuals

そこまで書いている以上、翻訳でも「私たち」という表現を維持しなければならないのは当然の話だ。実際維持しているが、極めて日本語として不自然な文章になっている。

このことから、私たちはとても重大な教訓を得た。

教訓1: 文章は簡潔にすべし

人間が読める文の量と速度は有限である。重要なのはプログラミングの仕方を教育することであって、文章の量ではない。

これは文が悪文だったというものだ。次は技術的な悪書の理由について書く。

サンプルコードの1割ほどがコンパイルできない

コンパイルできない理由は、識別子が間違っているとか、あるべき記号が欠けているとか、極めて些細でお粗末なtypoがほとんどだ。

このような問題は、本のソースコードからサンプルコードを抜き出してコンパイラーに通して文法違反がないかどうか確かめるテストを書けば防げる話だ。そして、この本はわざわざ大量の文章を割いて、テストの重要性を説いている。Stroustrupには、「医者の不養生」というニッポンのコトワザを教えてあげたい。

この本は、はじめC++11向けに、おそらく2006年か2007年ごろから書かれたものが、2008年に出版され、それをC++14に対応させ、また C++11の規格制定後に、C++11の新機能を使った行儀の良いお作法に対応させる修正を行っている。

その過程で、「ふふん、この程度の変更は自明だからコンパイルして確認するまでもないね」という怠惰とうぬぼれがあったのだろう。テストを書くべきである。

Stroustrupであろうと混乱したであろう興味深い間違いの例はある。例えば、変数の初期化をbrace-or-equal-initializerにすることでnarrowing conversionを防ぐなどのお作法のために、サンプルコードを全面的に修正したりしている。

void f( int x )
{
    short s1 = x ; // OK、ただし縮小変換
    short s2{x} ; // エラー、縮小変換は禁止されている
} 

問題は、これを以下のようなstd::string s(1, 'a')というコードに対して盲目的に適用してしまったことだ。

// "a"で初期化
std::string s1(1, 'a') ;
// "\x01a"で初期化
std::string s1{1, 'a'} ;

理由は、brace-or-equal-initializerでは、まずstd::initializer_list<T>を引数に取るコンストラクターが探され、ない場合は、その他のコンストラクターで引数の数と型があるものが探される。std::stringには、initializer_list<char>を引数に取るコンストラクターがあるので、そちらが優先される。

そして、リスト初期化のnarrowing conversionの禁止は、コンパイル時定数で変換先の表現可能な範囲である場合は発生しない(より正確には、そのような場合はnarrowing conversionとみなされない)。その結果、{'\x01', 'a'}というリスト初期化だと解釈されてしまった。

これはコンパイルも正常に通ってしまうので、実行して出力を確認しない限り見抜けないバグだ。

もうひとつの例は、C++03とC++11で挙動が変わるコードだ。

bool can_open(const string& s)
// check if a file named s exists and can be opened for reading
{
     ifstream ff(s);
     return ff;
}

can_open関数は、引数として与えられたファイル名でファイルを開けるかどうかを確認する関数だ。問題は、ffがファイルを開いているかどうかを、boolへの暗黙の型変換で調べている。ifstreamはbasic_iosから派生していて、basic_iosはoperator void *()という変換関数を持っていて、ファイルが開いているかどうかをnullptrかどうかで返すのだが、これは問題が多いとして、library issue 468ではexplicit operator bool()に変更された。そのため、C++11ではコンパイルエラーになる。

そもそも、暗黙の型変換に頼るのが間違いなのだ。ファイルを開いているかどうか確認するメンバー関数is_open()があるのだから、それを使えばよい。

これは、コンパイルさえしていれば発見できた問題だ。

全体的には、極めてお粗末で些細なill-formedなサンプルコードばかりだ。

教訓2: テストは重要だ

著者の文字コードへの理解がない

本にはこう書いてある。

「テキストファイルの最初の4バイトは4文字である」

この文脈は、テキストファイル一般の話だ。これから扱う課題の入力に使うテキストファイルの最初の4バイトは常に4文字であるとみなすという仮定の話ではない。つまり、1文字は1バイトであると書いていることになる。

このような内容のプログラミングの参考書を日本で出版したならば、マサカリが雨となって降り注ぎ、著者、編集者、査読者は二度と顔を出して表を歩けず、出版社の信頼は地に落ちることうけ合いだ。そして、すでにC++11にはUTF-8/UTF-16/UTF-32文字列リテラルが入っているのだからなおさら悪い。この文章は到底受け入れがたい。

そして、この本には、「中国の文字やマラヤーラム文字をサポートするには」などという文章も入っている。中国の文字やマラヤーラム文字をサポートした現実の文字コードは、すべて可変長エンコードであり、1文字は1バイトとは限らない。

また、中国の文字やマラヤーラム文字をサポートするには、というのに続けて、C++の標準ライブラリのiostreamやlocaleの詳細な参考書を読むべきだとも書いている。iostreamやlocaleは、設計上可変長エンコードに対応できず、この文書は無責任である。

またひどいことに、C++11で入った正規表現ライブラリもUnicodeに対応していると書いている。実際は対応していない。そもそも、可変上文字列に対応できない設計になっている。受け入れがたく無責任にもほどがある。

筆者はこれを何度もBjarne Stroustrupに指摘したが、残念ながら話が噛み合わず、本人に修正を促すことはできなかった。曰く、「これは英語圏の話であるから」。しかし、もはや英語圏とてUnicodeから逃れることはできないというのに。

そして、筆者の使う、unacceptableとかirresponsibleという言葉を侮辱的であると返すばかり。侮辱的にしろ、unacceptableなものはunacceptableであり、irresponsibleなものはirresponsibleでしかない。

このため、該当箇所に間違っていると指摘する注釈を入れ、また原文にない章を特別に追加して、現実の文字コードと、C++の文字と文字列とライブラリ、C++の規格と現実の文字コードの対応、Apple, GNU/Linux, Windowsにおける文字コードの取り扱いなど、日本人プログラマーなら誰でも知っているし、Wikipediaなどで簡単に調べられることを、簡単に浅く説明した。筆者の専門ではない分野を扱ったのでマサカリが山と飛んでくることを恐れている。

Cプリプロセッサー

この本のサンプルコードは、すべてstd_lib_facilities.hというヘッダーファイルを#includeすることが前提で書かれている。このヘッダーの中身は、本で使っている標準ライブラリヘッダーの#includeや、有益ないくつかの関数の追加。またusing namespace std ;などが書かれている。グローバル名前空間に読み込まれるヘッダーファイルでusing namespace std;を書くのはよろしくないが、これが入門書だということを考えると、まだ納得もできる。

ただし、納得のできないことはある。これだ。

#define vector Vector

Cプリプロセッサーで、vectorというトークンをVectorに置き換えている。Vectorとは何か。以下のように定義されている。

template< class T> struct Vector : public std::vector<T> {
 using size_type = typename std::vector<T>::size_type;


 using std::vector<T>::vector; // inheriting constructor

 T& operator[](unsigned int i) // rather than return at(i);
 {
  if (i<0||this->size()<=i) throw Range_error(i);
  return std::vector<T>::operator[](i);
 }
 const T& operator[](unsigned int i) const
 {
  if (i<0||this->size()<=i) throw Range_error(i);
  return std::vector<T>::operator[](i);
 }
};

ようするに、operator[]でもat()を使った範囲外チェックを行うようにするものだ。

本では、これを必要悪であり、現実のソフトウェアプロジェクトでもこのような技法を使うことはあり、実際に役に立っていると書いているが、とんでもないことだ。

範囲外チェックを行いたければ、最初からat()を使っておけばいいのだ。fstreamを暗黙の型変換でboolに変換してファイルがオープンされているかどうか調べようとしたり、Stroustrupは大昔の粗野な時代の悪い癖が抜けていないのではないかと疑う。

課題の設定

この本では、まず冒頭で変数や関数、式、文など言語の文法の基本を教えたあと、次の章で練習課題を出している。この本は、まだプログラミング経験の一切ない初心者を対象にしていることを思い出してほしい。その上で、いま変数や関数やif文を覚えたばかりの初心者が、以下の課題を解く難易度を考えてほしい。

「実数と四則演算と括弧がある数式を標準入力から読み込んで計算結果を標準出力する計算機を実装せよ」

実数と四則演算までならまだ初心者でもなんとかなるだろうが、括弧が出てきた時点で完全に初心者向けではない。

この本では、まずBNF記法で数式の文法を定義したあと、教科書的な再帰下降構文解析による数式のパーサーを書いて計算を行っている。SICPでも冒頭でここまで無茶な課題はなかったはずだ。

もちろん、面白い課題であり、全プログラマーがプログラミング学習の比較的早い段階で一度は練習のために実装してみるべき課題ではあるが、いかにもタイミングが早すぎる。

Bjarne Stroustrupの本がここまで悪書だとは思わなかった。特に文字コードへの理解が致命的にない。

Stroustrupのプログラミング入門の査読の仕事で、筆者は反面教師としての貴重な教訓を得た。また、C++11/14コア言語の執筆の経験からも、いろいろと執筆環境の不満点はあった。そこで、筆者が次に参考書を執筆するときは、以下のような環境で行おうと考えている。

  • OSにUbuntu GNU/Linuxを使う。理由は、必要なソフトウェアが標準のパッケージマネージャーで揃う上、C++を書く上で圧倒的に快適だからだ。
  • テキストディターにVimを使う。
  • 執筆環境はgitで管理する。

  • GNU Makeで参考書のビルドとテストを管理する。これ以上に複雑なビルドシステムは、参考書執筆では必要がないと判断した。
  • 参考書のソースコードはMarkdownで書く。
  • HTMLなどの各種フォーマットへのコンパイルはpandocを使う。
  • HTMLへの出力では、数式はmathjaxを使う。ただし、KaTexも興味深いので評価中だ。
  • HTMLへの出力では、ソースコードはhighlight.jsを使ってシンタックスハイライトする。
  • 参考書のソースコードからサンプルコードを抽出してGCCとClangで文法チェックをする。
  • textlintで日本語のチェックをする。できるだけ簡潔な文章を維持するために文章にこういったツールで制約をかける。

すでに、これらのことをだいたい実装している。まだC++17の参考書を書くには不確定要素が多すぎるが、そろそろ準備は始めるべきだ。

一つ不満なのが、textlintの実装がnode.jsで書かれていることだ。もちろん、ツールとして使うのであるから、正しく動作さえすれば、どのような言語で書かれていようと気にしないのだが、結果的に、textlintの導入方法がなかなか厄介だった。Ubuntuにはnodejsパッケージがあるが、これはJavaScriptの実行環境が/usr/bin/nodejsというファイル名になっている。理由はすでにnodeというファイル名のパッケージが存在していて、名前が衝突するからだ。nodeパッケージをいれないのであれば、nodejs-legacyパッケージを入れることによって、/usr/bin/nodeへのsymlinkを貼れる。そして、GitHubのレポジトリから直接/usr/localにファイルを引っ張ってくる。npmにより、パッケージ間の存関係が極めて複雑で、とても些細な機能ですらパッケージ化されている。

ドワンゴ広告

ドワンゴは1文字は1バイトではないとわかっている本物のC++プログラマーを募集しています。

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

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

2016-08-02

C++標準化委員会の文書: P0330R0-P0339R0

[PDF] P0330R0: User-Defined Literals for size_t

std::size_t型を返すuser defined literal suffixのzuを追加する提案。これにより、size_t型の変数をautoで宣言できるようになる。

using namespace std::support_literals;
auto size = 123zu ;

サフィックスのない整数リテラルの型はint型になるため、これまでズボラなプログラマーは符号付き整数をstd::size_t型の変数に代入したり比較したりしていた。符号付き整数と符号なし整数を変換したり比較すると、思いがけぬ挙動につながるので、好ましくない。

P0331R0: P0331r0 : Motivation and Examples for Multidimensional Array

多次元配列array_refの動機と利用例

P0332R0: P0332r0 : Relaxed Incomplete Multidimensional Array Type Declaration

array_refは、配列型を渡すことによって、一部を動的なサイズにすることができる。

array_ref< int [][5][] > a ;

これを実現するために、配列の宣言の文法を変更する。

P0333R0: P0333r0 : Improving Parallel Algorithm Exception Handling

Parallelism TSで並列ベクトル実行ポリシーでアルゴリズムを実行した時に、要素アクセス関数が例外を投げた場合、直ちにstd::terminateが呼ばれる。これは他の実行ポリシーのexception_listを投げる挙動と違い、一貫性がない。そこで、並列ベクトルポリシーの場合でもexception_listを投げるようにする。また、並列ベクトル実行ポリシーはbad_allocも投げることがある。

P0334R0: P0334r0 : Immutable Persistent Containers

変更できないコンテナー、immutable_listの提案。

immutable_listは要素を変更出来ないコンテナーだ。「変更」したいときは、新しいimmutable_listのオブジェクトを作る。要素は参照カウンターで管理されている。

確かに、標準ライブラリにほしいコンテナーだ。Haskellが参考にされている。

[PDF] P0335R0: Context Tokens for Parallel Algorithms

並列アルゴリズムにコンテキストトークンを追加する。

parallel::for_each( vec, 0, N, []( auto i )
    {
        parallel::for_each( par, 0, N, func ) ;
    } ) ;

このように、並列アルゴリズムがネストする場合で、外側の実行ポリシーがベクトルで、内側の実行ポリシーが並列の場合、挙動は未定義になる。この誤りを検出する方法がない。

そこで、要素アクセス関数(この場合、lambda式やfunc)にコンテキストトークンを与え、同トークン経由で並列アルゴリズムを呼び出す方法を付け加える。

parallel::for_each( vec, 0, N, []( auto context, auto i )
    {
        context.for_each( par, 0, N, func ) ;
    } ) ;

これにより、実行ポリシーの伝播が正しく行われるようになる。

[PDF] P0336R1:Better Names for Parallel Execution Policies in C++17

並列アルゴリズムの実行ポリシーの名前をリファクタリングする提案。シングルトンオブジェクトのseq, par, vecは変わらないが、std::execution名前空間の下におかれるようになる。

P0337R0: P0337r0 | Delete operator= for polymorphic_allocator

polymorphic_allocatorからoperator =を削除する提案。

polymorphic_allocatorはステイトフルなアロケーターである。propagate_on_container_copy_assignment と propagate_on_container_move_assignmentはfalseを返す。これは意図的なものである。理由は。ステイトフルなアロケーターは一度コンテナーに入れたら、そこから動かすべきではないからだ。その設計思想から考えれば、そもそもoperator =を提供すべきではない。operator =を使って失敗する例がいくつもある。そこで、operator =を削除する。

[PDF] P0338R0: C++ generic factories

汎用的なfactory関数の提案。

C++には、いわゆるmake系のfactory関数が存在する。例えば、make_sharedとかmake_uniqueとかmake_pairなどだ。

make関数が作られる理由は主に2つある。

新しく型を作るfactory関数

back_inserter、make_optional、make_ready_future, make_expectedなど、新たに型を作り、そのオブジェクトを返すものがある。

emplace構築を行うもの

make_uniqueやmake_sharedなど。

また、make_pairやmake_tupleのような、新たに型を作り、かつemplace構築まで行うものがある。

この提案は、そのような様々なmake_foobar関数を、make関数に統一しようと言う提案だ。例えば以下のようなードが、

int v=0;
auto x1 = make_shared<int>(v);
auto x2 = make_unique<int>(v);
auto x3 = make_optional(v);
auto x4v = make_ready_future();
auto x4 = make_ready_future(v);
auto x5v = make_ready_future().share();
auto x5 = make_ready_future(v).share();
auto x6v = make_expected();
auto x6 = make_expected(v);
auto x7 = make_pair(v, v);
auto x8 = make_tuple(v, v, 1u);
future<int&> x4r = make_ready_future(std::ref(v));
auto x1 = make_shared<A>(v, v);
auto x2 = make_unique<A>(v, v);
auto x3 = make_optional<A>(v,v);
auto x4 = make_ready_future<A>(v,v);
auto x5 = make>(v, v);
auto x6 = make_expected<A>(v, v);

以下のように書ける。

int v=0;
auto x1 = make<shared_ptr>(v);
auto x2 = make<unique_ptr>(v);
auto x3 = make<optional>(v);
auto x4v = make<future>();
auto x4 = make<future>(v);
auto x5v = make<shared_future>();
auto x5 = make<shared_future>(v);
auto x6v = make<expected>();
auto x6 = make<expected>(v);
auto x7 = make<pair>(v, v);
auto x8 = make<tuple>(v, v, 1u);
future<int&> x4r = make<future>(std::ref(v));
auto x1 = make<shared_ptr<A>>(v, v);
auto x2 = make<unique_ptr<A>>(v, v);
auto x3 = make<optional<A>>(v,v);
auto x4 = make<future<A>>(v,v);
auto x5 = make<shared_future<A>>(v, v);
auto x6 = make<expected<A>>(v, v);

make関数にテンプレート名を渡すと、それぞれに対応したfactory関数として振る舞う。

テンプレート名ではなく、型を渡すことも可能である。これによって具体的に指定することも可能になる。

auto x = std::make< unique_ptr<long>>(0) ;

P0091によって、コンストラクターからテンプレート実引数の推定ができるようになるので、make関数の一部の機能は普通に書けるようになるが、それでもmake関数の優位な点はいろいろあると主張している。

customization pointとしては、std::factory_traits<T>が提供されている。これを特殊化することによってユーザー定義のクラスに対する挙動を追加できる。

[PDF] P0339R0: polymorphic_allocator<void> as a vocabulary type

polymorphic_allocator<void>を、型を指定せずに使えるあロケーターにしようと言う提案。

ドワンゴ広告

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

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

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

2016-07-29

東京都知事選挙の候補者の主張の実現可能性の考察

現在、都知事選挙が行われている[要出典]。筆者の手元には、東京都選挙管理委員会の発行した、「東京都知事選挙 選挙公報」と題された新聞様の文書がある。この選挙公報は、「立候補者21名のうち掲載申請があった20名から提出された原稿をそのまま製版の上掲載」しているという。

この選挙公報をつらつら眺めていると、多くの立候補者の主張する公約の実現には、極めて超法規的な権力(既存の国際条約、憲法、法律、条例への違反)、日本の単年度国家予算(一般会計と特別会計を合わせて重複を省いた額、だいたい200兆円ほど)を超える金、時には物理法則を捻じ曲げる必要があることに気がついた。

しかし、それでもなお、公約を真面目に実現させた場合の状況を想像すると、なかなかにユーモラスな結果となることが予想される。そこで、この記事では、今回の都知事選挙の立候補者が選挙公報に寄せた内容を公約とみなし、文字通り実現させることが可能か、そして文字通り実現させた場合に起こるユーモラスな結果を考察したい。

今回の考察にあたっては、通常の常識における制約は考慮しない。都知事には超法規的な権力が与えられ、都知事の意思ひとつで、すべての日本国が批准する国際条約からは脱退できるものとし、日本の憲法、法律、条例は変更可能とする。すべての日本国民は、さながら大躍進政策や文化大革命のごとく、都知事の計画経済にしたがって行動するものとする。あらゆる倫理、道徳より都知事の意思が優先するものとする。

ただし、最低限の制約は必要である。そこで、物理法則に違反する内容(例:永久機関)は不可能とする。また、日本の単年度国家予算(約200兆円)を超える金が必要な内容は条件付き実現可能とする。日本国外に対する内容には通常の常識を適用する。

考察する立候補者の順番は、選挙公報の順番であり、他意はない。

立花考志

この立候補者の公約は全て実現可能である。

この立候補者の主張は、東京都の条例によってMHK集金人の戸別訪問を規制するとか、放送法の改正によってNHKの受信料を支払わなくてもよくするといったたぐいのことである。今回の考察における大胆な制約の下では、NHK自体を消失させることも可能であるので、この程度のことは、他の立候補者の主張に比べれば、比較的簡単に実現可能である。

マック赤坂

この立候補者の公約は条件付き実現可能である。実現可能性は、現在の条件に依存する。

この立候補者の公約の多くは、金さえあれば実現可能である。例えば、「待機児童ゼロ、老人介護施設3倍増」とか、「中学生以下65才以上に3万円支給」とか、「東京全域バリアフリー化」などといった公約は、日本の国家予算の範囲内の金で実現できる。

また、抗うつ薬の使用禁止とか精神科医の免許取り消しなどといった公約も、法律を改正すれば容易に可能である。

「東京オリンピックを大成功させる」という公約には、日本国外の人間の動員も必要であるが、オリンピックは世界的に有名なイベントであるから、日本国内さえ十分に整備して全国民を強制徴用して動員すれば大成功は可能であろう。

ただし、疑問点はある。

「都職員に・・・能力給・信賞必罰を徹底し人員の20%カットを目指す」という内容は、論理的に成り立たない可能性がある。現在の都職員の20%以上が本来不要であるならば可能である。しかし、もし不要な都職員が20%未満であれば、彼は不要でもないのに不当に解雇される。これは信賞必罰と矛盾する。したがって、この立候補者の公約が実現可能かどうかは、現在の都職員の20%以上が不要であるかどうかにかかっている。

「スマイルあふれる東京」を実現するには、東京にいる人間に強力な抗うつ剤、あるいは筋弛緩剤(顔面を弛緩させることにより笑っているような表情にする)の摂取を義務付けるなどして、強制的にスマイルを発生させなければならない。公約では同時に抗うつ剤の禁止を主張しているので、例えば亜酸化窒素のような顔面の筋肉を弛緩させる薬品を使うのであろう。極めてディストピアな世界になるが、もちろん実現可能だ。

また、「都内のレストランにチップ制を導入」とある。日本ではチップの文化がないので、これを導入するには大躍進や文化大革命のごとき都民の強制徴用と動員が必要になる。

総合的に判断して、この立候補者の公約は、疑問点がいくつかありながらも、実現可能である。

鳥越俊太郎

この立候補者の公約は実現不可能である。

この立候補者の公約の多くは、金さえあれば実現可能である。必要な金は国家予算を超えないので実現可能である。

がん検診の促進や骨粗しょう症対策は、通常の常識の範囲内でも実現可能であるし、災害に強い東京も、金さえあれば実現可能である。

ただし疑問点はある。「希望するすべての人が正社員になれる格差のない社会をつくり」とあるが、これは難しい。ここでいう「正社員」とは労働基準法等に基づく被雇用者であって、かつ、有期契約労働者や派遣労働者や請負ではなく、仕事を依頼する人間が直接、期間を限定せず、雇用するものをいうのであろう。

これは、雇用された会社ではなく、常に客先に常駐している派遣をなくすのであれば、通常の常識の範囲内ではあるが、「希望するすべての人」という条件により、通常の常識からは外れてしまう。

例えば、筆者の自宅の壁付けコンセントが破損したとする。コンセントの修理には電気工事士の資格が必要である。筆者は同資格を保有していないので、資格保有者に修理を依頼する。もし、資格保有者が正社員を希望した場合、筆者は資格保有者を雇用しなければならない。もちろん、有期雇用契約ではなく無期雇用契約でなければならない。

これを実現するには、人を雇用する手間を極端に下げなければならない。例えば、役所に印鑑証明でも出しに行く程度の気軽さで、雇用契約を結べるよう、行政の手厚いサポートが必要だ。雇用の概念も大幅に変わるだろう。この公約が実現した社会では、都民ひとりひとりが大勢の人間を相互に雇用しあっている状態になる。もはや現在の「正社員」などどうでも良くなっているはずだ。しかし、実現可能ではある。

「職人を大切にするマイスター制度を拡充します」と書いてある。「拡充」とは大辞林 第三版の解説によれば、「設備・組織などをひろげ,充実させること」である。すると、都知事選前にすでに日本にマイスター制度が存在しなければならない。現在、日本にはマイスター制度は存在していないので、この公約は前提となる条件を欠き実現不可能である。

「できるだけコンパクトでシンプルな2020オリンピック」と書いてある。オリンピックは大規模なイベントであり、コンパクトではないので実現不可能である。今回の考察では、多額の金を費やすことにより実現可能なことは実現可能だと判定するが、実現には多額の金がかかるにもかかわらず金をかけずに実現するという矛盾した公約は実現不可能だと判定する。

増田ひろや

この立候補者の公約はすべて実現可能である。

この立候補者の公約の多くは、金さえあれば実現可能である。必要な金は国家予算を超えないので実現可能である。

例えば、子育てや介護福祉や女性の活躍の場の充実などは、金があれば実現可能である。災害対策として上げている木造住宅の不燃化、耐震化も、金があれば実現可能である。オリンピックの成功や、その後も成長を続けるなども、金があれば実現可能である。

ただし疑問点がある。

「都民が、あたたかさにあふれ、不安がなく、安心して生活できる環境・社会の実現を目指します」とある。

「あたたかさにあふれ」るためには、暖房を完備しなければならない。冬の屋外でも「あたたかさにあふれ」るためには、屋外に隙間なく暖房器具を配置するか、すべて屋内にしてしまう必要がある。すべてを屋内にした場合、東京都民はドーム型通路の中を歩いて移動することになる。これは、金さえあれば可能だ。

「不安がなく」なるためには、全都民に強力な抗うつ剤の摂取を義務付けなければならない。極めてディストピアな世界となるが、もちろん実現可能だ。

桜井誠

この立候補者の公約は実現不可能である。

この立候補者の公約の多くは、倫理、道徳さえ無視すれば実現可能である。

倫理上問題のある外国人生活保護の廃止、表現の自由を侵害する半日ヘイトスピーチ禁止条例制定などは、今回の考察の制約の範囲内で実現可能である。

実現不可能なのは、「コンパクトな東京五輪の実施」だ。オリンピックは大規模なイベントでありコンパクトではないので実現不可能である。今回の考察では、多額の金を費やすことにより実現可能なことは実現可能だと判定するが、実現には多額の金がかかるにもかかわらず金をかけずに実現するという矛盾した公約は実現不可能だと判定する。

今尾貞夫

この立候補者の公約はすべて実現可能である。

この立候補者の公約の多くは、金さえあれば実現可能である。

子育て、教育にかかる個人負担はないとか、幼稚園、保育園は誕生直後から全員受け入れ態勢を取るとか、老人介護のために食堂浴場を整備した家を作るなどは、国家予算以下の額の金で実現可能である。

実現可能ではあるが疑問のあるものとして、直接民主制の導入を主張していることだ。

「知事交代をチャンスに都民皆の希望を集約、生活不安解消策を皆で見出し、皆で実現していく皆の参加する都政に変えます。」

皆が参加する都政を実現するためには、選挙で代表者を選出するのではなく、都民皆が議会に参加できる必要がある。したがって、この公約を実現するには直接民主制に切り替える必要がある。

谷山ゆうじろう

この立候補者の公約は条件付き実現可能である。実現可能性は、国外の未来の条件に依存する。

この立候補者の公約の多くは、実現可能である。

ただし、国外の未来の条件に依存した公約がある。

「「DONALD TRUMP アメリカ大統領」に毅然とNO」と書いてある。2016年アメリカ合衆国大統領選挙において、ドナルド・トランプは立候補者の一人であり、大統領になる可能性があるが、大統領選挙は2016年11月8日に行われ、投票結果が正式に発表されるのは2017年1月とされている。したがって、ドナルド・トランプが今回、あるいは将来のアメリカ合衆国の大統領になるかはまだ未定であり、もしドナルド・トランプが大統領にならなかった場合、大統領ではないので、前提となる条件を欠き、「毅然とNO」と言うこともできない。

今回は選挙公報の実現可能性だけを考察するものであって、その内容の良し悪しについて考察はしない。しかし、この立候補者の選挙公報の日本語は、解釈が難しい。例えば、以下は選挙公報からの抜粋である。

2020年世界はTOKYOに

その中心地、国立競技場からのみ発信します

イギリスBBC、中東アルジャジーラTVなど世界を舞台に活動してきた谷山ゆうじろう
は、毎日英語で定例記者会見を行いNHKワールドで生中継。日本を売り込みます

TOKYOから国際化&自立国家

国際人を育む、夢のあるカラーフルなシティTOKYOを目指す

既成政党の組織票・お金ありきの選挙戦に、断固反対します。名前を連呼するだけの選挙カーなし、
事務所なし、ガソリン代なし。あるのは国家観と、iPhoneのみ。従来の思考回路ではもう日本は
進化できません。毎年2万人人口減少の高齢化の中で、若い人に夢を。移動中のスマホで、ご家庭
のPCで、2020東京オリンピックスタジアム(建設中)前からの生放送演説をぜひお聞きください。

これは一部だが、とにかく文章らしい文章がない。「iPHoneのみ。」とか、「若い人に夢を。」とか、よくわからない文章の区切り方と構成をしている。筆者の解釈によれば、この立候補者は、

  • 2020年に国立競技場から発信(生放送演説?)をする
  • 発信は国立競技場からしか行わない
  • 東京オリンピックスタジアムでも生放送演説(発信ではない?)を行う
  • 演説の際、東京オリンピックスタジアムはまだ建設中である(生放送演説は2020年ではない?)
  • 事務所もガソリン代もない

などの情報が得られたが、この日本語の解釈が正しいのかどうか、筆者には自信がない。発信と生放送演説は違うことと、生放送演説は2020年ではなさそうなので、記述は矛盾しないように読める。この立候補者の文章の日本語は極めて解釈が難しいため、今回の実現可能性の考察は完全に間違っている解釈に対して行っている可能性がある。

後藤輝樹

この立候補者の公約は条件付き実現可能である。公約は国家予算を超える金があれば実現可能である。

この立候補者の選挙公報は、ほとんどが公約の箇条書きで構成されている。立候補者の学歴や職歴、属する政党などの公約ではない情報は極めて少ない。

この立候補者の公約をすべて実現するには、日本の国家予算を超える金が必要になる。したがって、この立候補者の公約は条件付き実現可能と判断した。

特に金のかかる公約は以下の通り

「すべての低所得者(国民)に毎月8万円支給します(ベーシックインカム導入)」

最大で以下の額の金がかかる。

$$ 8万円 \times 12ヶ月 \times 1億2千万人= 115兆2000億円 $$

「日本の借金約1000兆円を10分の1以下に減らし」などは、デノミネーションを行えば額面上は実現可能である。

「核武装します」、これには多額のカネがかかる。

「日本の食料自給率およびエネルギー自給率100%以上を目指します」

以下の公約は物理法則に違反しない。

「地震、津波および気象兵器テロ(人工地震兵器等)対策をします」

人間が知覚可能な地震を人工的に起こすことは可能であり、津波や降雨、旱魃なども、ある程度人工的に操作可能である。またこれは兵器開発ではなく対策なので、そのような兵器が存在しなくても実現可能である。

また、この立候補者は、日本の政治を天皇を元首とする君主制政治に変更する公約をしている。

公約は多数あるが、お互いに矛盾する公約は見つけられなかった。

「東京五輪中止、または超低コストでやります。」と書いてある。金があれば実現可能なことは多いが、支出を削るのに金は使えないので実現は難しいが、中止は可能なので実現可能だ。

中川ちょうぞう

この立候補者の公約は条件付き実現可能である。公約の実現には国家予算を超える金が必要になる。

この立候補者の選挙公報は具体性にかけるが、すべての実現を考えると、おそらく国家予算を上回る額の金が必要になる。

高橋しょうご

この立候補者の公約はすべて実現可能である。

この立候補者の公約をすべて実現するには、国家予算以下の金で足りる。

公約には具体的な対応作に欠けるものが多い。

「少子化対策の公約が守られていたら、私達の回りには今より多くの子供達がいたはずです」という文章があるが、これは誤りである。なぜならば、公約の少子化対策が効果のないものであれば、たとえ公約が守られていたとしても児童人口は増加しない。

せきくち安弘

この立候補者の公約は、全て実現可能である。

この立候補者は憲法改正を公約としている。その他の公約も国家予算以下の金で実現可能である。

この立候補者の提案する日本国憲法の前文には、「国民が投票により選ぶ代表が、常時一カ所に集う新しい国際協調の仕組みとして世界最高会議体(仮地球議事堂)を形成してゆく為に」という文章がある。これを解釈すると、おそらく政治家は24時間365日、一カ所に拘束されるのだろう。

山口敏夫

この立候補者の公約は、すべて実現可能である。

この立候補者の公約は、国家予算以下の金で実現できる。

「2020東京五輪・パラリンピックは・・・一、アスリート選手諸君の、”名誉”をかけた”活躍”に期待し、応援すること」と書いてあり、都民にオリンピック選手の応援を義務付けている。応援したくない都民がいたとしても、文化大革命、大躍進政策のごとく、都民の意思を無視して、都民徴用と強制応援を行えば実現可能となる。

やまなかまさあき

この立候補者の公約は、全て実現可能である。

「今立ち上がれ! 私達(眠れる子羊)よ!」と書いてあるが、都民は人間であり羊ではない。この文章は比喩であろう。しかし、眠れる獅子とか迷える子羊とはいうが、眠れる子羊とは何を意味するのであろうか。

「さあ、はじめよう«レジスタンス»!」とも書いてあるが、侵略や抑圧に対抗する民兵を組織して革命を目指すのではなく、同じく単なる比喩であろう。

「次代を担う!子供たちの輝ける未来«笑顔と笑い声のたえない»の創造を目指します!」と書いてある。「笑顔と笑い声のたえない」を創造するためには、都民に強力な抗うつ剤の摂取を義務付ける必要がある。ディストピアな社会になるが、もちろん実現可能だ。

岸本雅吉

この立候補者の公約は、全て実現可能である。

唯一気になるのが、徴農制だ。

「小学校・中学校時代に、「徴農制」を導入する」、「小学校・中学校時代に数期に分けて「徴農制」を導入します」

少し形は違うがポル・ポトを彷彿とさせる公約だ。

ないとうひさお

この立候補者の公約は、すべて実現可能である。

アメリカ合衆国のような自己責任について書いているが、それを実現するには修正第2条にある、「規律ある民兵は、自由な国家の安全にとって必要であるから、人民が武器を保有し、また携帯する権利は、これを侵してはならない。」のような、武装する権利を都民に認めるべきであるが、そのような言及はしていない。

また、「東京の人口を現在1/2にする」とも書いている。これは虐殺によって人口を減らすのではなく、地方に人を工場や企業を移転させることで実現するという。大躍進政策や文化大革命のような強制的な徴用と動員が必要であるが、もちろん実現可能だ。

望月義彦

この立候補者の公約は、全て実現可能である。

ゼロエミッション都市のために、緑化、木造、木質化を挙げている。おそらく厳しい建築規制が敷かれるのだろう。そのような厳しい建築規制では、東京の経済が他の公約どおりに「世界とともに成長し続ける未来都市」となれるかは疑問だが、十分な金さえあれば可能だろう。

また、「瞑想教育」を公約に入れているため、都民に特定の宗教を強制するものと見える。

小池ゆりこ

この立候補者の公約は、全て実現可能である。

ただし、実現した場合、社会構造を大きく変える公約がある。

「残業ゼロ」を実現するには、たとえ労使協定を結ぼうとも残業は違法になる法律を制定する必要がある。また、もちろん公務員も残業ができないので、国会議員の質問主意書の返答は極めて遅くなるだろう。

「満員電車ゼロ」を実現するためには、電車を拡張するより、東京都の経済を破壊するとか、都民を虐殺するなどしたほうが実現が容易だ。

「多摩格差ゼロ」もよくわからない公約だ。多摩を都心部のように経済的に充実させる公約であろうか。すると大躍進政策や文化大革命ばりに強制徴用と都民動員が必要になる。

宮崎正弘

この立候補者の公約は、全て実現可能である。

この立候補者の公約はあまりにも具体性に欠けるため、考察できることがほとんどない。

上杉隆

この立候補者の公約は、実現不可能である。

「知事給与ゼロ全額返上」と書いてあるが、給与返上は公職選挙法第199条の禁止する寄付にあたるので、現行法では禁止されているが、法律を改正すれば実現可能だ。

「首都直下型地震対策死者ゼロ」と書いてあるが、東京都で大規模な地震が起きた場合に死亡者を0人にできる保証はないので、実現不可能である。

「東京オリンピック運営費を当初のコンパクト案に」と書いてあるが、金さえあれば実現できることは多いが、支出を削るのは金がいくらあっても不可能なので、実現不可能である。

七海ひろこ

この立候補者の公約は、条件付き実現可能である。公約の実現可能性は国外の経済に依存する。

この立候補者は、「経済的にも精神的にも、世界一リッチな都市・東京を実現します」と書いている。これを実現するには、国外のすべての都市が東京の経済規模以下にならなければならない。国外に依存するので条件付き実現可能となる。

考察まとめ

金、法、倫理の制約を無視しても、これほど多くの立候補者の公約が実現不可能になるとは思わなかった。実現不可能な公約を出した立候補者は以下の通り。

マック赤坂、鳥越俊太郎、桜井誠、谷山ゆうじろう、後藤輝樹、中川ちょうぞう、上杉隆、七海ひろこ

以下は実現不可能な公約である。

オリンピックをコンパクトにする

オリンピックは巨大なイベントである。フルチンでかけっこをしていた昔と異なり、今のオリンピックは多数の国家から多数の選手が参加する。例えば、先のロンドン・オリンピックでは、204の国家から、10568人の選手が参加した。選手だけで1万人もいるのだから、これをどうやってコンパクトにせよというのか。参加国の桁を減らし、参加人数の桁も減らすしかない。しかし、おそらく立候補者はそこまでコンパクトにすることは考えていないだろう。

金をかければ実現できることは多いが、金をかけないことを実現するのは難しい。

実現可能性が過去や未来の不確定な結果に依存するもの

無能な都職員を20%クビにする公約を実現するには、現在の都職員の20%が実際に無能でなければならない。すでに確定した結果を変えることはできないので、現在の都職員のうち20%以上が無能でなければ実現できない。

マイスター制度を拡充するには、すでにマイスター制度が存在しなければならない。

ドナルド・トランプはまだアメリカ合衆国の大統領になることが確定していないので、もしドナルド・トランプが大統領にならなかった場合は、毅然とNOをいうこともできない。

日本の国家予算(約200兆円)を超える予算が必要になるもの

政治家は現在の国家予算という上限を認識すべきである。