Является ли NULL всегда ложным?
Можно ли предположить, что NULL
всегда переводит значение false в C?
void *somePtr = NULL;
if (!somePtr) {
/* This will always be executed? */
}
Или должна быть сделана явная проверка на значение NULL
?
Ответы
Ответ 1
Да. NULL оценивает значение false, так как C считает любое ненулевое значение true и любое значение нуля false. NULL по существу является адресом zero
и рассматривается как таковой при сравнении, и я считаю, что это будет повышаться до int для булевой проверки. Я бы ожидал, что ваш код будет читабель всем, кто знаком с C, хотя я бы, вероятно, сделал чек явным.
В программировании на C и С++ два нуля указатели гарантированно будут сравнивать равны; ANSI C гарантирует, что любой указатель будет равен 0 в сравнение с целым типом; кроме того, определяется макрос NULL как константа нулевого указателя, то есть значение 0 (либо как целочисленный тип, либо преобразован в указатель на void), поэтому нулевой указатель будет сравниваться равным NULL.
Ссылка: http://en.wikipedia.org/wiki/Null_pointer#Null_pointer
Ответ 2
Никогда не безопасно принимать что-либо.
Явная проверка также более понятна в отношении того, что вы тестируете.
Ответ 3
Язык 'C' датируется эпохой, когда (void *) 0 действительно может быть действительным указателем. Еще не так давно микропроцессоры 8080 и Z80 имели вектор прерываний по адресу 0. Столкнувшись с такими вариантами архитектуры, он не мог ничего сделать, но пусть заголовочный файл объявит значение NULL. Там были некоторые компиляторы, теперь давно забытые, где NULL не был равен (void *) 0 (0xffff был следующей альтернативой), тем самым давая поведение if() undefined.
С++ милостиво положил конец этому, нулевой указатель можно присваивать и тестировать против 0.
Ответ 4
Да (по крайней мере, для любого компилятора C, совместимого со стандартами!)
Из comp.lang.c FAQ:
Q: Является ли сокращенное сравнение указателей `` if (p) '' для проверки правильности непустых указателей? Что, если внутреннее представление для нулевых указателей отличное от нуля?
A: Он всегда действителен.
Ответ 5
NULL - это просто определение препроцессора. Это в stdio.h. Как правило, только безумный человек мог бы его переопределить, но это возможно. Пример:
#include <stdio.h>
#ifdef NULL
#undef NULL
#define NULL 1
#endif
void main()
{
if (NULL)
printf("NULL is true\n");
else
printf("NULL is false\n");
}
Этот код напечатает "NULL is true". Попробуйте, если вы мне не верите. Ваш компилятор может даже не предупредить вас, что вы делаете что-то странное.
Ответ 6
NULL
определяется как постоянный указатель, который, как гарантируется, указывает на бесполезное/несуществующее место в памяти. Большинство реализаций NULL
являются ((void *)0)
, но это не обязательно, так это.
Ответ 7
Я просто ссылаюсь на Вопрос 5.3 из C-FAQ. Он отвечает на этот точный вопрос.
Ответ 8
Да, в основном.
Во-первых, NULL является typedef. Я мог бы вкратце открутить вас, сказав в ранее включенном заголовке
#define NULL 1
Это может не иметь большого смысла, но с тех пор, когда код других людей имеет смысл?:)
Кроме того, хотя он, вероятно, синтаксически безопасен, он не семантически корректен. NULL означает "ничего", ни истинное, ни ложное, или логическое значение, или int или string. Это означает "символ для ничего". Таким образом, тестирование для NULL больше похоже на философскую проблему: если дерево падает в лес и if(listener)
, это делает звук?
Сделайте все одолжение и проявите готовность к тестированию против NULL.
Ответ 9
* NULL всегда нацелен на 0x00L. Вы можете считать это ложным, но, конечно, всегда выполняйте явную проверку.