プログラマの端は書き捨て。
kosen13s' Advent Calendar 2016 (http://www.adventar.org/calendars/1855) の 3 日目の記事です。
これは供養です!
先日、半年ほど使っていた Xubuntu 15.10 の仮想マシンに別れを告げ Xubuntu 16.10 に乗り換えたのですが、 前のディスクの tmp ディレクトリに大量のプログラムが書き捨てられていました。
人からの相談や、耳にした tips などを tmp に投げ入れているため、 もう用のないコードではありますが、もしかしたら誰かの知見になりうるかと思うので、公開します。
ただし、本当に意味のわからないコードもあるので、紹介するのは一部だけです。
/0523
C++ の deprecated を用いたコンパイル時型表示のプログラムです。
#include<bits/stdc++.h> class H{}; template <class T> [[deprecated]] void chk_type(T t){} int main(){ auto cache = new std::unordered_map<int, std::weak_ptr<const H>>; chk_type(cache); }
これをコンパイルすると
a.cpp: In function ‘int main()’: a.cpp:10:19: warning: ‘void chk_type(T) [with T = std::unordered_map<int, std::weak_ptr<const H> >*]’ is deprecated [-Wdeprecated-declarations] chk_type(cache); ^ a.cpp:6:21: note: declared here [[deprecated]] void chk_type(T t){} ^
このような警告が出て、 cache の型の推論結果が表示されます。 一節には、そこらの IDE では推論できない推論結果まで教えてくれるらしいです。
/0830
https://speakerdeck.com/greymd/mei-ri-kou-keru-sieruyun-wojue-eyou?slide=31 これで遊んでた時の残骸だと思う。シェル芸いいよ。 xaa ってこれわけわからずに split 打った出力だよなあ。
% ls 0830 fuga hoge holidays xaa
あと、同時期に "man コマンドクイズ" ってのにもはまってました。
man vim
を実行すると
vim - Vi IMproved, プログラマのテキストエディタ
と表示され、 vim はエディタであるとわかるのですが、
man emacs
を実行すると
emacs - GNU project Emacs
と表示され、「Emacs は Emacsだ」という強い意志を感じることができます。
/0904
C++ のラムダ式は関数ポインタに突っ込めるんだなあ・・・。 これで最適化を封じて時間計測する、みたいな技があると聞いた気がする。
#include<iostream> using namespace std; int main(void){ int (*hoge)(int) = [](int n){ return n*n; }; cout << hoge(10) << endl; }
/0921
mkfifo
ってコマンドを使うと名前付きパイプっていう面白いファイルを作ることができます。
もしかしたら環境によってコマンド名は違うかも。
% ls 0921 echo hello fifo| hello@ p| preprocess.c
何ができるかは説明すると長くなるんだけど、2つのプロセスからこのファイルへの書き出しと読み出しが両方行われた時に初めて、2つのプロセスに書き出しと読み出しを行わせる(それまではブロックする)っていう挙動をします。
何に使えるかわからん。
/1024
やさしい C のポインタのお話。 言いたいことはすべてコメントになってる。
#include<stdio.h> int main(){ char h[4]; h[0] = 1; h[1] = 2; h[2] = 3; h[3] = 4; // ポインタなんて所詮整数だからビット演算にかけられたりするよ printf("%p, %zu\n", h, (size_t)h); printf("%d\n", *(char*)((size_t)(h+3) & (-4))); putchar('\n'); // ポインタなんて所詮その変数が格納されている"先頭の"アドレスでしかないから、サイズの違う型のポインタにキャストしてやればもともとの変数の境界なんてうやむやにできるよ *((short*)h+1) = *(short*)h; for(int i=0; i<4; i++) printf("%d\n", h[i]); putchar('\n'); // short はここでは 2 バイト整数型として、それらを 1 バイトずつ表示。リトルエンディアン方式により下位のバイトが先行するのが見える short a = 258; printf("%d, %d", *(char*)&a, *((char*)&a+1)); }
この話を後輩に面白く話せるようになれたらいいなあ。 このコードが欲しければ好きに持って行ってください。
/1119
split
コマンドの挙動を調べたくなったので、
sudo apt-get source coreutils
してソースを拾ってきました。
いろんなコマンドの実装が読めて楽しいです。
% ls 1119 coreutils-8.23/ coreutils_8.23-4ubuntu2.dsc hgoe xaa xac coreutils_8.23-4ubuntu2.diff.gz coreutils_8.23.orig.tar.gz pipe/ xab xad
あとがき
思ったより何書いてるかわからないものが多くて抜粋に苦労しました。 広く浅く、いろんな言語、いろんな分野をやっているので、 面白い tips をご存じの方はぜひ教えて下さい!