2011-07-19 28 views
7

tengo varias copias de, digamos, stddef.h en mi sistema, se está en el camino /usr/include/linux/stddef.h, y tiene el siguiente aspecto:¿Por qué diferentes encabezados tienen el mismo nombre?

#ifndef _LINUX_STDDEF_H 
#define _LINUX_STDDEF_H 

#undef NULL 
#if defined(__cplusplus) 
#define NULL 0 
#else 
#define NULL ((void *)0) 
#endif 

#endif 

Otro está en el camino /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/include/, y que es el que está usado cuando digo #include <stddef.h>. los contenidos de ese uno es muy diferente de la primera, contiene las definiciones de ptrdiff_t, size_t etc.

Mi pregunta es: Por lo que yo sé, los/C estándares de C++ requieren que la definición de size_t debe ser colocado en stddef.h, sin embargo, el primero no sigue eso. Esa claramente no es la mencionada por los estándares de C/C++. Si ese archivo está allí para algún otro propósito, ¿por qué ambos archivos se nombran como stddef.h, no sería más seguro/más claro si tuvieran nombres diferentes?

+0

Parece bastante sospechoso, y la palabra de guardia calificada parece implicar que no se hace pasar por stddef.h intencionalmente. ¿Puedes verificar de qué paquete proviene? – Cheezmeister

+0

@Cheezmeister: 'apt-file' produce: ' linux-libc-dev:/usr/include/linux/stddef.h' y 'gcc-4.5:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/include/stddef.h' – loudandclear

+0

@Cheezmeister. Te secundaré. Ni la ruta '/ usr/include/linux/stddef.h' implica que es ** el encabezado estándar **. No hay 'stddef.h' bajo'/usr/include' en mi copia de Linux (Slackware64 13). – shinkou

Respuesta

3

El núcleo de Linux no enlaza con la biblioteca estándar c, por lo tanto, como regla general, los archivos de inclusión estándar no se pueden usar de manera segura, por lo que el kernel de Linux usa sus propios archivos de inclusión que se sabe que no confían en las funciones o los datos de la biblioteca c.

Cualquier software que se ejecute en el espacio del kernel, como los módulos kernel, debe usar los archivos include/linux y no los de biblioteca estándar.

Obviamente, los archivos de kernel include solo cubren cosas que probablemente sean necesarias en el kernel, por lo que son un subconjunto muy pequeño de los archivos de inclusión c estándar.

0

El estándar C requiere que incluir stddef.h es suficiente para definir size_t. Bajo el capó, se puede diseñar sin embargo los implementadores de la biblioteca lo desean.

Verá esto mucho en Linux, principalmente porque muchas de las implementaciones difieren entre sistemas (por ejemplo, x86 frente a brazo), y es más fácil poner la versión específica en un directorio separado.

Nota: Sin embargo, en el caso específico de /usr/include/linux/stddef.h, este es un encabezado de núcleo (destinado a compilar el kernel). Esto no fue pensado para haber sido incluido en el código fuente del espacio de usuario.


Esta edición es para responder a los comentarios de shinkou. No sé cómo hacer comentarios multilínea, así que esta es la manera más fácil:

$ cat incltest.c 
#include <stddef.h> 

$ cpp -H incltest.c 
... 
. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h 
... 

Usted puede hacer esto por cualquier cabecera.

En general, si tiene varias versiones de GCC en su sistema, tendrá varias versiones de CPP (y por lo tanto se puede ver que las diferentes versiones son utilizados por diferentes compiladores):

$ cpp-4.4 -H incltest.c 
. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.4.5/include/stddef.h 
+0

Eso es lo que entiendo, también. Sin embargo, ¿podría explicar por qué '/ usr/include/stddef.h' no existe (en algunas de las distribuciones, por ejemplo, Slackware)? – shinkou

+0

Si una distribución permite múltiples distribuciones de libc (y, por lo tanto, varias versiones de stddef.h), ¿cómo implementarla? Probablemente lo pondrías en diferentes directorios. GCC lo mantiene en directorios separados, y el compilador agrega automáticamente los encabezados específicos de la versión en un directorio predeterminado. - Acabo de marcar, cpp -H le dirá qué encabezado se usa –

+0

Si '/ usr/include/linux/stddef.h' es para el uso de compilación kernel solamente, ¿dónde podemos encontrar el * real *' stddef.h 'para el espacio de usuario entonces? 'find/usr/include -type f -name stddef.h' solo devuelve'/usr/include/linux/stddef.h' en mi máquina. – shinkou

0

Creo que uno está relacionado con el encabezado standerd de GCC y otro está relacionado con la definición específica del kernel. Entonces los contenidos son diferentes con el mismo propósito en diferente alcance.

Cuestiones relacionadas