iPhone 開発に使える C99 仕様と gcc 拡張

iPhone アプリの開発には、コンパイラとして gcc 以外を使うことは基本的にありません。
したがって、gcc に実装されている C99 仕様や gcc 拡張仕様を気がねすることなく利用することができます。

ここでは、便利な C99 仕様や gcc 拡張を紹介します。

配列の動的確保 (C99)

配列を定義するときに、動的にサイズを指定してメモリを確保することができます。

従来は、

int n = 100;
char* buf = alloca(n);

のように alloca を使っていたところを、

int n = 100;
char buf[n];

と、言語仕様の範囲内で、より直観的に書けるようになりました。

case の範囲指定 (gcc 拡張)

従来、switch 〜 case で

switch (n) {
  case 0:
  case 1:
  case 2:
  case 3:
    process(n);
    break;
}

のようにばらばらに書いていた case の部分を、

switch (n) {
  case 0 ... 3:
    process(n);
    break;
}

と、まとめて書けるようになりました。

値と「...」の間にスペースが必要なことに注意してください。

文字列処理でも、

switch (c) {
  case 'a' ... 'z':
  case 'A' ... 'Z':
    process(c);
    break;
}

のように、この構文を使うことができます。

このように、いままでは範囲指定したいがために switch を使うのをあきらめて if にばらしていたケースでも、switch を使えるようになりました。

3項演算子を2項だけで使う (gcc 拡張)

これは、以前書いたネタ ですが、3項演算子を LL 系言語の「||」と同じように使えるという gcc 拡張です。

具体的には、

x ? x : y

と書いていた部分を、

x ?: y

と書くことができます。

つまり、ruby

v = x || y || z

と書くのと同じことを、C でも

v = x ?: y ?: z;

と書けばできるということです。

__func__ (C99)

__func__ (あるいは __PRETTY_FUNCTION__) で、現在実行している関数名を参照することができます。

void c_func()
{
  NSLog(@"%s", __func__);
}

- (void)applicationWillFinishLaunching:(NSNotification*)note
{
  c_func();
  NSLog(@"%s", __func__);
}

のように、C 関数と Objective-C のメソッド内で __func__ を参照すると、

c_func
-[AppController applicationWillFinishLaunching:]

というように、実行中の関数名やメソッド名を取得できていることがわかります。

主にデバッグ時に有用だと思います。

参考

他にも使えそうな仕様がいろいろあるので、一度仕様に当たっておくことをオススメします。