私は次のコードを持っています:
MyType x = NULL;
NetBeansは、これをこれに変更するよう提案しました。
MyType x = __null;
調べてみると、__null
が「コンパイラー・キーワード」と呼ばれていることがわかりました。これは、コンパイラーの内部で使用されることを意味すると考えられます。 NetBeansがそれをコンパイラキーワードに変更することを提案した理由がわかりません。
C++のNULL
と__null
の違いは何ですか?
__null
はg++
内部のもので、C++ 11で追加された標準のnullptr
とほぼ同じ目的を果たします(一貫してポインターとして機能し、整数ではありません)。
NULL
は0
として定義されます。これは、整数、ブール、浮動小数点値、またはポインターとして暗黙的に使用できます。これは、ポインターを受け取る関数を呼び出すときに、オーバーロード解決の問題です。
いずれにせよ、__null
実装の詳細であるため、g++
を使用しないでください。したがって、これを使用すると、移植性のないコードが保証されます。 C++ 11に依存できる場合は(今までにできるでしょうか?)、nullptr
を使用してください。そうでない場合、NULL
が唯一の移植可能なオプションです。
NULL
はCからC++に取って代わられ、C++ 11より前ではそのCの意味を採用しました。
c ++ 11まで:マクロNULLは、実装で定義されたNULLポインター定数です。これは、ゼロに評価される整数型の整数定数式右辺値です。
次に、C++ 11は、タイプstd::nullptr_t
の専用のNULLポインターリテラルnullptr
を導入しました。ただし、おそらく下位互換性のために、マクロNULL
は削除されませんでした。コンパイラーが整数型またはポインター型として定義できるようになったため、その定義は少し緩和されました。
C++ 11以降:値がゼロの整数リテラル、またはstd :: nullptr_t型のprvalue
NULL
を使用すると、オーバーロード解決で実装定義の動作が得られます。たとえば、NULL
- macroの整数バージョンを使用するコンパイラを使用した次のコードを検討してください。次に、関数に渡されるパラメーターとしてNULL
を使用する呼び出しは、あいまいさを引き起こす可能性があります。
struct SomeOverload {
SomeOverload(int x) {
cout << "taking int param: " << x << endl;
}
SomeOverload(void* x) {
cout << "taking void* param: " << x << endl;
}
};
int main() {
int someVal = 10;
SomeOverload a(0);
SomeOverload b(&someVal);
// SomeOverload c(NULL); // Call to constructor is ambiuous
SomeOverload d(nullptr);
}
そのため、ポインタ型を表現する場合は、nullptr
を使用することをお勧めします。
また、__null
は使用しないでください。これはコンパイラ固有の移植性のない定数です。対照的に、nullptr
は完全に移植可能です。
NULL
は、nullポインターの古いCシンボルです。 C++は伝統的に0
をNULLポインターに使用し、C++ 11標準nullptr
以来使用していました。
x
がポインターではないように思えると、x
をヌルポインターに初期化できず、__null
シンボルはおそらくヌル用のコンパイラー内部シンボルです。 値(標準C++には実際には存在しない概念です)。
x
をデフォルト状態に初期化する場合は、MyClass
デフォルトコンストラクターに依存して、オブジェクトとそのメンバー変数を適切なデフォルト値に初期化する必要があります。