C++03と11

次のソースをコンパイルして実行する。move関係はC++03のときはコメントアウトする。

#include <iostream>
#include <vector>

struct S { 
    int i;

    S () {
        std::cout << "default constructor" << std::endl;
    }   
    S (const int i) : i(i) {
        std::cout << "constructor: i=" << i << std::endl;
    }   
    S (const S & s) : i(s.i) {
        std::cout << "copy constructor: i=" << i << std::endl;
    }   
    S (const S && s) : i(s.i) {
        std::cout << "move constructor: i=" << i << std::endl;
    }   
    ~S () {
        std::cout << "destructor: i=" << i << std::endl;
    }   
    S & operator = (const S & s) {
        i = s.i;
        std::cout << "operator=(&): i=" << i << std::endl;
        return *this;
    }   
    S & operator = (const S && s) {
        i = s.i;
        std::cout << "operator=(&&): i=" << i << std::endl;
        return *this;
    }   
};

void printv (std::vector<S> & v) {
    for (std::vector<S>::iterator it = v.begin(); it != v.end(); ++it) {
        std::cout << it->i << ", ";
    }   
    std::cout << std::endl;
}

int main () {
    //std::vector<S> v = {1,2,3}; // initializer-list
    std::vector<S> v(3);
    v[0] = S(1);
    v[1] = S(2);
    v[2] = S(3);
    printv(v);
    std::vector<S>::iterator it = v.begin();
    std::advance(it, 1);
    v.erase(it);
    printv(v);
}

コンパイラのバージョン。

$ g++ --version
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang++ --version
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix

結果

$ g++ -std=c++03 -W -Wall -pedantic vec.cc 

$ ./a.out
default constructor
copy constructor: i=6303208
copy constructor: i=6303208
copy constructor: i=6303208
destructor: i=6303208
constructor: i=1
operator=(&): i=1
destructor: i=1
constructor: i=2
operator=(&): i=2
destructor: i=2
constructor: i=3
operator=(&): i=3
destructor: i=3
1, 2, 3, 
operator=(&): i=3
destructor: i=3
1, 3, 
destructor: i=1
destructor: i=3

$ clang++ -std=c++03 -W -Wall -pedantic vec.cc 

$ ./a.out
default constructor
copy constructor: i=4202384
copy constructor: i=4202384
copy constructor: i=4202384
destructor: i=4202384
constructor: i=1
operator=(&): i=1
destructor: i=1
constructor: i=2
operator=(&): i=2
destructor: i=2
constructor: i=3
operator=(&): i=3
destructor: i=3
1, 2, 3, 
operator=(&): i=3
destructor: i=3
1, 3, 
destructor: i=1
destructor: i=3

$ g++ -std=c++11 -W -Wall -pedantic vec.cc  

$ ./a.out
default constructor
default constructor
default constructor
constructor: i=1
operator=(&&): i=1
destructor: i=1
constructor: i=2
operator=(&&): i=2
destructor: i=2
constructor: i=3
operator=(&&): i=3
destructor: i=3
1, 2, 3, 
operator=(&&): i=3
destructor: i=3
1, 3, 
destructor: i=1
destructor: i=3

$ clang++ -std=c++11 -W -Wall -pedantic vec.cc

$ ./a.out                                     
default constructor
default constructor
default constructor
constructor: i=1
operator=(&&): i=1
destructor: i=1
constructor: i=2
operator=(&&): i=2
destructor: i=2
constructor: i=3
operator=(&&): i=3
destructor: i=3
1, 2, 3, 
operator=(&&): i=3
destructor: i=3
1, 3, 
destructor: i=1
destructor: i=3

結構違うもんやな(小並感)

元々、std::vector::erase()でコピーコンストラクタが呼ばれてないのを見て、不思議に思ったのが発端だったけど、それに関しては単にoperator=(const T &&)が呼ばれる、ということのようだ。

vのコンストラクタの挙動が03と11で異なるのは意外。03の方はstd::vector(size_type, const T & t = T())になっていて順次コピーしているように見えるが、11ではすべてデフォルトコンストラクタが呼ばれている。std::vector(size_type)が、std::vector(size_type, const T &)とは別に用意されているのだろうか。

