c++ - cabeceras - headers en c
¿Cuándo se puede omitir la extensión del archivo en una directiva#include? (7)
Además de las buenas respuestas ya publicadas, debe tenerse en cuenta que el estándar C ++ no requiere la directiva "#include <iostream>
" para leer un archivo llamado "iostream", o incluso "iostream.h". Podría llamarse "fuzzball". O bien, no puede existir ningún archivo correspondiente y las definiciones se integran en el compilador y se activan mediante la directiva include.
Estoy jugando con gmock y noté que contiene esta línea:
#include <tuple>
Hubiera esperado tuple.h
.
¿Cuándo está bien excluir la extensión y le da a la directiva un significado diferente?
Incluye un archivo que simplemente se llama "tuple": el archivo en sí carece de una extensión.
El estándar putativo para incluir archivos en C ++ es nombrarlos sin la extensión .h; muchos escritores de bibliotecas siguen este estándar (STL, etc.) pero otros no.
Los encabezados estándar de C ++ no tienen un sufijo ".h". Creo que la razón es que hubo muchas implementaciones diferentes de estándares que romperían el estándar. Por lo tanto, en lugar de exigir que los proveedores cambien el encabezado exitante "iostream.h" (por ejemplo) para cumplir con los estándares (lo que rompería el código de usuario existente), el comité de estándares decidió que eliminarían el sufijo (que, creo que no entonces la implementación existente ya lo había hecho).
De esta forma, los programas existentes no estándar seguirían funcionando utilizando las bibliotecas no estándar del proveedor. Cuando el usuario quería hacer que sus programas cumplieran con los estándares, uno de los pasos que tomarían es cambiar la directiva " #include
" para soltar el sufijo ".h".
Asi que
#include <iostream> // include the standard library version
#include <iostream.h> // include a vendor specific version (which by
// now might well be the same)
Como han mencionado otras respuestas, los escritores de bibliotecas no estándar pueden elegir convenciones de nomenclatura, pero creo que querrían seguir usando ".h" o ".hpp" (como lo hizo Boost) por un par de razones:
- si y cuando la biblioteca se estandarice, la versión estándar no anulará automáticamente la anterior, no estándar (lo que puede hacer que se rompa el código de usuario con toda probabilidad)
- parece ser una convención (más o menos) que los encabezados sin sufijo son bibliotecas estándar, y aquellos con un sufijo (que no sean los viejos encabezados C) no son estándar.
Tenga en cuenta que un problema similar ocurrió cuando el comité fue a agregar mapas hash a la STL: descubrieron que ya existen muchas implementaciones hash_map
(diferentes), por lo que en lugar de hash_map
una estándar que rompa muchas cosas por ahí hoy, llaman a la implementación estándar " unordered_map
". Se suponía que los espacios de nombres ayudaban a evitar este tipo de salto a través de los aros, pero no parecía funcionar lo suficientemente bien (ni se usaba lo suficientemente bien) para permitirles usar el nombre más natural sin romper un montón de código.
Tenga en cuenta que para los encabezados ''C'', C ++ le permite incluir una <cxxxxxx>
o <xxxxxx.h>
. El que comienza con ''c'' y no tiene el sufijo ".h" pone sus declaraciones en el std
nombres std
(y posiblemente el espacio de nombres global), los que tienen el sufijo ".h" ponen los nombres en el espacio de nombres global (algunos compiladores también poner los nombres en el std
nombres estándar - no está claro para mí si eso cumple con los estándares, aunque no veo el daño).
Mi entendimiento fue que #include tuple "apuntaría" a tuple.h.
Mira esto: iostream vs iostream.h
No hay nada especial pasando. El archivo simplemente se llama tuple
.
La razón de esto ... que los encabezados de biblioteca estándar no tienen extensión de archivo se deben a namespace
de namespace
s.
Los espacios de nombres se agregaron al estándar de C ++ al final del juego con el estándar C ++ 98, incluido el std
nombres estándar en el que residen todas las entidades de biblioteca estándar.
Cuando la biblioteca estándar se movió al std
nombres estándar, eso significaba que todos los códigos C ++ existentes se romperían, ya que todos esperaban que la biblioteca estuviera en el espacio de nombres global. La solución fue dejar solos los viejos archivos de encabezado "dot-h" y proporcionar la biblioteca de espacio de nombres en los archivos que no tienen extensión.
De esta forma, el código anterior que incluiría #include<iosteam.h>
podría esperar un #include<iosteam.h>
global, mientras que el código nuevo podría #include<iostream>
y esperar un std::cout
.
Si el archivo se llama tuple
entonces necesitas #include <tuple>
si se llama tuple.h
entonces necesitas #include <tuple.h>
Es tan simple como eso. No estás omitiendo ninguna extensión.
Gente,
Creo que el trato es: #include <lib> siempre incluye / lib / include en la ruta de búsqueda (el .h está marcado) mientras que #include <lib.h> busca solo -I <ruta de acceso>.
Tenga en cuenta que podría estar equivocado ... Así es como creo que funciona (en Forte cc en Solaris).