Calloc (), punteros y todos los bits cero

Posible duplicado:
¿NULL es siempre cero en C?

El estándar C establece lo siguiente para calloc() :

La función calloc asigna espacio para una matriz de objetos nmemb, cada uno de cuyo tamaño es el tamaño. El espacio se inicializa a todos los bits cero.

con la siguiente advertencia relacionada con todos los bits cero :

Tenga en cuenta que no es necesario que sea la misma que la representación de cero en coma flotante o una constante de puntero nulo.

Progtwig de prueba:

 #include  #include  #include  int main() { char** list = calloc(10, sizeof(*list)); int i; for (i = 0; i < 10; i++) { printf("%p is-null=%d\n", list[i], NULL == list[i]); } free(list); return 0; } 

Construí y ejecuté este progtwig con los siguientes comstackdores:

  • VC7, VC8, VC9, VC10
  • gcc v4.1.2, gcc v4.3.4
  • Forte 5.8, Forte 5.10

En todos los casos, todos los bits cero son un puntero NULL (a menos que haya cometido un error en el progtwig de prueba).

¿Cuál es la razón por la que el estándar C no garantiza que un puntero NULL sea todo cero ? Por curiosidad, ¿hay comstackdores donde todos los bits cero no son un puntero NULL ?

Las preguntas frecuentes de com.lang.c responden a esto en la pregunta 5.16 , donde explica por qué sucede esto, y la pregunta 5.17 , donde da ejemplos de máquinas reales con NULL distinto de cero. Un caso relativamente “común” es que la dirección 0 sea válida, por lo que se selecciona una dirección diferente no válida para NULL . Un ejemplo más esotérico es la Máquina Lisp de Symbolics, que ni siquiera tiene punteros como los conocemos.

Entonces no es realmente una cuestión de elegir el comstackdor correcto. En un sistema moderno de direccionamiento de bytes, con o sin memoria virtual, es poco probable que encuentre un puntero NULL que no sea la dirección 0.

El estándar C está cuidadosamente diseñado para acomodar hardware que es completamente extraño, y este es solo uno de los resultados. Otra cosa rara en el mismo sentido es que es posible para sizeof(void *) != sizeof(int *) , pero nunca verás que suceda en una architecture direccionable por bytes.

Sí, hay algunas implementaciones (algunas de ellas son exóticas), donde la representación interna del puntero NULL no es todo cero bits. Esta sección de las preguntas frecuentes de C es muy interesante (especialmente estas: 1 y 2 ).