ошибка: 'NULL' не был объявлен в этой области

120

Я получаю это сообщение при компиляции C ++ на gcc 4.3

error: NULL was not declared in this scope

Он появляется и исчезает, и я не знаю почему. Зачем?

Спасибо.

jackhab
источник
2
Возможно, вы не объявили NULL в контексте того, откуда приходит сообщение?
Пол Томблин,
1
По крайней мере, вы должны опубликовать полный фрагмент кода, который выдает ошибку. В противном случае будет очень сложно определить, что происходит, просто взглянув на строку ошибки.
Naveen

Ответы:

179

NULLне ключевое слово. Это идентификатор, определенный в некоторых стандартных заголовках. Вы можете включить

#include <cstddef>

Чтобы он был в объеме, включая некоторые другие основы, например std::size_t.

Йоханнес Шауб - litb
источник
Боже, я так избалован Java (null - это ключевое слово), что никогда не думал, что NULL не будет ключевым словом в C ++. Спасибо :)
Стефан Хендрикс
14
На самом деле это тоже не ключевое слово в Java.
Man of One Way
4
@ManofOneWay Нет, он существует в Java, он просто пишется со строчными буквами вместо заглавных.
Ataraxia
8
@ZettaSuro Я не говорил, что этого не существует. Я просто сказал, что это не ключевое слово.
Man of One Way
8
Теперь, когда компиляторы в целом поддерживают C ++ 11, возможно, стоит упомянуть nullptrключевое слово, которое на самом деле является ключевым словом и не требует #includes. Это также более безопасно, чем NULL.
templatetypedef
38

GCC делает шаги в направлении C ++ 11, вероятно, поэтому теперь вам нужно включить cstddef , чтобы использовать константу NULL . В C ++ 11 предпочтительнее использовать новое ключевое слово nullptr , которое реализовано в GCC начиная с версии 4.6. nullptr не может быть неявно преобразован в целочисленные типы, поэтому его можно использовать для устранения неоднозначности вызова функции, которая была перегружена как для указателей, так и для целочисленных типов:

void f(int x);
void f(void * ptr);

f(0);  // Passes int 0.
f(nullptr);  // Passes void * 0.
Сеппо Энарви
источник
1
Но все же это странное поведение! Даже компиляция моего кода с -std = c ++ 98 GCC по-прежнему не распознает макрос NULL, и он распознает nullptr только с c ++ 11 или gnu ++ 11 в качестве аргумента для -std.
фараон
2
Стандарт C ++ уже в 1998 году заявил, что NULL определен в cstddef - новые версии компилятора просто более строго следуют стандарту, потому что им необходимо реализовать nullptr. Ваш (ошибочный) код скомпилирован с более ранними версиями GCC, но будет сложно сохранить обратную совместимость с более ранними версиями GCC в дополнение к более ранним стандартным версиям C ++.
Сеппо Энарви
NULLникогда не было встроенным ключевым словом; это макрос, определенный в нескольких стандартных заголовках C, включая <stddef.h>(или <cstddef>). Как gcc "предпринимает шаги к C ++ 11" влияет на это? Я не вижу в вопросе ничего, что подразумевает, что (невидимый) код скомпилирован с более ранними версиями gcc / g ++ или более ранними версиями языкового стандарта.
Кейт Томпсон,
1
Это именно то, что я сказал выше: уже в C ++ 98 он был определен в cstddef. Тем не менее, gcc (и другие компиляторы тоже) приняли код, который использовал NULL, без предварительного включения cstddef. Я совершенно уверен, что рассматриваемый (невидимый) код был скомпилирован с более ранними версиями, хотя он не строго соответствует стандартам. Теперь я только предполагаю, что такое более строгое поведение современных версий связано с разработкой компилятора для поддержки синтаксиса C ++ 11.
Сеппо Энарви,
10

NULLне ключевое слово; это макро-подстановка для 0, и , я полагаю , входит stddef.hили cstddef. У вас нет #includedподходящего файла заголовка, поэтому g ++ воспринимает его NULLкак обычное имя переменной, а вы его не объявили.

Дэвид Торнли
источник
5

Чтобы завершить другие ответы: если вы используете C ++ 11, используйте nullptr, которое является ключевым словом, которое означает указатель void, указывающий на null. (вместо NULL, который не является типом указателя)

Леонардо Раэле
источник
0

NULL также можно найти в:

#include <string.h>

String.h извлечет NULL откуда-то еще.

Сова
источник
0

Вы можете объявить макрос NULL. Добавьте это после #includes:

#define NULL 0

или

#ifndef NULL
#define NULL 0
#endif

Нет ";" в конце инструкции ...

Derzu
источник