yohhoyの日記

技術的メモをしていきたい日記

ポインタ型への非NULLアノテーションもどき

C99仕様で拡張された構文を用いて、関数引数としてのポインタ型に非NULLアノテーションを行う方法。正直微妙。

int f1(int *p)
{
  if (p == NULL)
    return 42;
  return *p;
}

int f2(int p[static 1])
{
  if (p == NULL)
    return 42;
  return *p;
}

Clang 3.5/-O1の出力アセンブリ

f1:
        movl    $42, %eax     ; 戻り値(eax) = 42
        testq   %rdi, %rdi    ; p == NULL?
        je      .LBB0_2
        movl    (%rdi), %eax  ; 戻り値(eax) = *p
.LBB0_2:
        retq

f2:
        movl    (%rdi), %eax  ; 戻り値(eax) = *p
        retq

関数f2の引数pは “要素数が1個以上のint型配列(int p[static 1])”、つまりコンパイラはint型ポインタpを非NULL値とみなしてよい。実際の出力アセンブリでも引数pのNULLチェック処理は省略されている。

関連URL