規格と実装を見ながら比較できればいいんだけど、ちょっと時間がないのでここまで。

neocomplcache-snippets-completeをつかう

いつまでもzencoding.vimで無理やりスニペット入力するのはどうかと思ったのでneocomplcache-snippets-completeに移行しました。

tex.snipはこんな感じ。

snippet align
alias   \begin{align}
	\begin{align}
		${1}
	\end{align}

snippet aligns
alias   \begin{aligns}
	\begin{aligns}
		${1}
	\end{aligns}

snippet table
alias   \begin{table}
	\begin{table}[htbp]
		\begin{center}
			\caption{}
			\label{}
			\begin{tabular}{}
				${1}
			\end{tabular}
		\end{center}
	\end{table}

snippet figure
alias   \begin{figure}
	\begin{figure}[htbp]
		\begin{center}
			\includegraphics[width=0.7\textwidth]{${1}}
			\caption{}
			\label{}
		\end{center}
	\end{figure}

snippet thebibliography
alias   \begin{thebibliography}
	\begin{thebibliography}{99}
		\bibitem{${1}}
	\end{thebibliography}

snippet eqnum
alias   \renewcommand{\theequation}
	\renewcommand{\theequation}{\thesection.\arabic{equation}}
	\makeatletter
	\@addtoreset{equation}{section}
	\makeatother

snippet jsart
alias   \documentclass{jsarticle}
	\documentclass{jsarticle}
	\usepackage{amsmath,amssymb}
	\usepackage[dvipdfmx]{graphicx}
	\renewcommand{\theequation}{\thesection.\arabic{equation}}
	\makeatletter
	\@addtoreset{equation}{section}
	\makeatother
	\title{${1}}
	\author{}
	\date{}
	\begin{document}
	\begin{abstract}
	\maketitle
	\section{}
	\begin{thebibliography}{99}
	\bibitem{}
	\end{thebibliography}
	\end{document}

snippet jart
alias   \documentclass{jarticle}
	\documentclass{jarticle}
	\usepackage{amsmath,amssymb}
	\usepackage[dvipdfmx]{graphicx}
	\renewcommand{\theequation}{\thesection.\arabic{equation}}
	\makeatletter
	\@addtoreset{equation}{section}
	\makeatother
	\title{${1}}
	\author{}
	\date{}
	\begin{document}
	\begin{abstract}
	\maketitle
	\section{}
	\begin{thebibliography}{99}
	\bibitem{}
	\end{thebibliography}
	\end{document}

とりあえずコードだけ入れておき、キャプションなんかは後で調整することが多いので、プレースホルダは少なくしています。

また、別途plugins.vimを作って.vimrcからsourceします。

if has('win32') + has('win64')
    let g:neocomplcache_snippets_dir = expand('$HOME/vimfiles/snippets')
elseif has('unix')
    let g:neocomplcache_snippets_dir = expand('~/.vim/snippets')
else
    let g:neocomplcache_snippets_dir = expand('~/.vim/snippets')
endif
imap <C-k> <Plug>(neocomplcache_snippets_expand)
smap <C-k> <Plug>(neocomplcache_snippets_expand)
noremap es :<C-u>NeoComplCacheEditSnippets<CR>

Windowsの $HOME/vimfiles とかLinuxの ~/.vim は ~/Dropbox/.vimシンボリックリンクにしています。
plugins.vimの中ではNeoBundle関係の記述も入れて、必要なプラグインのロード・設定をまとめて書いています。今はpathogen.vimは使わなくなりました。
とはいえ、neocomplcacheneocomplcache_snippets_completeとzencodingしか入ってないのですが。

人気エントリー(笑)

tweetbuzzというサイトでtwitter上で言及された数を拾えるというので設置してみたけど、あんまり役に立たないなこれw
どうも短縮URLについて、対応してるドメインのみリンク先を拾うようになっているらしい。htn.toは対象外で、短縮されたURLのまま登録されている。使えないw


HTTPリクエスト飛ばしてステータスコード見るくらいはしてほしいなぁ。例えばhtn.toの場合は301 Moved Permanentlyを返すようだ。他のもだいたいそうなんじゃないかなぁ。

