タグ

Cに関するbananapenguinのブックマーク (7)

  • memologue - シグナルハンドラを使わないでシグナルをハンドルする

    「シグナルハンドラの中でできることは非常に限られているんですよ」というお話を1年半くらい前に書きましたが、この話には続きがあって、ある特定の条件下ではこの制限を緩和することができます。今回はその方法についての解説です。sigwait(3)という関数を使います。 ※ この話、うっかり書き忘れていました。ちょっとしたきっかけで思い出したので、暇があるうちに書いておきます。 ■「シグナルを待つ」処理 〜従来の方法〜 皆様、「シグナルの到着を待つ」処理を、次のように書いてしまっていないでしょうか? // シグナルハンドラ void handler(int signo) { // この中で使って良いのは非同期シグナルセーフ(async-signal-safe)な関数のみ }を用意して、 sa.sa_handler = handler; sigaction(SIGHUP, &sa, NULL); ..

    memologue - シグナルハンドラを使わないでシグナルをハンドルする
    bananapenguin
    bananapenguin 2015/02/26
    シグナルハンドラなんていらなかったんや
  • memologue - UNIX上でのC++ソフトウェア設計の定石 (2)

    鉄則2: シグナルハンドラで行ってよい処理を知ろう sigaction関数で登録したシグナルハンドラで行ってよい処理は非常に限定されている 次の3つの処理だけが許されている 自動変数の操作 “volatile sig_atomic_t” 型の大域変数の操作 「非同期シグナルセーフ」関数の呼び出し これ以外の処理を記述しないこと! 説明: シグナル受信時に何らかの処理を行うためには、シグナルハンドラと呼ばれる関数を用意し、それをsigaction関数でシグナル名と紐付けておけばOKです。しかし、シグナルハンドラ内で行ってよい処理は、上記の通り非常に限定されています。これを把握しないまま奔放なコードを書くと次のような現象が起き得ます: 問題1: プログラムがデッドロックする危険がある タイミングに依存する、再現困難なバグの原因となる デッドロックの発生が典型例だが、それ以外にも関数の戻り値不正

    memologue - UNIX上でのC++ソフトウェア設計の定石 (2)
    bananapenguin
    bananapenguin 2015/02/26
    シグナルハンドラと非同期シグナルセーフ関数
  • モダンなC, C++の開発環境の構築方法 - 考える人、コードを書く人

    まだC, C++がないようなので書いてみた。主にLinux(DebianとかUbuntu)での環境構築について。 コンパイラ まずはapt-getでコンパイラをインストールする。UbuntuやDebianなら以下のコマンドでgccやg++および標準ライブラリ等がインストールされる。 $ sudo apt-get install build-essential デバッグツール デバッガおよびデバッグツールは少なくとも以下の三つは入れる。(あとltraceも欲しいかな?) GDB 言わずと知れたGNUのデバッガ Valgrind メモリリークや不正メモリアクセスの検出 strace システムコールのトレース $ sudo apt-get install gdb valgrind strace ビルドツール C, C++のビルドツールといえばまずmakeが浮かぶけど、最近ではSConsやCMak

    モダンなC, C++の開発環境の構築方法 - 考える人、コードを書く人
  • C言語関数辞典 - nextafter, nextafterf, nextafterl

    nextafterl 関数は,実軸上で x から見て y の方向にある x の次に表現可能な値を求め,long double 型で返します. nextafter,nextafterf,nextafterl 関数は,x がその型で表現できる最大の有限な値であり,かつその結果が無限大かその型で表現できない場合,値域エラー (range error) が発生する事があります. よく似た関数に,nexttoward,nexttowardf,nexttowardl 関数があります. 戻り値 y の方向にある x の次の値 C言語サンプルプログラム 以下に nextafter 関数を使用したサンプルプログラムを示します. /* header files */ #include <stdio.h> #include <stdlib.h> #include <math.h> /* main */ int

  • double型の値をchar配列に変換する方法はありますか?

    定数1.0を直接変換する方法は無いので、変数に入れてから「それがchar配列だと騙す」しかない。 例1. union _t { double d; char c_a[1]; /*先頭要素のアドレスさえ取得できれば良いので要素は1個で良い*/ } data; int i; char *p; data.d = 1.0; p=data.c_a; for (i = 0;i < sizeof(double);i++) printf("0x%2.2x ",*p++); putchar('\n'); 例2. double d = 1.0; char *p; p = (char *)&d; for (i = 0;i < sizeof(double);i++) printf("0x%2.2x ",*p++); putchar('\n');

    double型の値をchar配列に変換する方法はありますか?
  • CからC++への変更点

    関数のプロトタイプ C++では、一部C言語とは違う、または拡張された部分がいくつかあります コンパイラの実装レベルや、低レベルな部分での違いは省略します C++プログラムを読み書きするのに、Cプログラマが最低限知るべきことを紹介します まずは、関数のプロトタイプについてです C言語でのプロトタイプ宣言で、引数に何も値を受け取らない場合はvoidを明示する必要があります しかし、C++では任意です。voidを省略すると値を受け取らない関数を意味します #include <stdio.h> /*C言語ではvoidを明示しなければならない*/ void func(void); void func() { puts("kitty on your lap"); } int main() { func(); return 0; } 上はC言語プログラムです C言語では、引数に何も受け取らない関数の場合

  • printf による16進表示について

    C言語初心者です。 今作っているプログラムで、データを16進形式で表示しようとしています。 大体このような感じです。 /*入力時*/ char buf[5]={0x4e,0x94,0xa0,0x2b,0x78} /*出力時*/ for (i = 0; i < 5; i++) { printf("0x%02x\n",buf[i]) } 実際には入力後にある処理によってbufは更新されるのですが、printfの出力結果として、 0xffffff4e 0x94 0xffffffa0 0x2b 0x78 というように、'ffffff'が付加したものがいくつか出力されてしまいます。 これはどういった意味を持つのでしょうか? なんか初心者ならではの漠然とした質問ですいません。。。

    printf による16進表示について
  • 1