カテゴリー「GCC/POSIX」の35件の記事

2009年2月13日 (金)

[プログラミング] 猛勉強中

iPhoneアプリで一儲けしようと世間に新しい経験をしてもらおうと、目下Cocoa&Objective-Cを勉強中です。

 

ところで勉強を重ねるごとに、「言語が思考を規定する」という感覚が「ライブラリ→コンポーネント→フレームワーク」の順で強くなっているのを感じます。.NET FrameworkとPOSIXライブラリくらいしかまだきちんと比較したことがないのですが・・・。

何というか、POSIXは良くも悪くもローレイヤでのトピックが多いのに比べ、.NETは手当り次第にオブジェクト指向(ただしGUIの設計方法はMVCを全く意識しづらいインタフェースになっているのが気持ち悪すぎ)だし、CocoaについてはMVCの見事な分離と委譲(delegate)・データソースの考え方がすばらしい(けれどフレームワーク外の作業はPOSIXべったり)。

どれも一長一短で、学んでいる側としてはこれほど刺激になることはないですね。
このフレームワークの概念、Javaについては他の言語よりもずっとバリエーションも豊かで先を行っていると思うので、こちらもちょっと触っていってみるべきかもしれないなと、.NETでのソケット実現のスマートさに驚きながら思ったのでした。
Concurrentパッケージも気になるし。

コンピュータには面白いことが沢山ありますな。
こうして得られた技術を使って、家族やみんなが幸せになるようなものが作れたら、開発者冥利に尽きるというものです。

さあ、またがんばるぞ。

| | コメント (0) | トラックバック (0)

2008年7月25日 (金)

[プログラミング] Inside a profiler

最近はネタ記事ばかり投稿してるかときちです。どうもこんにちは。

「いや待て、このままでは只のバカと思われてしまうよ!」

という危機感を持ちましたので、この前社内で発表したプロファイラの仕組みについてのスライドを公開することにします。
「プロファイラとは何か」から始まり、実際にプロファイラがどのような仕組みで動くか、動いているかを紹介しています・・・が、そんなことよりも勉強しているボクを見てください。

情報自体はインターネットからの寄せ集めですが、まあ初心者向けとしてそこそこ面白がってくれました。つっこみどころとかあると思いますので、コメント待ってます。

それにしてもスライド作成中に、Windowsの商業向けでは唯一のVisual StudioがTeam Edition(20万円以上もする!)でなければプロファイラが付属していないことを知りました。

Macではより高機能なDTraceベースのInstrumentsなんかが無償で付いていると言うのに、なんだそれ。開発者をなめてんのか、と。

| | コメント (2) | トラックバック (0)

2008年3月22日 (土)

[C] memcpy()とmemmove()の違いを調べた

Code Reading、ということでCのメモリコピー関数memcpy()とmemmove()の違いについて調べてみることにしました。APIは以下のとおりです。

void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
※restrict修飾子についてはこちらを参照

で、この2つをなぜ調べる気になったのかというと、memmove(3)のmanページに

The memmove() function copies n bytes from string s2 to string s1.  The two strings may overlap; the copy is always done in a non-destructive manner.

という記述があったから。memcpy()はs1とs2の指す領域がオーバーラップした時の振る舞いは未定義だとありますが、memmove()は上記のとおり正しくコピーされることを保証しています。
ソース上ではどのように違うのか、と気になったのです。

続きを読む "[C] memcpy()とmemmove()の違いを調べた"

| | コメント (0) | トラックバック (0)

2008年3月14日 (金)

[C] 関数内の関数の評価順序は未定義

タイトルそのままなのですが、

void foo(int a, int b, int c) { return; }

int main() {
    foo(printf("A"), printf("B"), printf("C"));
    return 0;
}

Forest というソースを実行した時に、ABCと表示されるのかCBAと表示されるのか、はたまた別の順序になるかは、仕様として決められていません。関数引数が評価される順序は、つまり不定なのです。

しかも、GCCだとバージョンによっても評価順序は変わるとのこと。

今回はprintf()というお互いに副作用の無い(*)関数を評価させましたが、互いの実行順序が意味を持つような場合、引数に関数を直接渡してしまうのではなく、事前に順番通り呼んでから引数に渡すように注意してください。

int main() {
    int a, b, c;
    a = printf("A"); b = printf("B"); c = printf("C");
    foo(a, b, c);
    return 0;
}

以上です。・・・なんて偉そうな事を書いていますが、実は順序不定である事を今日知ったことは内緒です。

【注意】
上ではprintf()を副作用がないと書きましたが、厳密には標準出力に対して副作用があるので注意してください。この場合だと、「ABC」または「CBA」と表示される事を期待したプログラムを書いてはいけない、ということです。

| | コメント (0) | トラックバック (0)

2007年9月 7日 (金)

応用編1回でビリー肉痛、とマルチスレッドの話

ビリーズブートキャンプ応用編を1回やっただけで「ビリー肉痛」なかときちです。基礎編とは身体の動かし方が違うので、また刺激になっていい感じ。

ビリー肉痛:ビリーズブートキャンプによる筋肉痛。激しい動きが多いエクササイズのため、十分な準備運動をしておかないと怪我の元となりかねない危険な状態。

関係ないですが、僕の作った「ビリー肉痛」という単語でググってみたら280件もヒットしてびっくり。同じようなことを考える人は多いのね・・・

さて、さいきんはめっきり技術的な話題が減っていますが、ちゃんと勉強はしていますよ。今日はスレッドの実装モデルについて勉強しました。続きはそのメモです。

続きを読む "応用編1回でビリー肉痛、とマルチスレッドの話"

| | コメント (0) | トラックバック (0)

2007年7月11日 (水)

