タグ

ブックマーク / 0xcc.net (12)

  • strchr() ではまった話 - bkブログ

    strchr() ではまった話 標準Cライブラリに strchr() という関数があります。文字列の先頭から指定した文字を探すという単純な関数なのですが、先日、意外な仕様を知りました。 以下のコードを見てみます。 if (strchr("+-*/", c)) { // c は四則演算の記号かな? ... } この if 文は c が + - * / のいずれかの場合に条件が真となり、ブロック中が実行されます。…と、思いきや、実は条件が真になるケースがもうひとつありました。c が '\0' の場合です。 まさかと思って手元の Linux の man を見ると、文字列の終端のナル文字 ('\0') の扱いは明記されていません。 The strchr() function returns a pointer to the first occurrence of the character c i

    nirvash
    nirvash 2007/12/23
    論理的にはあってるなぁ。罠罠。
  • 浮動小数点演算ではまった話 - bkブログ

    浮動小数点演算ではまった話 浮動小数点演算のありがちな問題ではまりました。 いろいろ調べているうちに x86 特有のちょっとおもしろい 現象に遭遇したので紹介したいと思います。 パーセンテージの計算 簡単な C のプログラムでパーセンテージを計算しようと思い、 次のようなコードを書きました。 int x, y; ... int a = (double)x / y * 100; int a = x * 100 / y としないのは、 x が大きい場合に x * 100 が オーバーフローを起こす (INT_MAX を越える) ためです。 このコードは一見、期待通りに動いていたのですが、 しばらく使っていると、手元の環境では x = 53, y = 100 のときに a は 53 ではなく 52 になることに気づきました。 これは次の理由によります。 式の最初の (double)53 / 10

  • prelink の効果を測定する - bkブログ

    prelink の効果を測定する prelink は大量の共有ライブラリをリンクしたプログラムの起動時間を短縮するためのツールです。最近の Linux で利用できます。Gentoo Linux Prelink ガイドによると「典型的なKDEプログラムの起動時間は50%も短縮することができます」とのことです。このエントリでは簡単なプログラムを書いて prelink の効果を調べる実験を行ってみます。 通常、動的リンクされたプログラムはシンボルの参照時に再配置およびシンボルのルックアップなどを行う必要があります。prelink は実行ファイルと依存する共有ライブラリを書き換えて、これらの処理を行う必要性を減らします。また、prelink されたプログラムはリロケーションによって発生する共有不可能ページが減るため、プロセス間で共有できるページが増えるというという効果もあります。 prelink

  • Binary Hacks の発売日決定 - bkブログ

    Binary Hacks の発売日決定 Binary Hacksの発売日が決まりました。 Amazon には 2006/11/14 とありますが、出版社に確認したところ、正式な発売日は 2006年 11月11日でした。めでたく1111というバイナリな発売日となりました。 Binary Hacks のアイディアをオライリーの方に話したのが、昨年 12月の Binary 2.0 カンファレンスにおいて。それか1年近くかかってしまいましたが、ようやく完成しました。 内容的に類書があまりないユニークな1冊に仕上がったと思います。 ぜひ、目次とはじめにをご覧ください。 ちなみに、書は qwikWeb を使って執筆しました。雑多な取りまとめと比較的簡単なところを私が担当し、高度な部分は他の方が書いています。「書に寄せて」は大変光栄なことに、川合史朗さんに寄稿していただきました。

  • 再入不可能な関数を C で実装する - いやなブログ

    再入不可能な関数を C で実装する 一度実行したら二度と中身を実行できなくなる再入不可能な関数を C で実装してみます。通常、このような関数はシングルトンなどの静的なデータの初期化に使いますが、ここではデータについては考えないことにします。 static 変数をフラグに使う まずは最も単純な方法から見ていきます。次の関数は static 変数をフラグに使って再入を防いでいます。厳密に言えば関数そのものには入ってしまっていますが、ここで気にしないことにします。 void once(void) { static int entered; // 最初は 0 if (entered == 1) { // すでに入ったことがある場合は return; // すぐ出る } entered = 1; // 初回の場合のみ、何かを実行する } この方法はシングルスレッドのプログラムではうまく動きますが、マ

  • gdb tips - bkブログ

    gdb tips gdb を使う上で便利な tips を紹介します。基的な使い方をマスターしている人向けです。 .gdbinit の設定 ホームディレクトリに .gdbinit を置いておくと、gdb の起動の際に読み込まれます。私の場合は次のような設定をしています。 set history save on set history size 10000 set history filename ~/.gdb_history set print pretty on set print static-members off set charset ASCII set history から始まる最初の 3行は履歴に関する設定です。それぞれ、 gdb のコマンドラインの履歴をファイルに保存する、保存する行は最大 10000 行、ファイル名は ~/.gdb_history 、という意味になります。

    nirvash
    nirvash 2006/07/18
    gdb tips。次 gdb 使うときに設定する
  • いやなブログ: Linux の共有ライブラリを作るとき PIC でコンパイルするのはなぜか

    Linux の共有ライブラリを作るとき PIC でコンパイルするのはなぜか 通常、Linux の共有ライブラリを作るときは各 .c ファイルを PIC (Position Independent Code) となるようコンパイルします。しかし、実は PIC でコンパイルしなくても共有ライブラリは作れます。それでは PIC にする意味はあるのでしょうか。 さっそく実験してみます。 int func () { printf(""); printf(""); printf(""); } PIC でコンパイルするには gcc に -fpic または -fPIC を渡します。-fpic の方が小さく高速なコードを生成する可能性がありますが、プロセッサによっては -fpic で生成できる GOT (Global Offset Table) のサイズに制限があります。一方、-fPIC はどのプロセッサで

  • C++ のシンボルをデマングルする - bkブログ

    C++ のシンボルをデマングルする C++ コンパイラはシンボルが一意の名前を持つように名前マングル (name mangling) と呼ばれる処理を行います。記事では GNU の開発環境で C++ のシンボルをデマングル (demangle) する方法を紹介します。 マングルの方法はコンパイラ依存です。同じコンパイラでもバージョンによってマングルの方法が異なることがあります。たとえば GCC 3.x では int foo(int) を _Z3fooi に、 int foo(const char*) を _Z3fooPKc のようにマングルしますが、 GCC 2.95 ではそれぞれ foo__FPCc, foo__Fi となります。 コマンドラインからデマングル C++ のオブジェクトファイルに nm をかけると、デフォルトではマングルされた読みづらい形式でシンボルが出力されます。 %

    nirvash
    nirvash 2006/06/23
  • いやなブログ: 配列操作の比較表: Ruby, Python, JavaScript, Perl, C++

    配列操作の比較表: Ruby, Python, JavaScript, Perl, C++ プログラムを書いていると、他のプログラミング言語の記憶とごっちゃになって、「配列の後ろに要素を追加するのは push だっけ、 append だっけ」などと混乱することがあります。特に Ruby, Python, JavaScript はコードの書き方が似ているので、この問題が起きがちです。 そこで、備忘録として、 Ruby, Python, JavaScript, Perl, C++ の配列操作の比較表を作りました。一番慣れている Ruby を基準にしています。間違いなどがあったらご指摘いただけると助かります。他の言語のもあるといいなあ。 Ruby (Array) Python (list) JavaScript (Array) Perl (@) C++ (std::vector)

    nirvash
    nirvash 2006/05/07
    [][][ruby][javascript][perl][python]C のvectorは指定した値で簡単に初期化できないのがいたいんだよな。
  • UTF-8 のオクテット数 - bkブログ

    UTF-8 のオクテット数 UTF-8 で表現した 1文字は最長で 6オクテット (バイト) と思っていたのですが、新しい方の RFC では 4 オクテットまでとなっているのを知りました。 RFC 2279 日語訳 (原文) UTF-8は、文字は1から6オクテット長に符号化される。 RFC 3629 日語訳 (原文) UTF-8において、U+0000..U+10FFFF範囲(UTF-16アクセス可能範囲)からの文字は、1から4までオクテットの連鎖を使って符号化される。 RFC 3629 の「RFC 2279からの変更点」を見ると「文字の範囲を0000-10FFFFに限定した (UTF-16アクセス可能範囲)」と説明がありました。新しい方といっても 2003年11月に公開されているので、もう2年近く経っているのですね。

    nirvash
    nirvash 2006/05/07
    UTF-8 で表現した文字は、実質最長4オクテットだよなぁ、と思ってたら後の RFC で 4オクテット二変更されていたのか。
  • いやなブログ: Binary 2.0カンファレンス 2005 発表資料とレポート

    Binary 2.0カンファレンス 2005 発表資料とレポート Binary 2.0 カンファレンス 2005 は大盛況のうちに無事終了いたしました。開催にご協力いただいた皆様、スピーカーの皆様、参加していただいた皆様、大変ありがとうございました。 当日の発表資料とレポートをこのエントリでまとめています。参加報告などはこのエントリへのトラックバックで受け付けています。よろしくお願いいたします。 Binary 2.0 時代の到来 - 高林哲プログラムはなぜ Mona OS で動くか?fork?何それ? - ひげぽんDynamic Programming Language C -- 私は誰? - 浜地慎一郎g++と例外キャッチボール - 中村孝史G-Inspector -- GTK+ ランタイムインスペクション - 青笹茂実行時自己書き換え佳境 - 首藤一幸ハードコアバイナリアンへの道 -

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

    Cのプログラムの中でブレークポイントを設定する Cのプログラムをデバッグする際には GDB などのデバッガが役立ちます。通常、ブレークポイントはデバッガの中から設定しますが、デバッグ対象のCのプログラムの中で設定することもできます。 Linux なら #include <signal.h> して、任意の箇所に raise(SIGTRAP); を挿入すれば OK です。 raise() 関数を用いて SIGTRAP シグナルを発生させています。 あるいは x86 限定なら __asm__("int3"); でも OK です。ここでは SIGTRAP を発生させるために int3 (0xcc) 命令を埋め込んでいます。GDB もソフトウェア的にブレークポイントを設定するときは当該箇所に int3 を書き込んでいるので、やっていることは割と似ています (GDBの場合は int3 を書き込む部分の

    nirvash
    nirvash 2006/05/07
    ほほー。
  • 1