svn update; make; make install

最近作業をいろいろ自動化しようとしている。
不要な処理は回避したいのだが、makeの正否は返り値を見ればわかるし、

make && make check && make install

でいいけど、svn updateで更新されたのかどうかを調べる方法がわからなかったので、調べた。
最終的に↓こういう形になった。もっとスマートな方法があるのかもしれないけど。

cd $SRCDIR
REV=$(LANG=C svn info | grep ^Revision | awk '{print $2}')
svn update
REV2=$(LANG=C svn info | grep ^Revision | awk '{print $2}')
if [ $REV != $REV2 ]; then
    make && make install
fi


hgの場合は、$(hg id -n)でリビジョン番号が取れるので楽だった。gitはどうなんだろう。

コンパイル高速化比較メモ

開発に参加してる某プログラムパッケージのMLで、g++よりclangの方が速いぜ的な話が(Macユーザから)あり、一応Linuxでもソースにパッチを当てればclangでも通るようになった*1ので、コンパイル時間を比較してみた。あと 漢(オトコ)のコンピュータ道: MySQL 5.5をわずか30秒足らずでコンパイルするためのテクニック でccacheのことも知ったので、これも試してみた。

  • g++-4.4 vs. clang
  • with/without ccache

という2つの条件の組合せ。
Quad-coreの2cpuで計8coreなUbuntu Server 10.04.2LTSで実行。RAMは16GBで、十分にある。事前にaclocal/autoreconf/configureまで済ませてある状態。

$ time make -j9

で時間を計る。ccacheを使う場合は、実行前に

$ ccache -C

でキャッシュをクリアしておき、2回連続で試す。つまり、無キャッシュ状態と、完全にキャッシュが効いた状態を比較する。コードを含むヘッダを複数箇所でincludeしているコードが多い場合、無キャッシュでスタートしてもそれなりに効くはず。ccache分のオーバーヘッドの方が大きいかもしれないが。


コンパイラのバージョンは次の通り。実際にはこれにmpicxxをかませる。

$ g++ --version
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang++ --version
clang version 3.0 (trunk 129915)
Target: x86_64-unknown-linux-gnu
Thread model: posix
compiler ccache result time(sec.)
g++ no make -j9 931.26s user 80.92s system 434% cpu 3:53.21 total 931.26
g++ cleared make -j9 948.99s user 82.61s system 424% cpu 4:03.13 total 948.99
g++ cached make -j9 98.50s user 53.69s system 272% cpu 55.802 total 98.50
clang no make -j9 798.77s user 69.83s system 437% cpu 3:18.75 total 798.77
clang cleared make -j9 811.85s user 72.17s system 422% cpu 3:29.29 total 811.85
clang cached make -j9 95.60s user 57.89s system 308% cpu 49.716 total 95.60


うん、ccache使えばいいんじゃないかな……w
どうやらコード全体の中では何度もincludeされてその都度コンパイルされている部分というのはccache自体のオーバーヘッドよりも少ない程度のようだ。
しかし一度キャッシュが効いてしまえば圧倒的に速い。確かにclangはg++より速いのだが、そんなのは誤差であった。

*1:動作は若干怪しい(特定のinputで計算結果がおかしい)ため、このまま使えるわけではないが……

跳.jp化してtweetするbookmarklet

http://d.hatena.ne.jp/CenterC/20101220/1292846019魔改造
Chromeっていつの間にか結構長いbookmarkletでも動くようになってた。以前は結構制限厳しい時期があったような……

javascript:function cbac(res){var d=document;var v=d.createElement('div');var a=d.createElement('a');a.href=encodeURI('http://twitter.com/?status= '+res.shorten+' "'+d.title+'"');a.target='_blank';a.onclick=function(){d.body.removeChild(v)};a.style.margen='50% 0px';a.style.backgroundColor='white';a.style.color='blue';a.style.fontSize='xx-large';a.style.textAlign='center';a.appendChild(d.createTextNode('tweet for "'+d.title+'"'));v.style.position='absolute';v.style.top=d.body.scrollTop;v.style.left=0;v.style.zIndex=256;v.style.width='100%';v.appendChild(a);d.body.appendChild(v);}(function(d){var s=d.createElement('script');s.setAttribute('src','http://跳.jp/api.jsonp?url='+location.href+'&callback=cbac');d.head.appendChild(s);})(document);

