¿Por qué se usa la dirección cero para el puntero nulo?

¿Por qué se usa la dirección cero para el puntero nulo?

2 puntos:

  • solo el valor constante 0 en el código fuente es el puntero nulo:la implementación del compilador puede usar cualquier valor que desee o necesite en el código en ejecución. Algunas plataformas tienen un valor de puntero especial que no es válido y que la implementación podría usar como puntero nulo. Las preguntas frecuentes de C tienen una pregunta:"En serio, ¿alguna máquina real realmente usó punteros nulos distintos de cero o diferentes representaciones para punteros a diferentes tipos?", que señala varias plataformas que usaron esta propiedad de 0 como el puntero nulo en la fuente C mientras representado de manera diferente en tiempo de ejecución. El estándar de C++ tiene una nota que deja en claro que la conversión de "una expresión constante integral con valor cero siempre produce un puntero nulo, pero la conversión de otras expresiones que tienen valor cero no necesariamente produce un puntero nulo".

  • un valor negativo podría ser tan utilizable por la plataforma como una dirección:el estándar C simplemente tenía que elegir algo para usar para indicar un puntero nulo, y se eligió cero. Sinceramente, no estoy seguro de si se consideraron otros valores centinela.

Los únicos requisitos para un puntero nulo son:

  • está garantizado comparar desigual a un puntero con un objeto real
  • cualquier dos punteros nulos se compararán iguales (C++ refina esto de tal manera que solo necesita mantenerse para los punteros del mismo tipo)

Históricamente, el espacio de direcciones que comenzaba en 0 siempre era ROM, utilizado para algún sistema operativo o rutinas de manejo de interrupciones de bajo nivel, hoy en día, dado que todo es virtual (incluido el espacio de direcciones), el sistema operativo puede asignar cualquier asignación a cualquier dirección, por lo que puede específicamente NO asignar nada en la dirección 0.


IIRC, no se garantiza que el valor del "puntero nulo" sea cero. El compilador traduce 0 a cualquier valor "nulo" apropiado para el sistema (que en la práctica probablemente sea siempre cero, pero no necesariamente). La misma traducción se aplica cada vez que compara un puntero con cero. Debido a que solo puede comparar punteros entre sí y con este valor especial 0, evita que el programador sepa nada sobre la representación de memoria del sistema. En cuanto a por qué eligieron 0 en lugar de 42 o algo así, supongo que es porque la mayoría de los programadores comienzan a contar desde 0 :) (Además, en la mayoría de los sistemas, 0 es la primera dirección de memoria y querían que fuera conveniente, ya que en las traducciones de práctica como las que estoy describiendo rara vez se llevan a cabo; el idioma simplemente las permite).