Una dificultad con la exclusión automática de encabezado duplicado es que el estándar C es relativamente silencioso sobre el tema de lo que significa incluir nombres de archivos. Por ejemplo, suponga que el archivo principal que se está compilando contiene directivas #include "f1.h"
y #include "f2.h"
, y los archivos encontrados para esas directivas contienen ambos #include "f3.h"
. Si f1.h
y f2.h
están en directorios diferentes, pero se encontraron buscando rutas de acceso incluidas, entonces no estaría claro si las #include
directivas dentro de esos archivos tenían la intención de cargar el mismo f3.h
archivo o diferentes.
Las cosas empeoran aún más si se agregan las posibilidades de incluir archivos que incluyen rutas relativas. En algunos casos en los que los archivos de encabezado utilizan rutas relativas para las directivas de inclusión anidadas, y donde se desea evitar realizar cambios en los archivos de encabezado suministrados, puede ser necesario duplicar un archivo de encabezado en varios lugares dentro de la estructura de directorios de un proyecto. Aunque existen múltiples copias físicas de ese archivo de encabezado, deben considerarse semánticamente como si fueran un solo archivo.
Si la #pragma once
directiva permitiera seguir un identificador once
, con la semántica de que el compilador debería omitir el archivo si el identificador coincide con uno de una #pragma once
directiva encontrada anteriormente , entonces la semántica no sería ambigua; un compilador que podría decir que una #include
directiva cargaría el mismo #pragma once
archivo etiquetado que uno anterior, podría ahorrar un poco de tiempo omitiendo el archivo sin abrirlo nuevamente, pero dicha detección no sería semánticamente importante ya que el archivo se omitiría si o no el nombre de archivo fue reconocido como una coincidencia. Sin embargo, no conozco ningún compilador que funcione de esa manera. Hacer que un compilador observe si un archivo coincide con el patrón #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
y tratar tal cosa como equivalente al anterior #pragma once someIdentifier
sisomeIdentifier
permanece definido, es esencialmente tan bueno.
#pragma once
que le dice al compilador que solo incluya ese archivo una vez.