ラベル C の投稿を表示しています。 すべての投稿を表示
ラベル C の投稿を表示しています。 すべての投稿を表示

2013年1月20日日曜日

Shared Object 入門

2012年8月4日土曜日

インライン関数まとめ

2012年6月19日火曜日

マクロを文字列化する

プリプロセッサでマクロを文字列化する方法ないかな〜、って以前から思ってたんですが、 u-boot のソースコード読んでいたときに発見しました!

どういうことかといいますと #x のような文字列化機能がプリプロセッサにありますね。
例えば、以下のような感じ。


---

#include <stdio.h>

#define MK_STR(x) #x

char buf[] = "baudrate=" MK_STR(19200);

int main()
{
    puts(buf);

    return 0;
}

---

これをコンパイル、実行すると

$ ./a.out
baudrate=19200

19200"19200" のように文字列化してくれています。ここまで普通です。


やりたいことは、19200 の部分をマクロで定義しておきたいのです。

---

#include <stdio.h>

#define CONFIG_BAUDRATE 19200
#define MK_STR(x) #x

char buf[] = "baudrate=" MK_STR(CONFIG_BAUDRATE);

int main()
{
    puts(buf);

    return 0;
}

---


$ ./a.out
baudrate=CONFIG_BAUDRATE

う〜ん、残念。
CONFIG_BUADRATE19200"19200"
と置き換えてほしいんですが、 CONFIG_BAUDRATE をそのまま文字列化してくれました。

sprintf(buf, "%d", CONFIG_BAUDRATE)
みたいに sprintf は使いたくない。

で、今回見つけたやり方は以下の方法。


---

#include <stdio.h>


#define CONFIG_BAUDRATE 19200
#define XMK_STR(x) #x
#define MK_STR(x) XMK_STR(x)

char buf[] = "baudrate=" MK_STR(CONFIG_BAUDRATE);

int main()
{
    puts(buf);

    return 0;
}

---


$ ./a.out
baudrate=19200


おぉぉ〜!うまくいった。

一見無駄にも見える
#define XMK_STR(x) #x
#define MK_STR(x) XMK_STR(x)

というマクロ定義ですが、こんな効能があるんですね。

2012年4月6日金曜日

拡張インラインアセンブラの勉強 2

拡張インラインアセンブラの勉強 1

register 変数

2012年4月5日木曜日

関数のプロローグとエピローグ

2012年2月24日金曜日

C言語のswitch文で ...

Linux のコードを見ていると、こんな書き方もできるのかぁ、というものに出くわすことがありますね。

例えば、
arch/arm/mach-rpc/irq.c  にある、以下のようなコード。

                switch (irq) {
                case 0 ... 7:
                        irq_set_chip_and_handler(irq, &iomd_a_chip,
                                                 handle_level_irq);
                        set_irq_flags(irq, flags);
                        break;

                case 8 ... 15:
                        irq_set_chip_and_handler(irq, &iomd_b_chip,
                                                 handle_level_irq);
                        set_irq_flags(irq, flags);
                        break;

                case 16 ... 21:
                        irq_set_chip_and_handler(irq, &iomd_dma_chip,
                                                 handle_level_irq);
                        set_irq_flags(irq, flags);
                        break;

                case 64 ... 71:
                        irq_set_chip(irq, &iomd_fiq_chip);
                        set_irq_flags(irq, IRQF_VALID);
                        break;
                }



...」で範囲指定できるらしい。見た時びっくりしました。

 
gcc のマニュアルを参照すると
http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/C-Extensions.html#C-Extensions

これはGNU 拡張機能らしいです。
(Case Ranges: `case 1 ... 9' and such. )

gcc に -pedantic をつけると非標準機能を使っていると警告してくれるみたい。
ポータビリティを気にする場合は便利かも。

上のような書き方をすると

警告: range expressions in switch statements are non-standard

という風に warning 出してくれました。