LoginSignup
6

More than 1 year has passed since last update.

posted at

updated at

本当にあった怖いNULL

はじめに

C++では、NULL#define NULL 0のように定義されており、本来使うべきではないところ(ポインターに関係のないところ)でも使用できてしまいます。

C++11ではNULLの様々な問題点を解消するためにnullptrキーワードが導入されました。nullptrは整数型に暗黙変換できず、より安全です。今日ではNULLは使うべきではありません。

なぜNULLは良くないのか、過去に見た事例を振り返りながら復習してみましょう。

NULL文字とNULLの混同

NULL文字('\0')とNULLポインター(NULL)は異なる概念のものですが、名前が似ているためか、混同している事例がありました。偶然にも値が一致しているので正しく動作します。

間違いの例:

char text[256];
text[0] = NULL;

修正例:

char text[256];
text[0] = '\0';

nullptrは整数型へ暗黙変換できないため、このような問題は生じません。

char text[256];
text[0] = nullptr; // エラー

文字列オブジェクトの先頭をNULLと比較している

NULL文字とNULLの混同である上に、無駄にわかりにくいコードです。

間違いの例:

const string str = ...;
if (*str.c_str() != NULL) { ... }

修正例:

const std::string str = ...;
if (!str.empty()) { ... }

0とNULLの混同

整数の0とNULLは偶然にも値が一致しますが、異なる概念のものですから混同してはいけません。

間違いの例:

double d = NULL;

修正例:

double d = 0;

nullptrは整数型へ暗黙変換できないため、このような問題は生じません。

double d = nullptr; // エラー

falseとNULLの混同

falseNULLは偶然にも値が一致しますが、異なる概念のものですから混同してはいけません。

間違いの例:

bool f() {
   ...
   return NULL;
}

修正例:

bool f() {
   ...
   return false;
}

nullptrは整数型へ暗黙変換できないため、このような問題は生じません。

bool f() {
    return nullptr; // エラー
}

コンテナをNULLで初期化している

整数0との混同ですが、異なる勘違いが背景にあるかもしれません。

間違いの例:

std::vector<int> v(NULL);

修正例:

std::vector<int> v;

nullptrは整数型へ暗黙変換できないため、このような問題は生じません。

std::vector<int> v(nullptr); // エラー

コンストラクタはexplicitにする

std::vectorでは起こりませんが、このとき呼び出されるコンストラクタがexplicitでない場合は、以下のようなコードも通ってしまいます。

MyArray arr = NULL;

暗黙変換を意図する場合を除き、1引数のコンストラクタは必ずexplicitを指定しましょう。

class MyArray{
    ...
    explicit MyArray(int){ ... }
};
MyArray a = 0; // エラー: explicitのため暗黙変換はできない
MyArray a(0);  // OK

純粋仮想関数を宣言する0とNULLの混同

どんな教科書にもおそらく載っておらず、なぜこのようなコードが書かれたのかは謎です。

間違いの例:

virtual void f() = NULL;

修正例:

virtual void f() = 0;

もちろん、nullptrであれば文法エラーとなります。

まとめ

nullptrを使いましょう。

また、こうしたミスを発見するには、NULLnullptrに置換することが効果的です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6