状態変数まとめ

Blockswall マルチスレッドプログラミングで必須の概念である、「状態変数(Condition Variables)」について何となく分かってきたので、ここまでのまとめを書きます。

これまで何度も書籍やソースを読んで来たけれど、どうにも使いどころや存在意味がよく分からなかったので・・・。

ひょっとすると今ここで書いたことも間違っているかもしれませんが、もしそうなら遠慮なく指摘してください。
(ヨロシクお願いします)

続きを読む "状態変数まとめ"

| | コメント (0) | トラックバック (0)

2007年6月 8日 (金)

メモリ破壊チェックツール

Struggling メモリ破壊や、メモリリークを調べる場合,Linux状では通常Electric Fenceやdmalloc、valgrindなどを使用します。メモリリーク、ダブルフリーはもちろん、valgrindは領域を超えたアクセスなどまで検出してくれる優れものです。

しかしこれらは、組み込み機器のようなメモリの少ない、遅い環境で使うことは難しいのが実情です。バイナリをROMに持ってくることすらできません。そのため、メモリエラーの類が発生した場合はソースレビューか、コンソールへのfprintf()(←printf()だとバッファリングでずれる)にどうしても頼ってしまいます。

(以下マニアックな話が続くので、残りは「続きを読む」に書きます)

続きを読む "メモリ破壊チェックツール"

| | コメント (0) | トラックバック (0)

POSIXの隠しAPI

Vegetables 仕事、というかプログラミングの話です。

今,「VxWorksのAPIを提供しているライブラリの置き換え、撤廃」という作業をしています。pthreadsライブラリを直接叩くことで、アプリ層のプログラムが(v2linのような)VxWorks互換ライブラリがそのまま残っているかのようにプログラムできることを目的としています。

ところが、VxWorksなどの組み込み処理では必ず提供されている、『タイマ制限付き関数コール』といったリアルタイムOS(RTOS)では必要なAPIが、pthreadsの多くで提供されていません。
そのため,例えば最大5秒だけセマフォの解放待ちをする、という処理すら簡単には行えません。

他にもメッセージキューへの送受信、ウォッチドッグタイマなど。タスク生成とタスク実行が分けることもLinuxではできないです。

唯一のpthreads資料、「Pthreadsプログラミング 」にも載っていない状況なので、既存APIを使用してうまく代替フレームワークを作ってあげなければ・・・と、今日まで覚悟していました。

たとえばメッセージキューはFIFOを書き込みのシグナルにすることで、FIFOへのファイルディスクリプタでselect()を使う・・・などなど。

while (1) {
  select(fifo_fds+1, ...) ...
  msgrecv(..., NO_WAIT); ...
}

ところが今日,メンバーの一人が入手したSUSv3ドキュメントを見てみると、実はセマフォ・メッセージキュー共に、待ち時間指定付きのAPIが用意されていることが分かりました。

これらを使えば無理せずタイムアウトをサポートできますので、VxWorksのAPI移植、という目的は比較的容易に達成できることになりそうです。

いや、マジでよかった。

無知は無駄を招き、手間を増やすだけだなと痛感した一日でした。
もっとすごい開発者になりたい!(妖怪人間○ム風)

| | コメント (0) | トラックバック (0)

2007年5月23日 (水)

GCCの便利な関数

Horsetail ※写真はどこかで撮ったツクシ。感じだと土筆と書くけれど、英語だとhorsetailです。同じ物を指しているのに、印象が全然変わりますね。

−−−

さて、今回はGCC限定の話です。Windowsや他のコンパイラでは通用しない内容ですが、同様のAPIはどのコンパイラにもきっとあると思うので、探してみると面白そうかも。

えっと、GCCでは組み込み関数として

  • __builtin_return_address(N)
  • __builtin_frame_address(N)

が用意されています。これはそれぞれ、

  • 関数の呼び出し元(=戻り先・リターンアドレス)を返す
  • 関数が使用しているスタックの現在位置を返す

という機能を持っています。

これらの関数はなかなか便利で、例えば
「あるライブラリ関数の中で落ちているのが分かったけれど、これは誰から呼ばれたのだろう」
とか、
「組み込みソフトだからGDBが使えないけど、どうにか関数のバックトレースを得たいんだけど」
みたいなシチュエーションで活躍します。戻り先アドレスをもとにbinutilsのaddr2lineを使用したり、フレーム情報からどのスレッドで動作しているかを調べたり。

ちなみに引数のNには0以上の整数を指定します。0であれば自身の関数についての情報を返し、1以上は指定数ぶん戻った関数についての情報を返してくれます。ただしこの関数に変数を使用することはできないので注意。
(マクロで定義されているため??)

実はGDBもこれらの関数を使用してデバッグ情報を取得しています。
ということはつまり、これがあればLD_PRELOADを占有してしまうLibSegFaultや、重くてターゲット上で動作させられないGDBなんていらないわけで(言い過ぎ)。

まぁ、GCCでしか通用しないバッドノウハウですが、色々と使えそうです。

| | コメント (0) | トラックバック (0)

2007年4月 5日 (木)

関数内の関数

いつからかは分かりませんが、最近のGCCでは、関数の中に関数を記述できます。こんなぐあいに。

int main() {
    int a = 4;
    void hoge(x) { printf("Hello, %d\n", a+x); };
    hoge(3);
    return 0;
}

$ a.out
Hello, 7
$

これによって、

  • 変数スコープの単位をもっと細かく分けられる
  • 無名関数に近いことが出来る

というメリットを享受できます。うまく使えば影響の範囲を制御できて、なかなか便利です(他のコンパイラへの移植性はなくなるけど・・・)。

続きを読む "関数内の関数"

| | コメント (0) | トラックバック (0)