無駄な装飾が入ってるから長くなるのだけど。
実行するとページの一番上に、白背景に青文字の"tweet for なんちゃら"という(font-size:xx-largeの)リンクが出てくるので、クリックするとついったーが別窓で開く。
クリックとともに出てきたリンクは消える。
それだけ。
style関連いじってるあたりをテキトーに書き換えれば見た目も変えられる。


一応、同内容で見やすくしたもの。

javascript:
function cbac(res){
  var d=document;
  var v=d.createElement('div');
  var a=d.createElement('a');
  a.href=encodeURI('http://twitter.com/?status= '+res.shorten+' "'+d.title+'"');
  a.target='_blank';
  a.onclick=function(){d.body.removeChild(v)};
  a.style.margen='50% 0px';
  a.style.backgroundColor='white';
  a.style.color='blue';
  a.style.fontSize='xx-large';
  a.style.textAlign='center';
  a.appendChild(d.createTextNode('tweet for "'+d.title+'"'));
  v.style.position='absolute';
  v.style.top=d.body.scrollTop;
  v.style.left=0;
  v.style.zIndex=256;
  v.style.width='100%';
  v.appendChild(a);
  d.body.appendChild(v);
}
(function(d){
  var s=d.createElement('script');
  s.setAttribute('src','http://跳.jp/api.jsonp?url='+location.href+'&callback=cbac');
  d.head.appendChild(s);
})(document);

追記

