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