C/C++

領域を固定パターンで埋める memfill

ある値で int 配列を埋めたい、構造体配列を初期化したい、なんて要求はざらにあるような気がするのだけれど、標準ライブラリーにはいってないのはなぜなんだぜ? 見たとおり、速度は O(log nmemb)。 void* memfill(void *ptr, const void *data, size_t siz…

#ifdef 分岐を制御するプリプロセッサー定義の探索

由緒正しいソースコードをメンテナンスしていると、大量の #ifdef 分岐に泣かされることが、よくある。よし、ソースコードや Makefile で定義されているプリプロセッサー(つまり #define や -D オプション)をあらかじめ列挙しよう! そうだ、分岐に使われ…

map のダンプ

std::map を使っていたとして、この中身をコンソールに出力したくなる、そんな場面はたびたびあるとおもう。 で、 C++ 使いとしては、すらすらとこんな具合に書けるようになりたいよね。 typedef std::map<std::string, int> my_map_t; struct my_pair_t : my_map_t::value_typ</std::string,>…

static_assert

あたらしい C 言語規格 C1X では、コンパイル時に評価可能な静的表明をソースコードに埋めておけるらしい。 うらやましい。 https://www.securecoding.cert.org/confluence/display/seccode/DCL03-C.+Use+a+static+assertion+to+test+the+value+of+a+constan…

static 宣言の後に extern 宣言しても大丈夫

static int N = 256; extern int N; と書くのは合法 (そして N は static)。 妙だ。 非常にむずがゆい。逆はダメ。 つまり extern int N; static int N = 256; と書くとエラー。

簡易メモリー使用量計測器

リークしてるんじゃない? ということで、簡単に現時点でのメモリー使用量のスナップショットを取りたくなった。Linux なら /proc/[pid]/statm を参照するのが簡単だということでこんな感じのユーティリティーを実装。 #include <unistd.h> // for getpid() #include <memory> </memory></unistd.h>…

ARM の関数呼び出し

ARM の関数呼び出し、正確には関数呼び出しからの戻りかたの処理がおもしろかたのでメモしておく。お試しソースはこれ。: /* fcall.c */ int foo() { return 1; } int simple_call() { const int v = foo(); return v; } int call_twice() { return foo() +…

同名のシンボルを持つ同名のライブラリーをリンクしたライブラリーを dlopen したときの名前解決

昨日のエントリーのあとで、では dlopen/dlclose で明示的にリンクしたらどうなるか? という疑問がわいたので引き続いて調査。 (リンカー・ローダーのソースを読まずに動作から確認している…というあたり、弱いなあ)main というアプリケーションが one/li…

同名のシンボルを持つ複数のライブラリーをリンクしたときの名前解決

GOT やリンカー・ローダーの仕組みを考えれば、そうなるかな、と納得はできるんだけれど、たいそうショックを受けたことがら。次のような三つのソースを用意する。 /* a.c */ int puts(const char *str); void foo() { puts("hello"); } void bar() { foo();…

const 宣言できたとしても、すべきでない場合

例として次のような int をラップしているだけの Number クラスを考える。 class Number { int *const v; public: Number() : v(new int(0)) {} ~Number() { delete v; } void set(int value) const { *v = value; } int get() const { return *v; } }; ここ…

関数引数で初期化される変数と戻り値をともにクラスの const メンバーにしたい

C/C++ の関数は複数の値を戻すのが苦手なので、たいていのプログラマーは関数の引数を戻り値を格納する場所として使う方法に染められていく。 /* create new Object and returns its id */ Id object_initialize(/*[out]*/ Object** object); さて、この Id …

初期化リストにおける基底クラスの初期化順序

基底クラスの初期化につづけてメンバー変数の順で初期化されるから注意しましょうという話。テストケースをつくるときに、にかよった設定をするオブジェクトがたくさんあるので、そのベースクラスをつくり、ちょっとした違いを派生クラスでカバーしようと考…

コマンドラインのプリプロセッサー定義で文字列を渡す

$ cc -o hello hello.c -DHELLO="\"hello, world!\"" $ ./hello hello, world!などと、コンパイルオプションで渡した文字列をソースコードで使うにはどうしたらいいか?解答編: #define quote(x) q(x) #define q(x) #x #include <stdio.h> int main() { puts(quote(H</stdio.h>…

コンテナと for ループ

次のようなコード断片、 iterator を明示的に使う for ループが見苦しく感じる。 void hexstr( const std::vector<unsigned char>& bytes, std::vector<char>& out) { for(std::vector<unsigned char>::const_iterator iter = bytes.begin(); iter != bytes.end(); ++iter) { int byte = (int)*it</unsigned></char></unsigned>…

エラーメッセージ

標準ライブラリーで使われるエラー番号 errno、これの定義はもちろん errno.h にある。標準エラー出力に errno の値を %d あたりで出力してしまってから、 errno.h やら asm-generic/errno-base.h を眺めてどんなエラーかを翻訳する…ということをしがちな自…

バッファ内容の16進ダンプ

大好き車輪の再発明の時間がやってきました…。バッファ内容を 16 バイトごとにダンプするコード。 テストコードも書かずにざっと書き下しておもったとおりに動いたのがうれしくて、記録を残しておきたくなった。 static void dump(size_t offset, char *buf,…

脆弱性クイズ

過去の日報を読み返していたら、自分のメモにこんなものを発見した。: //脆弱性クイズ! -- 以下のコードの問題点と、改善案を述べよ (10点) void quiz(char c) { char buffer[4]; sprintf_s(buffer, "%3.3o", c); // ... (snip) ... } …ぱっと見て、すぐに…

16進バイト列を10進数文字列に変換する

8 バイトの数値を 10 進文字列に変換するなら glibc の sprintf に書式文字列 "%llu" を与えて得られることはわかったんだけれど、任意長のバイト列を 10 進数文字列に変換するって、できるかな?というチャレンジが心をよぎったのでやってみた。 #include <vector> </vector>…

16進テキストをバイナリーに変換する

"hexdump -C" といったコマンドでバイナリーファイルを 16 進数テキストに変換することはできるのに、その逆はないよねえという話になった。そしてたしかに知らない。あれば便利なのに…。ということでみんな大好き再発明のお時間です。: // hex2bin.cc #incl…

「情熱プログラマー」にあった、 99 bottles of beer を代入なしでコーディングするの巻

C++ の string クラスを連結につかい、ループは再帰呼び出し実現。関数型言語での常道を C++ に持ち込んだ一品です。 string オブジェクトを作っては廃棄し、廃棄しては作ってと、富豪プログラミング的側面も兼ね備えています。今回のように代入禁止縛りがな…

SALとソースコード解析

マイクロソフト C コンパイラーによるソースコード静的解析 Microsoft Windows SDK に付属の C コンパイラー (cl.exe) ではソースコードの静的解析機能が利用できます。 コンパイラーの起動オプションに /analyze を追加すると、バッファの境界検査や書式文…

Microsoft Security Annotation Language (aka SAL)

http://blogs.msdn.com/michael_howard/archive/2006/05/19/602077.aspx# SALがどのように使われるものかを解説した記事。2006年か。ずいぶん昔だ http://blogs.msdn.com/sdl/archive/2009/06/11/a-declspec-sal-to-attribute-sal-rosetta-stone.aspx 上述の…

「テスト駆動開発入門」の xUnit 実装を C++ でしてみる

ケント・ベック「テスト駆動開発入門」の第 2 部をもとに C++ 版のユニットテストフレームワークを実装する一連の流れをまとめてみた。 xUnitへの第1歩 (第18章) 以下がテストフレームワークをつくるためのTODOリストだそうである。 テストメソッドを呼び出…

仮想継承

C++ の場合、同じクラスを継承する場合に明示的に virtual 修飾することではじめて仮想継承が有効になる。 クラス A を継承するクラス B と C があって、これらふたつを多重継承するクラス D において、基底クラス A を唯一にしたい…次のような継承関係を実…

ビットフィールド

ビットフィールドが int に制限されていることを知らなかった。今後気をつける。 ビットフィールドの型は,int,unsigned intのいずれか一つの修飾版又は非修飾版でなければならない。 6.5.2.1 構造体指定子及び共用体指定子 -- X 3010-1993(ISO/IEC 9899:19…

構造体メンバーの並び順

構造体オブジェクト内では,非ビットフィールドメンバ及びビットフィールドが置かれる単位は,、宣言された順に増加するアドレスをもつ。構造体オブジェクトへのポインタは,適切に変換すれば,その先頭メンバ(又はビットフィールドならば,それが置かれた単…

モンティ・ホール問題

モンティ・ホール問題についてくわしくは Wikipedia を読んでもらうとして、モンティがあけなかった扉を選んだ時に、もとの扉のままの二倍の勝率になる、ということをモンテカルロ法によって確認できないかとざっとコードを書いてみた。 自分が選んだ最初の…

スタックプロテクターは alloca 割り当てを使うプログラムも守ってくれるか?

先だって同僚からそんな疑問を受け、気になっていたので調べた。結論から言うと、守ってくれる。 そもそもスタックプロテクターは、関数呼び出し時にスタックフレーム内の戻りアドレスの直上にカナリア変数を置き、呼び出し元に返る前にカナリア変数がオーバ…

snprintf の戻り値

C99 規格で定義されている snprintf は、二番目の引数でバッファサイズを受け取る。その戻り値はバッファサイズを超えうる、ということを昨日知った。というのは、戻り値はフォーマットした結果あるべき出力結果の文字列長さを返すから。つまり、次のソース…

#if 0 hacks

ネタ元: d:id:Seasons:20090504:1241390314 さっそく試してみた。たしかに楽しい。 $ cat << EOF > a.c > #if 0 > src=\$0; dst=\${src%.*}; gcc -o \$dst \$src && ./\$dst; exit > #endif > #include <stdio.h> > int main(void) { return puts("hello, world."), 0</stdio.h>…