書き忘れてたけどChrome10以外では動作確認してないので、動かなかったら動くように各自で書き換えてくださいね(ぉ

追記(2011/04/01)

表示位置の一番上にリンクを出すように変更。

思想地図β vol.1 対談から考える非実在青少年問題

思想地図β vol.1

思想地図β vol.1

巻頭対談、巻頭言、アニメージュオリジナル特別版だけ読んだ。残りはおいおい読む……かもしれない。


p. 7

いままで思想や批評に、そして言論一般に関心を抱かなかった人々にこそ、手にとってほしいと願っている。

とのことで、実際ぼくはそういうカテゴリに属するのではないかと思う。およそ思想・批評・言論といったものに関係する書物としてはほぼ初めて購入した。
こういった分野に対する関心を最初に持ったきっかけは、おそらくは、ねとすたシリアスで、その後、ロージナ茶会ちゃんねるなどを見つつ、それっぽい人たちをtwitterでfollowしつつ、のような感じ。


この本を買った最大の動機は、単純に巻頭対談を読みたかったから。(一部の)世間で物議を醸す例の条例について、提案側である都・クリエイター・批評家・未成年の子を持つ親であるところの当事者達はどう思っているのか知りたかったから。
それで、読んでみたのだけど……


まず感じたのは「意味が分からない」だった。一番最初の東氏の(座長的な立場としての)導入めいた一連の言葉がまずわからない。「こりゃ相当なリテラシーが要求されるな」と思った。
リトルボーイ的なもの」って、そこにダブルミーニングを見いだすことにどういう意味があるのか、単なるこじつけとしか思えない。しかしなんとなくわからなくもないというか、こじつけなのは承知の上で、そこに繋がりを見いだすというか、逆に定義づけのような形でその繋がりを何かの材料のように俎上に載せることによって見えてくるものがあるのかもしれないな、とは思った。結局のところ何が見えるのかはわからなかった、ということ。
次に、「話がかみ合ってない」と思った。これはぼくにリテラシーが足りないからだと思うが、話があちこちに飛んでいて、繋がりが全く見えなかった。これで互いに納得して和気藹々になる理由がさっぱり掴めない。特にブランド論の流れは完全に意味不明だった。リテラシーというよりも視野の問題なんだろうか……


ということで、以下、ろくに理解していないという前提の下で。
結局のところ、猪瀬氏(というか都)のモチベーションは「棚問題」であって規制ではない、とはいうものの、実際に審議会による恣意的な運用が可能で、条例の文章自体では規定しておらず、であるが故に出版社側は(資本主義下での会社組織として否応なく)自主規制を強めざるを得ず、それで食えなくなる作家が少なからず出てくる、という問題意識への解答にはまったくなっていないように見える。
しかし逆に考えると、現在の出版界での表現は商業主義に走りすぎ、エロければ売れるからもっとエロくしよう、ということでしかなく、その結果小学生に悪影響があるのであれば、そこには抑制が必要だ、というのもわかる。エロさだけで即物的に儲けても良いが、全年齢を巻き込むな、という趣旨だろう。おそらく「傑作」関連の言説もそのあたりが念頭にあるのではないかと思う。
都としては、「どんな言論表現も自由であり、出版差し止めなどはしない。しかしゾーニングは確実に」という立場なのだろう。
創作者側としては、「ゾーニング指定されると取次でも書店でも扱いが非常に小さくなり、ペイしなくなって生活できない」「ゾーニング指定されないために、作品内容自体を変更しなければならない」ということで、わりと実際的な問題ではある。


「両さんが普通の生活しか送れなくなる」問題で考えれば、もし「こち亀」が不適切だと審議会に判定された場合、秋本治氏および集英社には2つの選択肢があり、1つは「週刊少年ジャンプでの連載を諦め、内容そのままに(小口止めされた)青年誌に移る」、もう1つは「両さんに普通の生活を送らせて週刊少年ジャンプでの連載を続ける」。
前者の選択肢があるから表現の自由は損なわれていない、たとえ青年誌に移っても「傑作」であれば同等に売れるだろうし、それを求めないのは作家の怠慢、というのが都の論法だろうと思う。
後者は、はっきり言って論外だろう。そんな「こち亀」を誰が読みたいものか。実行されたが最後、いかに長寿連載といえどもあっというまに打ち切りになってしまうだろう。従って作品自体を終わらせない為には、前者を選ばざるを得なくなる。
しかし週刊少年ジャンプに比肩する発行部数の小口止めされた青年誌なんて存在するんだろうか。いかに傑作であろうとも、やはりメディア露出というのは重要だと思う。
「ジャンプ並の露出を持ち、創作者が生活できるだけのマネタイズが可能な、ゾーニングされたメディア」が存在しさえすれば解決する問題ではあるが、現時点で存在しない以上は、やはり条例によって食えなくなる作家が大量に発生することは想像に難くない。


漫画・アニメに限らず、小説・映画・演劇・音楽のような創作一般にすら限らず、スポーツやダンス、武術、科学技術など、あらゆる事柄でそうだと思うのだが、頂点の質は裾野の広さで決まると思う。
それに携わる人口が多ければ多いほど、トップレベルの人々が織りなす技は優れたものとなる。また、人々はそれを優れていると認め、産業として成り立っていく。
ゾーニングは、少なくともその裾野を切り取る。


そもそもゾーニング自体が、大人の、親のエゴである、というのも一面としてあるだろう。
後退する東京都の性教育 - Togetter
こういう状況は明らかに行き過ぎで、当の子供達のためにならない。
マトモに性教育を施さず、しかも性行為による被害から守ろうとするから、子供に対する過剰な表現摂取規制を施さざるを得なくなる。ちゃんと教育した上で与えればよい。例えば、中学校で確実に教育し、それが完了している15歳以上なら、何でも見て良い、ということもできるはず。ちゃんと教育していれば。
実際のところ中学校での保健体育の授業は機能していないだろう。自分の記憶でも、ほとんどスポーツだけが趣味だから体育教師になったような男が、似合わない照れ隠しをしつつぐだぐだとやっていたような印象しかない。少なくとも、体育と保健は切り離した方が良いと思うのだが……


とまぁ、あれこれ考えたけど結局どうすりゃいいんだかわからないなぁ……
銀の弾丸」になりそうなのは、

  • ジャンプ並の露出を持ち、創作者が生活できるだけのマネタイズが可能な、ゾーニングされたメディア
  • 小中学校でのマトモな性教育・暴力教育

あたりだろうけど、どちらも所詮はファンタジーの産物だろう。


後半ほとんど思想地図β関係ねぇな(´・ω・`)