В чем разница между NULL и __null в C ++? - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть следующий код:

MyType x = NULL;

NetBeans предложил мне изменить его на следующее:

MyType x = __null;

Я посмотрел его и обнаружил, что __null вызывается«ключевое слово компилятора», которое, как я предполагал, означает, что оно используется внутри компилятора.Я не понимаю, почему NetBeans предложил заменить его на ключевое слово компилятора.

В чем разница между NULL и __null в c ++?

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018

NULL - старый символ C для нулевого указателя.C ++ традиционно использовал 0 для нулевых указателей, и, поскольку стандарт C ++ 11 nullptr.

Учитывая, что x не является указателем, вы не можете инициализировать x должен быть нулевым указателем, а символ __null, возможно, является некоторым внутренним символом компилятора для нулевого значения (которое на самом деле не существует в стандартном C ++).

Если вы хотите, чтобы x инициализировался в какое-либо состояние по умолчанию, тогда вы должны положиться на конструктор MyClass по умолчанию, чтобы инициализировать объекты и его переменные-члены некоторыми подходящими значениями по умолчанию.

0 голосов
/ 28 декабря 2018

NULL был перехвачен из C в C ++ и - до C ++ 11 - принял его значение C:

до C ++ 11: макрос NULL определяется реализациейконстанта нулевого указателя, которая может быть целочисленным выражением-константой rvalue целочисленного типа с нулевым значением.

C ++ 11 затем ввела выделенный литерал нулевого указателя nullptr типа std::nullptr_t.Но - вероятно, для обратной совместимости - макрос NULL не был удален;его определение было немного смягчено, поскольку компиляторы теперь могут определять его как целочисленный или как тип указателя:

C ++ 11 и далее: целочисленный литерал со значением ноль или значение типа std:: nullptr_t

Если вы используете 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, напротив, идеально переносимый.

0 голосов
/ 28 декабря 2018

__null - это g++ внутренняя вещь, которая служит примерно той же цели, что и стандарт nullptr, добавленный в C ++ 11 (действует как указатель, а не целое число).

NULL определяется как 0, который может неявно использоваться как целое число, логическое значение, значение с плавающей запятой или указатель, что является проблемой, когда речь идет о разрешении перегрузки, когда вы хотите вызвать функцию, которая принимает указатель специально.

В любом случае вы не должны использовать __null, потому что это деталь реализации g++, поэтому его использование гарантирует непереносимый код.Если вы можете положиться на C ++ 11 (наверняка вы можете сейчас?), Используйте nullptr.Если нет, NULL - ваш единственный портативный вариант.

...