Mahagam:
с какого года?
С появления первого стандарта языка С в 1989/1990 году. Хотя по-моему это поведение `0` в указательном контексте уже появилось в K&R - надо проверить. Во втором издании - точно, ибо оно подогнано под C89/90, а вот что там в первом - интересно было бы взглянуть.
Кстати, я когда-то задавал именно этот вопрос на StackOverflow
https://stackoverflow.com/questions/7128819/when-did-constant-0-i ... ial-status
Согласно ответу Jerry Coffin, специальная обработка `0` в указательных контекстах появилась намного раньше.
Mahagam:
а как до этого писали программы в которых требовалось лазить в ноль?по физическому адресу 0x0000 находится что-то полезное.
См. ниже.
Mahagam:
по физическому адресу 0x0000 находится что-то полезное.
а тут я пытаюсь добраться до этого полезного, а мне опля так - производят замену.
Это потому, что вы пытаетесь "добраться" до этого адреса совершенно криворуким и безграмотным способом. Откуда у вас в коде взялся `NULL`? `NULL` не предназначается и никогда не предназначался для доступа к адресу `0`. Оставьте `NULL` в покое.
С формально-педантичной точки зрения, языки С и С++ не предоставляют портабельных способов добраться до конкретного адреса. Однако все мы понимаем, что в реальной жизни это может быть необходимо, по каковой причине как правило каждая реализация предоставляет средства для того, чтобы поставить указатель на конкретный адрес. Например, в С++ это обычно делается вот так
int *p = reinterpret_cast<int *>(0xABCD1234);
при этом в `reinterpret_cast` в С++ (в отличие от всех остальных кастов) не производит "подмены" для значения `0`, то есть даже на платформе с ненулевым null pointer value
int *p = reinterpret_cast<int *>(0);
должно занести в `p` физическое значение `0` и тем самым дать вам доступ к адресу `0` на вашей платформе.
В С все несколько менее удобно, ибо там нет такого удобного `reinterpret_cast`. В С обычно
int *p = (int *) 0xABCD1234;
занесет вам конкретный адрес в указатель, но вот для константного значения `0` в указательном контексте всегда делается подмена. В том же самом comp.lang.c FAQ, который вы линковали, эта тема - обход подмены - отдельно освещена (http://c-faq.com/null/accessloc0.html). В частности, вы можете сделать
int address = 0;
int *p = (int *) address;
и на типичной C платформе в `p` ляжет адрес `0`, как вы и хотели.