«специальное значение указателя» — это замечательно. Но, допустим, нам необходим доступ к структуре, лежащей по адресу 0. В этом случае «специальное значние указателя», очевидно, необходимо переопределить. Но это невозможно. Это и странно.
Диск это блочное устройство, ему просто говорят с какой дорожки какие блоки прочитать, он понятия не имеет о файлах и файловой системе.
А и не нужно.
Как действуют буткиты, сидящие в MBR, вы знаете? Например, концепт eEye? Судя по тому, что написано вами, нет.
Я не знаю, к сожалению, возможностей контроллера. Возможно, подмена только одного блока — все, что он сможет, но если он может подменить пару других, из области ядра, этого достаточно.
Мы лишь можем присвоить это состояние через p = 0 или p = NULL и сравнить с тем же 0 или NULL.
Но раз вводится отдельная сущность — NULL, в этом есть смысл, кроме повышения читаемости кода. Раз уж это макрос. Логично было бы, если бы if для указателей сравнивал бы с !NULL, а не !0.
2. Каждая платформа имеет свой зарезервированный пустой указатель. О его реальном физическом представлении знает лишь компилятор.
Верно, но тогда компилятор какой-либо платформы может/должен учитывать, что NULL, как некорректный адрес, не равен (может быть) 0, потому что 0 — корректный.
Т.е. если говорить о переносимости, то на двух платформах:
#define NULL ((void*)0)
…
p = NULL;
…
if(p){
…
}else{
…
printf(«we must be here\r\n»);
}
и
#define NULL ((void*)0xFFFFFFFF)
…
p = NULL;
…
if(p){
…
}else{
…
printf(«we must be here\r\n»);
}
Должен в обоих случаях выдать надпись — ведь правила переносимости соблюдены — при вроверке указателя идет сравнение с NULL.
Предположу, что по тем же причинам, что и отсутствие типа bool в C. Для нового значения null, нужно было вводить новый тип данных.
Так тип данных-то есть — указатель это не int. И на множестве экзотических платформ разрядность указателя может не совпадать с int'ом, поэтому pointer есть как тип. А вот введение отдельного bool это уже лишняя сущность, плюс почти везде сравнение с нулем «дешевое». Указатели — чуть другое дело.
На таком уровне незачем менять MBR, если можно подменять сразу код ядра. Хотя возможности измененной прошивки не до конца понятны, может они не так уж велики.
Разговоры о переносимости вообще страннЫ в данном контексте. Да, код на Си скомпилируется и на другой платформе — в этом смысле он переносим.
Но если это у нас написанный на Си драйвер под Windows, переноси — не переноси — программа все равно платформозависимая.
Я неверно понял, что подразумевается под «нулевой указатель». Мне казалось, что «нулевой» — это всегда численно равный нулю. И в этом случае — разыменовывай — не хочу.
Но, как верно отметили выше, нулевой — это NULL, который может теоритически и не быть численно ранвым 0.
Так в Си строк как таковых вообще нет. Так что 1:1.
GC там идет через установку скрытых try..finally.
Не используйте строки и динамические массивы — и будет вам счастье. Вызывайте менеджер памяти ОС и используйте ASCIIZ C-style. Более того, try-..finally затыкается stub'ми.
Ага, значит, мы можем переопределить null на конец памяти? Это, кстати, интересная идея и даже более здравая — никто не сможет хранить структуру (объект) в конце памяти. А в начале может.
Тут путаница с самим словом NULL. В том же Паскале используется nil, оно чуть-чуть более нейтрально.
Но, т.к. это представление сильно зависит от платформы, устанавливать значение указателя в особое состояние null необходимо присваиванием нулевого значения целого интегрального типа.
А почему не значения null, которое могло бы быть переопределено? Определено оно для платформы как 0 — будет 0, -1 — будет 0xff....ff?
Из-за проверки if, которая опирается на нулевок значение, а не на null в случае указателя?
Вас не затруднит указать первый стандарт, в котором появилось упоминание этого?
До x86 и AVR были другие архитектуры, зачастую с перекрестными окнами и отдельными внешними аппаратными менеджерами памяти. В которых 0 тоже мог быть корректным адресом.
«специальное значение указателя» — это замечательно. Но, допустим, нам необходим доступ к структуре, лежащей по адресу 0. В этом случае «специальное значние указателя», очевидно, необходимо переопределить. Но это невозможно. Это и странно.
Я не предлагал менять что-то на диске, вы невнимательно читаете.
А и не нужно.
Как действуют буткиты, сидящие в MBR, вы знаете? Например, концепт eEye? Судя по тому, что написано вами, нет.
Я не знаю, к сожалению, возможностей контроллера. Возможно, подмена только одного блока — все, что он сможет, но если он может подменить пару других, из области ядра, этого достаточно.
Но раз вводится отдельная сущность — NULL, в этом есть смысл, кроме повышения читаемости кода. Раз уж это макрос. Логично было бы, если бы if для указателей сравнивал бы с !NULL, а не !0.
Верно, но тогда компилятор какой-либо платформы может/должен учитывать, что NULL, как некорректный адрес, не равен (может быть) 0, потому что 0 — корректный.
Т.е. если говорить о переносимости, то на двух платформах:
#define NULL ((void*)0)
…
p = NULL;
…
if(p){
…
}else{
…
printf(«we must be here\r\n»);
}
и
#define NULL ((void*)0xFFFFFFFF)
…
p = NULL;
…
if(p){
…
}else{
…
printf(«we must be here\r\n»);
}
Должен в обоих случаях выдать надпись — ведь правила переносимости соблюдены — при вроверке указателя идет сравнение с NULL.
Так тип данных-то есть — указатель это не int. И на множестве экзотических платформ разрядность указателя может не совпадать с int'ом, поэтому pointer есть как тип. А вот введение отдельного bool это уже лишняя сущность, плюс почти везде сравнение с нулем «дешевое». Указатели — чуть другое дело.
Но если это у нас написанный на Си драйвер под Windows, переноси — не переноси — программа все равно платформозависимая.
Но, как верно отметили выше, нулевой — это NULL, который может теоритически и не быть численно ранвым 0.
GC там идет через установку скрытых try..finally.
Не используйте строки и динамические массивы — и будет вам счастье. Вызывайте менеджер памяти ОС и используйте ASCIIZ C-style. Более того, try-..finally затыкается stub'ми.
Однако ниже уже подсказали, что NULL — необязательно 0.
Тут путаница с самим словом NULL. В том же Паскале используется nil, оно чуть-чуть более нейтрально.
А почему не значения null, которое могло бы быть переопределено? Определено оно для платформы как 0 — будет 0, -1 — будет 0xff....ff?
Из-за проверки if, которая опирается на нулевок значение, а не на null в случае указателя?
До x86 и AVR были другие архитектуры, зачастую с перекрестными окнами и отдельными внешними аппаратными менеджерами памяти. В которых 0 тоже мог быть корректным адресом.