WhozCraig написал эти комментарии к теперь удаленному answer, но его можно было бы довести до полного ответа (и вот что я здесь сделал). Он отмечает:
Интересное примечание: AS/400 является уникальной площадкой, где любой не- действительный указатель считается эквивалентным NULL
. Механики, которые они используют для этого, просто потрясающие. «Действительным» в этом смысле является любой 128-битный указатель (платформа использует 128-битное линейное адресное пространство для всего), содержащее «значение», полученное известным доверенным набором команд. Жестко, как верить, int *p = (int *)1; if (p) { printf("foo"); }
будет не печать "foo" на этой платформе. Значение, присвоенное p, не является доверенным источником и, следовательно, считается «недействительным» и, таким образом, эквивалентно NULL
.
Это откровенно поразительно, как это работает. Каждый 16-байтовый абзац в отображаемом виртуальном адресном пространстве процесса имеет соответствующий бит в общесистемном растровом изображении. Все указатели должны находиться на одной из этих границ абзаца. Если бит «горит», соответствующий указатель хранится из надежного источника, в противном случае он является недопустимым и эквивалентен NULL. Вызовы к malloc, указателю math и т. Д. Проверяются при определении того, горит ли этот бит или нет. И, как вы можете себе представить, постановка указателей в конструкции приносит совершенно новый мир боли в отношении идеи упаковки структуры.
Это отмечено сообщество-вики (это не мой ответ - я не должен получить кредит), но он может быть удален, если WhozCraig пишет свой ответ.
Это показывает, что существуют реальные платформы с интересными свойствами указателя.
Были платформы, где #define NULL ((void *)0)
не является обычным определением; на некоторых платформах это может быть только 0
, на других, 0L
или 0ULL
или другие соответствующие значения, если компилятор это понимает. C++ не нравится ((void *)0)
как определение; системы, в которых заголовки, взаимодействующие с C++, могут не использовать версию указателя void.
Я узнал С на машине, где представление для адреса char *
для данного места памяти отличалось от адреса int *
для того же места в памяти. Это было в дни до void *
, но это означало, что вы должны были правильно объявить malloc()
(char *malloc();
- никаких прототипов), и вам нужно было явно указать возвращаемое значение на правильный тип или получить дампы ядра. Будьте благодарны за стандарт C (хотя рассматриваемая машина, ICL Perq - фирменное оборудование из Three Rivers - была в значительной степени заменена к тому времени, когда был определен стандарт).
Вы можете использовать '0' вместо' NULL'. – pmg
NULL определяется в 'stddef.h', вам не нужно определять его самостоятельно. – Mat
@pmg 0 не переносится, если ответ на мой первый вопрос верен – stdcall