C/C++

East Asian Ambiguous Character Width の確認を ICU4C で行う

特にターミナル上で作業するにあたり、East Asian Ambiguous Character Width 問題は頭がいたい。以下は vim のスクリーンショット。■とα、きれいに表示されているだろ。ウソみたいだろ。全角なんだぜ、それで・・・*1 という訳で、文字種によって、East Asi…

gcc のリンカエラーはライブラリ指定が末尾にないため

リンカのエラーが発生した場合のオプションを末尾に記述しなければいけない理由は不明です。 Cygwinでのncursesの使用について - あいや☆ぱぶりっしゅぶろぐ! うわ、これは知らなかった・・・。1 時間以上ハマってしまった・・・。

printf と write の同期

フレームワークが write システムコールで標準出力にログ出力、そのフレームワーク上で動作するアプリケーションは printf で標準出力にログ出力し、アプリケーションはマルチスレッドで動作するというケースにおいて、write の出力が printf の出力で潰され…

構造体のメンバのオフセットを取得する offsetof

Android のソースツリー内に頻繁に見かけられる offsetof というマクロ。構造体のメンバのオフセットを取得するマクロなんだけど、よく考えられてるなと感心した。 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) もっとも、構造体のオフ…

boost::filesystem で ~ ディレクトリを作ってはいけない

よくあるアプリ固有の設定ファイルを保持するディレクトリを、ホーム以下に以下のように Boost のライブラリを使用して作ろうと思ったら・・・ boost::system::error_code ec; const boost::filesystem::path dir("~/.hoge"); const boost::filesystem::file…

C/C++ でファイルサイズ取得

C/C++ を使用して、ファイルサイズを取得する方法の備忘録。 // g++ getFileSize.cpp -lboost_system-mt -lboost_filesystem-mt #define CAN_CUST_FPOS_TO_LONG 0 #include <stdio.h> #if CAN_CUST_FPOS_TO_LONG unsigend long getFileSize1(const char *fileName) { </stdio.h>…

フィボナッチで各種言語をベンチマーク

AWK、Ada、Bash、Boo、C、C#、C++、Clojure、D、Erlang、Forth、Fortran、Go、Groovy、Haskell、Io、Java、JavaScript、Lisp、Lua、OCaml、Objective-C、PHP、Pascal、Perl、Pike、Prolog、Python、R、Ruby、Scala、Scheme、Smalltalk、Tcl でフィボナッチ数…

Labels as Values による Compiled goto でインタプリタを高速化

Android のインタプリタは C で実装されたバージョンとアセンブラで実装されたバージョンがあって、どちらもインストラクションを goto で処理するように実装されている。ずっと気になっていた C の goto の仕組みを調べてみた。単純化したのが以下の擬似コ…

C 言語における最適化を抑止する

C 言語の最適化抑止について調査した。ローカル変数のアドレスを関数外部にリークさせた場合、volatile がなくても最適化が抑止されるのではないか、という仮説を証明するためだ。環境は以下のとおり。 Ubuntu 12.04 LTS gcc 4.6.3 検証するコードは以下のと…

C 言語のマクロで関数をオーバーライド

マクロで関数をオーバーライド。 #include <stdio.h> void foo() { printf("foo\n"); } #define foo() printf("FOO\n") int main(int argc, char *argv[]) { foo(); #undef foo foo(); return 0; } 上記を実行すると: FOO foo と表示される。ポイントは undef の使い</stdio.h>…

Eclipse CDT で参照を解決できない

単純なコードだと問題がなかったんだけど、ソケットを使用するコードで以下のように sys/socket.h に定義されているはずの定数が CDT 上では解決できない。Windows の CDT は GNU C という環境が定義されていて、cygwin を参照するようになっている。インク…

C におけるデバッグ出力のジレンマ

