Что лучше применять для пустых указателей 0 или NULL или может
reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
Здравствуйте, Аноним, Вы писали:
А>Что лучше применять для пустых указателей 0 или NULL или может А>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
существует поверье, что на некоторых платформах нулевой указатель вполне может быть валидным, поэтому использовать NULL переносимее.
Здравствуйте, Аноним, Вы писали:
А>Что лучше применять для пустых указателей 0 или NULL или может А>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
Для пустых указателей в С++ используется 0.
Складывается впечатление, что 0 обладает некоторым специальным типом, который приводится к лююому указателю или интегральному типу.
Т.е. можно написать int *p = 0, но нельзя int *p = 1;
Здравствуйте, dkon, Вы писали:
D>существует поверье, что на некоторых платформах нулевой указатель вполне может быть валидным, поэтому использовать NULL переносимее.
Здравствуйте, Другой Аноним, Вы писали:
ДА>Здравствуйте, dkon, Вы писали:
D>>существует поверье, что на некоторых платформах нулевой указатель вполне может быть валидным, поэтому использовать NULL переносимее.
ДА>Для таких поверий есть еще слово "суеверие".
ты явно что-то знаешь я в стандарте нашел только это:
"The macro NULL, defined in any of <перечисление хедеров>, is an implementation defined C++ null pointer constant..."
Здравствуйте, dkon, Вы писали:
D>Здравствуйте, Другой Аноним, Вы писали: ДА>>Здравствуйте, dkon, Вы писали: D>>>существует поверье, что на некоторых платформах нулевой указатель вполне может быть валидным, поэтому использовать NULL переносимее. ДА>>Для таких поверий есть еще слово "суеверие". D>ты явно что-то знаешь я в стандарте нашел только это: D>"The macro NULL, defined in any of <перечисление хедеров>, is an implementation defined C++ null pointer constant..."
А я нашел вот это:
A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to
zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that
type and is distinguishable from every other value of pointer to object or pointer to function type. Two null
pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer
to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification
conversion (4.4).
Здравствуйте, leper, Вы писали:
D>>ты явно что-то знаешь я в стандарте нашел только это: D>>"The macro NULL, defined in any of <перечисление хедеров>, is an implementation defined C++ null pointer constant..."
L>А я нашел вот это:
L>
L>A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to
L>zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that
L>type and is distinguishable from every other value of pointer to object or pointer to function type. Two null
L>pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer
L>to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification
L>conversion (4.4).
L>Пункт 4.10.1
"вычисляется в ноль" -- это тоже самое, что "равно нулю"? я в немецком не силен просто.
L>>A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to
L>>zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that
L>>type and is distinguishable from every other value of pointer to object or pointer to function type. Two null
L>>pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer
L>>to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification
L>>conversion (4.4).
L>>Пункт 4.10.1
D>"вычисляется в ноль" -- это тоже самое, что "равно нулю"? я в немецком не силен просто.
Да. По этому поводу Страуструп в "Специальном издании", п. 5.1.1 разъясняет:
"Ноль (0) иммет тип int. Ноль, как правило (но не всегда), будет физически представлен в виде последовательности
нулевых битов соответствующей длины. Гарантируется, что нет объектов с нулевым адресом."
Заметь, что гарантируется именно языком С++. Никакого отношения к валидности нулевого адреса на некоторой
платформе, данное утверждениее не имеет.
Здравствуйте, dkon, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
А>>Что лучше применять для пустых указателей 0 или NULL или может А>>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
D>существует поверье, что на некоторых платформах нулевой указатель вполне может быть валидным, поэтому использовать NULL переносимее.
Угу, причем "некоторые"="практически все", и одной из таких платформ является x86 семейство процессоров. "Невалидность" нулевого указателя обеспечивается _языком_, а не платформой. Под досом, где не было никаких средств контроля, просто начало сегмента данных резервировалось в c0 под фиксированную надпись, и при её изменении по выходу с0 ругался на null pointer assignment.
Здравствуйте, dkon, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
А>>Что лучше применять для пустых указателей 0 или NULL или может А>>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
D>существует поверье, что на некоторых платформах нулевой указатель вполне может быть валидным, поэтому использовать NULL переносимее.
Это полная ерунда. 0 и NULL в контексте указателей абсолютно эквивалентны. Поэтому 0 точно так же переносим, как и NULL.
Что же касается валидности нулевого указателя на некоторых платформах — это машинный (физический) нулевой указатель может быть "валидным" (т.е. машинный адрес 0). А 0 в С++ обозначает языковой (логический) нулевой указатель, который к машинному адресу 0 никакого отношения не имеет. Логический нулевой указатель "валидным" ни в одной реализации С++ не бывает, т.е. ни на один объект никогда не указывает.
Здравствуйте, dkon, Вы писали:
L>>А я нашел вот это:
L>>
L>>A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to
L>>zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that
L>>type and is distinguishable from every other value of pointer to object or pointer to function type. Two null
L>>pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer
L>>to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification
L>>conversion (4.4).
L>>Пункт 4.10.1
D>"вычисляется в ноль" -- это тоже самое, что "равно нулю"? я в немецком не силен просто.
Это значит, что NULL может быть определен и как '0', и как '(2 — 2)', и как (5 + 10 — 30 / 2)', и как '(sizeof(int) — sizeof(int) * sizeof(char))'. Главное, чтобы это было ICE со значением 0.
Здравствуйте, Anton V. Kolotaev, Вы писали:
AVK>Здравствуйте, Аноним, Вы писали:
А>>Что лучше применять для пустых указателей 0 или NULL или может А>>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
AVK>Для пустых указателей в С++ используется 0. AVK>Складывается впечатление, что 0 обладает некоторым специальным типом, который приводится к лююому указателю или интегральному типу.
AVK>Т.е. можно написать int *p = 0, но нельзя int *p = 1;
Не столько сам 0 (как литерал), сколько ICE со значением 0. Можно написать и
Здравствуйте, Аноним, Вы писали:
А>Что лучше применять для пустых указателей 0 или NULL или может А>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
по-моему без разницы, так как:
#define NULL 0.
а можно так и вообще FALSE использовать, так как опять же
#define FALSE 0,
тем более, что часто тестируя валидность указателей мы делаем это именно так
if(somePointer){
doSomething;
}
А>Что лучше применять для пустых указателей 0 или NULL или может А>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
Это один из примеров непоследовательности г-на Страуструпа.
Он не любит NULL потому что это макрос.
А макросы он не любит, потому что они не позволяют контролировать типы.
Но дело-то в том, что в Си NULL определялся как ((void*)0) что при разумном использовании позволило бы контролировать типы и выдавать варнинг если указатель сравнивается не с адресом. Более того, NULL — это не просто 0, а невалидный адрес, который на другой платформе может оказаться не нулем а, например 0xffff.
L>Да. По этому поводу Страуструп в "Специальном издании", п. 5.1.1 разъясняет: L>"Ноль (0) иммет тип int. Ноль, как правило (но не всегда), будет физически представлен в виде последовательности L>нулевых битов соответствующей длины. Гарантируется, что нет объектов с нулевым адресом."
L>Заметь, что гарантируется именно языком С++. Никакого отношения к валидности нулевого адреса на некоторой L>платформе, данное утверждениее не имеет.
Очень самоуверенная гарантия. Тем самым разработчики С++ требуют от разработчиков железа чтобы они не создавали платформ, на которых нулевой валиден.
Здравствуйте, SWW, Вы писали:
SWW>Это один из примеров непоследовательности г-на Страуструпа.
SWW>Он не любит NULL потому что это макрос. SWW>А макросы он не любит, потому что они не позволяют контролировать типы.
SWW>Но дело-то в том, что в Си NULL определялся как ((void*)0) что при разумном использовании позволило бы контролировать типы и выдавать варнинг если указатель сравнивается не с адресом.
При правилах преобразования, принятых в Си++, не позволило бы.
SWW>Более того, NULL — это не просто 0, а невалидный адрес, который на другой платформе может оказаться не нулем а, например 0xffff.
"Невалидный адрес" на другой платформе оказаться "не нулем а, например 0xffff" может. Но на нулевом указателе это не скажется.
Если предположить, что на некоторой платформе "невалидный адрес" — это 0xffff, то все равно к значению нулевого указателя приводятся целочисленные константные выражения со значением нуль.
Если размер указателя и размер целого совпадают, то можно выяснить фактическое значение адреса, соответствующего нулевому указателю.
void* p = 0;
int pval = reinterpret_cast<int>(p); // может оказаться равным 0xffff
Здравствуйте, SWW, Вы писали:
L>>Да. По этому поводу Страуструп в "Специальном издании", п. 5.1.1 разъясняет: L>>"Ноль (0) иммет тип int. Ноль, как правило (но не всегда), будет физически представлен в виде последовательности L>>нулевых битов соответствующей длины. Гарантируется, что нет объектов с нулевым адресом."
L>>Заметь, что гарантируется именно языком С++. Никакого отношения к валидности нулевого адреса на некоторой L>>платформе, данное утверждениее не имеет.
SWW>Очень самоуверенная гарантия. Тем самым разработчики С++ требуют от разработчиков железа чтобы они не создавали платформ, на которых нулевой валиден.
В D&E Страуструп пишет, что любое константное выражение со значением 0 может быть неявно преобразовано в нулевой указатель. Не гарантируется, что нулевой указатель будет представлен той же последовательностью битов, что и целое 0. Гарантируется, что нулевой указатель отличим от остальных указателей того же типа.
Из-за того, что 0 преобразуется (неявно) в нулевой указатель, получаем:
void f(int*);
void f(int);
int main()
{
f(0); // вызов f(int), т.к. не требует преобразованияreturn 0;
}
Здравствуйте, SWW, Вы писали:
L>>Да. По этому поводу Страуструп в "Специальном издании", п. 5.1.1 разъясняет: L>>"Ноль (0) иммет тип int. Ноль, как правило (но не всегда), будет физически представлен в виде последовательности L>>нулевых битов соответствующей длины. Гарантируется, что нет объектов с нулевым адресом."
L>>Заметь, что гарантируется именно языком С++. Никакого отношения к валидности нулевого адреса на некоторой L>>платформе, данное утверждениее не имеет.
SWW>Очень самоуверенная гарантия. Тем самым разработчики С++ требуют от разработчиков железа чтобы они не создавали платформ, на которых нулевой валиден.
Нет, ничего подобного от разработчиков железа С++ не требует. Ты просто путаешь понятие нулевого указателя языка С++ и нулевого машинного адреса в железе. Это соврешенно разные вещи, никак между собой не связанные. Язык С++ нигде не требует, чтобы нулевой указатель соответствовал нулевому машинному адресу.
Если в некотором железе адрес 0x0 чем-то "занят", то разработчики компилятора могут использовать, например, машинный адрес 0xFFFFFFFF для внутреннего представления нулевого указателя. Но на уровне языка такой указатель по прежнему будет представляться константным выражением со значением '0'.
Здравствуйте, Heyyou, Вы писали:
А>>Что лучше применять для пустых указателей 0 или NULL или может А>>reinterpret_cast<SOME_TYPE*>(0)/ Я применяю 0 но это вроде бы не очень наглядно. Например в Паскале 0 это не nil
H>по-моему без разницы, так как: H>#define NULL 0. H>а можно так и вообще FALSE использовать, так как опять же H>#define FALSE 0, H>тем более, что часто тестируя валидность указателей мы делаем это именно так H>if(somePointer){ H> doSomething; H>}
В языке С++ нет никакого 'FALSE', поэтому к тестированию указателей через 'if' оно никакого отношения не имеет и иметь не может.
ME>В D&E Страуструп пишет, что любое константное выражение со значением 0 может быть неявно преобразовано в нулевой указатель. Не гарантируется, что нулевой указатель будет представлен той же последовательностью битов, что и целое 0. Гарантируется, что нулевой указатель отличим от остальных указателей того же типа.
То есть ненависть к макросам привела к тому, что Страуструпу пришлось снабдить сам язык столь необычным свойством. Кстати, неявные преобразования также им не приветствуются, но вероятно это он считает меньшим злом.