2007年12月22日

strchr() ではまった話

標準Cライブラリに strchr() という関数があります。文字列の先頭から指定した文字を探すという単純な関数なのですが、先日、意外な仕様を知りました。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2007年9月 8日

Unicode の文字列をソースコードに埋め込む方法

Unicode の文字列をソースコードに埋め込む場合、直接 UTF-8 などで文字列を書く方法と、\uXXXX などのようにエスケープして表記する方法があります。後者の方法についてまとめてみました。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2007年2月28日

浮動小数点演算ではまった話

浮動小数点演算のありがちな問題ではまりました。 いろいろ調べているうちに x86 特有のちょっとおもしろい 現象に遭遇したので紹介したいと思います。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年8月10日

再入不可能な関数を C で実装する

一度実行したら二度と中身を実行できなくなる再入不可能な関数を C で実装してみます。通常、このような関数はシングルトンなどの静的なデータの初期化に使いますが、ここではデータについては考えないことにします。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年6月24日

memccpy() で文字列をコピーする

詳解Unixプログラミングを読んでいたところ、標準入出力ライブラリの章に「この例からわかることは、行単位の関数は memccpy(3) を用いて実装されていることである」という記述がありました。

一瞬、memcpy(3) の誤植かと思いましたが、調べてみると 4.3 BSD で追加された関数ということがわかりました。 glibc に入っているので Linux でも使えます。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年5月 3日

glibc の fopen() で 'm' オプションを使う

最近の glibc の fopen() には 'm' というオプションがあると知りました。 'm' オプションを指定すると、リードオンリーでファイルを開いたとき、可能な場合、 mmap が内部的に使われるようになります。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年4月28日

実行時のスタックの消費量を調べる

先日の記事では checkstack.pl を用いて個々の関数がどのくらいスタックを消費するか調べる方法を紹介しました。今回は、実行時の実際のスタック消費量を調べてみます。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年4月24日

checkstack.pl で関数のスタック消費量を調べる

Linux カーネルのソースコードに付属する checkstack.pl を使うと、C/C++ のプログラムの関数のスタック消費量を調べることができます。checkstack.pl は objdump -d のディスアセンブルの出力からスタックポインタの操作をパターンマッチしてスタックの消費量を計算しています。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年4月23日

子プロセスに LD_PRELOAD を継承させない

Linux で LD_PRELOAD 環境変数を使うと共有オブジェクト (共有ライブラリ) のプリロードを行うことができます。通常、LD_PRELOAD が設定されている間は、あるプロセスから呼んだ子プロセスも同様にプリロードを行いますが、場合によっては子プロセスにはプリロードさせたくないときもあります。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年4月22日

Cのポインタを整数に変換する

Cのポインタを整数に変換したいときがあります。このとき問題になるのは、ポインタのサイズが int と同じとは限らないということです。たとえば、 x86_64 の 64ビットのバイナリでは sizeof(int) = 4, sizeof(void *) = 8 となります。ポインタと同じサイズの整数を使いたい場合は C99 で導入された stdint.h で提供される intptr_t または uintptr_t を使います。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年4月 3日

Doug Lea の malloc (dlmalloc)

小さなオブジェクトを大量に new しまくるプログラムを C++ で書いたところ、処理時間の多くが malloc() に費やされていることがわかりました。このような場合、自前でメモリ管理を行って最適化するという方法がありますが、なかなか大変です。

そこで、安易に高速な malloc に置き換えてみようということで、 Doug Lea の malloc (通称 dlmalloc) の最新版を試してみました。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年2月22日

ライブラリの外に公開するシンボルを制限する

C言語にはファイル内 (コンパイル単位) からしかアクセスできない static 関数と、別のファイルからもアクセスできる非static 関数があります。しかし、ライブラリを作成する上では、この2つのスコープだけでは不十分なときがあります。

本記事では GNUの開発環境において、ライブラリの外に公開するシンボルを制限する方法を紹介します。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年2月19日

リンクされているライブラリによってプログラムの動作を変える

weak シンボルを用いると、リンクされているライブラリによってプログラムの動作を変えることができます。ここでは GNU 拡張を用いて weak シンボルを利用する方法を紹介します。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2006年2月 5日

Cのプログラムの中でブレークポイントを設定する

Cのプログラムをデバッグする際には GDB などのデバッガが役立ちます。通常、ブレークポイントはデバッガの中から設定しますが、デバッグ対象のCのプログラムの中で設定することもできます。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年12月19日

配列へのポインタと配列へのリファレンス

C/C++ のあまり使われない機能に、配列へのポインタと配列へのリファレンスがあります。ここでは、それらがどのようなものかまとめたいと思います。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年12月17日

main() の前に関数を呼ぶ

C/C++ のプログラムで、main() の前に関数を暗黙的に呼びたいときがあります。ここでは GCC の拡張を使った方法と、C++ のコンストラクタを使った方法を紹介したいと思います。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年12月 1日

こんなプログラムはいやだ: INT_MIN / -1

昨日とは別の知人から、INT_MIN / -1 を計算するとおもしろいことになると教えてもらいました。次の C のプログラムをコンパイルして実行するとどのような結果になるでしょうか。

#include <limits.h>
int
main ()
{
    volatile int a = -1;
    printf("%d\n", INT_MIN / a);
    return 0;
}
続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年11月30日

こんなプログラムはいやだ: 負の剰余

知人から次の式の計算結果はどうなるかという問題を出されました。

-3 %  5
 3 % -5
-3 % -5
続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年11月29日

こんなプログラムはいやだ: float++

次の C言語のプログラムをコンパイルして実行するとどうなるでしょうか。

int
main ()
{
    volatile float i;
    for (i = 0; i < 100000000; ++i);
    return 0;
}
続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年10月25日

普通のやつらの下を行け: Cで動的コード生成・実行

スクリプト言語には動的にコードを生成して実行する機能を持ったものが多くあります。 普通のやつらの下を行けの第3回として、今回は C による動的なコード生成と実行に取り組んでみたいと思います。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

普通のやつらの下を行け: C でバックトレース表示

普通のやつらの下を行けの第2回として、今回は glibc の関数を使って C でバックトレース (スタックトレース) の表示を行ってみます。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年10月24日

普通のやつらの下を行け: assert_caller()

以前に、低レベルプログラミングを愛好する知人が「普通のやつらの下を行け」を口癖にしていました。当時は何を言っているのかと聞き流していましたが、自分も最近になってようやく低レベルプログラミングのおもしろさがわかってきました。今回は「普通のやつらの下を行け」企画の第一弾として assert_caller() なるものを作ってみたいと思います。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年10月17日

GCC の最適化で printf が puts になる場合

GCC の最適化により printf の呼び出しが puts に置き換わることがある、と 先日、教えてもらったので試してみました。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク  

2005年10月10日

リンクと同名のシンボル

C や C++ のプログラムで同じ名前のグローバルなシンボルが 2つ以上存在するとどうなるでしょうか。 Debian GNU/Linux sarge + GCC 3.3.5 での動作を見てみます。

続きを読む...
投稿者 satoru : 固定リンク | このエントリーを含むはてなブックマーク