「開発中にデバッグログを出力したい。でもリリース時には出力したくない」、というような要求はかなりの頻度である。こんな感じでやることになるだろう(デバッグとリリースを切り分ける #ifdef は省略)。 #include <stdio.h> #include <stdarg.h> #define debug1(fmt, ...) p</stdarg.h></stdio.h>…

boost 1.48.0 ビルド方法

boost のビルド。数年ぶりですっかり忘れていたのでメモ。 ソースコードをダウンロード。今回はここから 1.48.0 をダウンロード bjam をビルドするか持ってくる。今回はここから 3.1.18 をダウンロード bjam を boost のトップディレクトリにコピー Visual S…

C のプリプロセッサでは文字列が扱えない

以下のコードはコンパイルが通らない。 #include <stdio.h> #define ABC "abc" //#define ABC 1 int main(int argc, char *argv[]) { #if ABC==ABC printf("ok\n"); #endif return 0; } コンパイルエラーのメッセージは以下のような感じだ。 ppt_test.c:6:5: error: t</stdio.h>…

メモリをファイルのように扱いたい

ファイルをメモリのように扱うのは mmap、ではその逆で、メモリをファイルのように扱いたい場合は・・・?fmemopen や open_memstream という関数を見つけたけど、FILE ポインタを返す関数ではなくディスクリプタを返す関数が希望。 なんでそんなことをした…

影響ないはずのコードがベンチマーク結果に影響を及ぼす原因

C で書いたプログラムを、各リリースに対してベンチマークをとってみたら、前回だけ明らかに遅くなっている。今回は元通りに戻っている。およそ 18% 低下していて再現性もあるので、誤差ではなく、原因調査をしてみた。一時的に遅くなって、元に戻っているの…

GNU Make のプリプロセッサ ifeq で or 条件をしたかった

以下のような Makefile で ifeq (($version),1) CFLAG += -DVERSION=($version) -DFOO -DBAR else ifeq (($version),2) CFLAG += -DVERSION=($version) -DFOO -DBAR endif endifversion が 1 か 2 の時に、コンパイルスイッチを追加したい、という要求がある…

解放する資源が何もないなら、デストラクタは不要

こんなクラスがあったとします。 class Person { public: std::string name; size_t age; };ヒープ上にインスタンスを作らないので、コンストラクタは必要ありません。もし、 Person *p = new Person;などのように、ヒープ上にインスタンスを作りたいなら、…

std::vector に入れる独自クラスにはデフォルトコンストラクタが必要

std::vector に独自クラスを入れる場合、デフォルトコンストラクタとコピーコンストラクタが必要不可欠だ。 #include <iostream> #include <vector> class Foo { public: int i; Foo() : i(0) { std::cout << "default" << std::endl; } Foo(int num) : i(num) { std::cout << </vector></iostream>…

!0 のビットパターンと C における bool

C99 からは C 言語で bool が使用できるが、互換性のため、以下のようなコードが書かれることが多い。 #ifdef HAVE_STDBOOL_H #include <stdbool.h> #else typedef enum { false=0, true=!false } bool; #endif ここで気になるのは、 true=!false の部分で、これはいっ</stdbool.h>…

ビットフィールドのためのポータブルなコード

ビットフィールドは、構造体のサイズをコンパクトにするために便利な仕組みだ。 typedef struct { int bar: 24; int baz: 8; } Foo; 32 ビット環境なら、こんな構造体だと、この構造体は 4 バイトですむ。ただ、24 ビットとか 8 ビットというような環境に依…

i++ と ++i、++i の方が高速という都市伝説を解明

昔、ある時、ふと気がついた。 int i; for (i = 0; i < 10; i++) { } for (i = 0; i < 10; ++i) { } 同じ動作をする for ループなんだけど、i++ と ++i の部分で、i++ の方が処理に無駄がある(下の値とインクリメントした値の両方を保持しなきゃならない)…

Windows Vista と Windows 7 の互換性モード

今日ひとつわかったことがあるので、ここに覚書。Windows Vista と Windows 7 には、プログラムを実行する際に、互換性モードで実行することが可能なんだけど、その互換性モードで実行されたプログラムが何をしているか、というの(のひとつ)が GetVersion …

pthread_exit を明示的に呼びたいけど、警告も出したくない

こんなコードがあったとして #include <pthread.h> void *sub(void *unused) { pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t thread; pthread_create(&thread, NULL, sub, NULL); pthread_join(thread, NULL); return 0; } これをこのようにコ</pthread.h>…

strtol と integer constant(整数定数)

手元にある「ANSI C 言語大辞典」によると、strtol は base が 0 であれば、strtol は整数定数の形式を読み込む。 と書かれていて、じゃあ整数定数は何かというと 0xFFFE 12345UL というような表記形式である。 簡単なテストをしてみたら、手元の gcc で期待…

文字列配列の初期化とサイズ

文字配列の初期化は、文字列リテラルを使用すると最後に NUL 文字が付与されます。 #include <stdio.h> int main(int argc, char *argv[]) { char a[] = "abcde"; char b[] = {'A', 'B', 'C', 'D', 'E'}; printf("a:%d b:%d\n", sizeof(a), sizeof(b)); return 0; } </stdio.h>…

C における代入式の左辺と右辺の評価順序 #2

C と Java における代入式の左辺と右辺の評価順序 は副作用完了点の完了までの間に、被副作用オブジェクトを複数回参照しているために発生する問題で、こうしたコードは動作未定義という扱いになってしまう。 a[i] = ++i; これは単に以下のように書き直せば…

C と Java における代入式の左辺と右辺の評価順序

#include <stdio.h> int main(int argc, char *argv[]) { int a[2] = { -1, -1 }; int i = 0; a[i] = ++i; printf("a[0]=%d\na[1]=%d\n", a[0], a[1]); return 0; } こんな短いコードを gcc と cl でそれぞれコンパイルして実行すると、gcc だと a[0]=1 a[1]=-1cl だ</stdio.h>…

gcc の最適化の罠

最近立て続けに GCC の最適化関連でバグが発生した。 三項演算子のネストを解釈しきれない int i = strcmp("abc", str) == 0 ? func0(str) : strcmp("def", str) == 0 ? func1(str) : strcmp("ghi", str) == 0 ? func2(str) : strcmp("jkl", str) == 0 ? fun…

プリプロセッサのトークン結合演算子「##」の仕様が不明

こんなことをしたい。 #include <stdio.h> #define FOO(name) int *__##name = &##name int main(int argc, char *argv[]) { int bar; FOO(bar); printf("%x\n", __bar); return 0; } これは cl(VC)だとコンパイルできて期待通りに動作するんだけど、gcc だとコンパ</stdio.h>…