programming - ¿Qué significa doble guión bajo(__const) en C?
int c programming (4)
El guión bajo en __const significa que esta palabra clave es una extensión de compilación y su uso no es portable (la palabra clave const se agregó a C en una revisión posterior, 89 creo). El __THROW también es un tipo de extensión, supongo que se define como __attribute __ (algo) si se usa gcc, pero no estoy seguro de eso y soy demasiado flojo para comprobarlo. El __addr puede significar cualquier cosa que el programador quiera que signifique, es solo un nombre.
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
Encontré la definición de la función anterior en /usr/include/netinet/ether.h en un cuadro de Linux.
¿Puede alguien explicar lo que significa el doble guión bajo frente a const (palabra clave), addr (identificador) y por último __THROW?
En C, los símbolos que comienzan con un guión bajo seguido de una letra mayúscula u otro guión bajo se reservan para la implementación. Como usuario de C, no debe crear ningún símbolo que comience con las secuencias reservadas. En C ++, la restricción es más estricta; usted, el usuario no puede crear un símbolo que contenga un doble guión bajo.
Dado:
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
La notación __const
está allí para permitir la posibilidad (algo improbable) de que un compilador con el que se usa este código sea compatible con las notaciones prototipo pero no tenga una comprensión correcta de la const
palabras clave estándar C89. Las macros de autoconf
aún pueden verificar si el compilador tiene soporte de trabajo para const
; este código podría ser utilizado con un compilador roto que no tiene ese soporte.
El uso de __hostname
y __addr
es una medida de protección para usted, el usuario del encabezado. Si compila con GCC y la opción -Wshadow
, el compilador le avisará cuando cualquier variable local -Wshadow
una variable global. Si la función solo utilizara el hostname
de hostname
lugar de __hostname
, y si tuviera una función llamada hostname()
, habría un sombreado. Al usar nombres reservados para la implementación, no hay conflicto con su código legítimo.
El uso de __THROW
significa que el código puede, en algunas circunstancias, declararse con algún tipo de ''especificación de lanzamiento''. Esto no es estándar C; es más como C ++. Pero el código se puede usar con un compilador de C siempre que uno de los encabezados (o el propio compilador) defina __THROW
como vacío, o para alguna extensión específica del compilador de la sintaxis estándar de C.
La sección 7.1.3 del estándar C (ISO 9899: 1999) dice:
7.1.3 Identificadores reservados
Cada encabezado declara o define todos los identificadores enumerados en su subcláusula asociada, y opcionalmente declara o define los identificadores enumerados en sus subsecuentes instrucciones de bibliotecas futuras e identificadores que siempre se reservan para cualquier uso o para uso como identificadores de alcance de archivo.
- Todos los identificadores que comienzan con un guión bajo y una letra mayúscula u otro guión bajo siempre están reservados para cualquier uso.
- Todos los identificadores que comienzan con un guión bajo siempre están reservados para su uso como identificadores con alcance de archivo tanto en el espacio ordinario como en el espacio de nombre de etiqueta.
- Cada nombre de macro en cualquiera de los siguientes apartados (incluidas las direcciones futuras de la biblioteca) está reservado para su uso como se especifica si se incluye alguno de sus encabezados asociados; a menos que se indique explícitamente lo contrario (ver 7.1.4).
- Todos los identificadores con enlace externo en cualquiera de las siguientes subcláusulas (incluidas las futuras instrucciones de la biblioteca) están siempre reservados para su uso como identificadores con enlace externo. 154)
- Cada identificador con alcance de archivo enumerado en cualquiera de las siguientes subcláusulas (incluidas las direcciones futuras de la biblioteca) está reservado para su uso como nombre de macro y como identificador con alcance de archivo en el mismo espacio de nombre si se incluye cualquiera de sus encabezados asociados.
No hay otros identificadores reservados. Si el programa declara o define un identificador en un contexto en el que está reservado (distinto de lo permitido por 7.1.4), o define un identificador reservado como un nombre de macro, el comportamiento no está definido.
Si el programa elimina (con
#undef
) cualquier definición de macro de un identificador en el primer grupo enumerado anteriormente, el comportamiento no está definido.Nota al pie 154) La lista de identificadores reservados con enlaces externos incluye
errno
,math_errhandling
,setjmp
yva_end
.
Consulte también ¿Cuáles son las reglas sobre el uso de un guión bajo en un identificador de C ++ ? muchas de las mismas reglas se aplican tanto a C como a C ++, aunque la regla incrustada de doble subrayado solo está en C ++, como se menciona en la parte superior de esta respuesta.
Los nombres con guiones bajos dobles están reservados para ser utilizados por la implementación. Esto no necesariamente significa que son internos per se, aunque a menudo lo son.
La idea es que no se permite el uso de nombres que comiencen con __
, por lo que la implementación es gratuita para usarlos en lugares como macro expansiones o en los nombres de extensiones de sintaxis (por ejemplo, __gcnew
no es parte de C ++, pero Microsoft puede agregarlo a C ++ / CLI confiando en que ningún código existente debería tener algo como int __gcnew;
en él eso detendría la compilación).
Para saber qué significan estas extensiones específicas, es decir, __const
, necesitará consultar la documentación de su compilador / plataforma específica. En este caso particular, probablemente debería considerar el prototipo en la documentación (por ejemplo, http://www.kernel.org/doc/man-pages/online/pages/man3/ether_aton.3.html ) para ser la interfaz de la función y ignore las decoraciones __const
y __THROW
que aparecen en el encabezado real.
Por convención en algunas bibliotecas, esto indica que un símbolo particular es para uso interno y no pretende ser parte de la API pública de la biblioteca.