Почему бы не вызвать nullptr NULL?


в C++11 the nullptr ключевое слово было добавлено как более безопасный тип константа нулевого указателя, так как предыдущее общее определение NULL а 0 имеет некоторые проблемы.

почему Комитет по стандартам решил не вызывать новую константу нулевого указателя NULL, или заявить, что NULL должно быть #defineд nullptr?

7 64

7 ответов:

Стефан т. Лававей (член комитета по стандартам C++) объяснил, что один раз в говорить (55:35):

в то время как реализация разрешено #define NULL nullptr, это сломало бы довольно некоторые виды использования, такие как

int i = NULL;

и, по-видимому, их много. Так что они не могли форсировать перемены.

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

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

кроме того,,

проверить сайт Бьярне Страуструпа

должен ли я использовать NULL или 0?

в C++ определение NULL равно 0, поэтому существует только эстетическое разница. Я предпочитаю избегать макросов, поэтому я использую 0. Еще одна проблема с NULL - это то, что люди иногда ошибочно считают, что это другое от 0 и / или не целое число. В предварительном стандартный код, null был/есть иногда определяется к чему-то непригодному и поэтому должен был/должен быть избежавший. В наши дни это встречается реже. Если вы должны назвать null указатель, назовите его nullptr; это то, что он называется в C++11. Затем, "нулевым" будет ключевым словом.

без фактического участия в обсуждении в комитете по стандартам, трудно сказать наверняка, но я бы подумал, потому что это сломает какой-то код, который использует NULL в смысле, где nullptr недостаточно совместим. И взлом старого кода никогда не является хорошей идеей.

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

на мгновение вы можете сделать:

void* p = 0;

но не это без неявного кастинга:

void* p = 1234;

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

nullptr улучшите это, применяя это указатель, вы не можете назначить это целое число. Поскольку поведение изменяется, создается новое имя для обратной совместимости.

также обратите внимание, что,nullptr обрабатывается компилятором, его фактическое значение не предоставляется пользователю (например, ноль в случае NULL). Гораздо проще иметь архитектурно-зависимое значение, скажем 0xdeadbeef, без логики кода программиста аффекта.

почему Комитет по стандартам решил не вызывать новую константу нулевого указателя NULL

предположительно потому, что новый нулевой указатель является ключевым словом, а ключевые слова не могут быть #defined, так называя это NULL сделал бы включение любого заголовка C, вероятно, плохо сформированным.

или заявить, что NULL должно быть #defined to nullptr?

комитет по стандартам позволяет NULL на #defined to nullptr, но это не требует оно.

в C++11 18.2 типов [поддержку.типы]/2: Макрос NULL является определяемой реализацией константой нулевого указателя C++ в этом международном стандарте.

C++11 4.10 преобразования указателей [conv.ptr] / 1: А константа нуль-указателя является неотъемлемой константное выражение (5.19) prvalue типа integer, которое равно нулю или prvalue типа std::nullptr_t.

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

я продемонстрирую случай, когда решение определить nullptr как другой тип помогает предотвратить ошибки.

рассмотрим эти функции:

void foo(int);
void foo(char *);

int main()
{
    foo(NULL); // oops
}

в C++98 приведенный выше код вызывает функцию foo(int), потому что NULL заменяется на 0, что, скорее всего, не то, что вы намеревались.

но если вы позвоните foo (nullptr) он называет правильным -- foo (char*).

Thenullptr вводится для безопасности типов и для ясности (вероятно, чтобы остановить инициализацию типов без указателя с помощью NULL).

The NULL(тип int) не изменяется на nullptr(тип указателя), чтобы избежать путаницы и обеспечить обратную совместимость.