«специальное значение указателя» — это замечательно. Но, допустим, нам необходим доступ к структуре, лежащей по адресу 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'ми.
Большинство этой дряни идет под MS.
«специальное значение указателя» — это замечательно. Но, допустим, нам необходим доступ к структуре, лежащей по адресу 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.