2009-02-28 9 views
41

preguntas que he revisado y How to use include directive correctlyC++ #include semantics y tampoco aborda este - ni los otros sugeridos por eso, cuando he escrito el título ...¿Cuáles son los beneficios de una ruta relativa como "../include/header.h" para un encabezado?

Lo que, en su caso, son las ventajas de la escritura:

#include "../include/someheader.h" 
#include "../otherdir/another.h" 

en comparación con el uso de sólo un nombre de archivo sin formato:

#include "someheader.h" 
#include "another.h" 

o tal vez un nombre relativo sin el '..':

#include "include/someheader.h" 
#include "otherdir/another.h" 

Los problemas que veo son:

  • no se puede mover una cabecera sin tener que preocuparse acerca de qué archivos de origen que incluyen.
  • Puede terminar con rutas muy largas para encabezados en dependencias e informes de errores. Hoy tuve uno con "../dir1/include/../../include/../dir2/../include/header.h".

El único mérito que puedo ver es que, si bien no es necesario mover ficheros, usted podría ser capaz de salirse sin necesidad de utilizar siempre '-I' directivas encontrar las cabeceras, pero la pérdida de la flexibilidad y la la complejidad de compilar en subdirectorios, etc. parece superar el beneficio.

Entonces, ¿estoy pasando por alto un beneficio?


Gracias por las entradas. Creo que el consenso es que no hay ningún beneficio importante para la notación usando "..." que estoy pasando por alto. En términos generales, me gusta la notación "somewhere/header.h"; Lo uso en nuevos proyectos. En el que estoy trabajando no es nuevo.

Uno de los problemas es que hay diversos conjuntos de cabeceras, a menudo con un prefijo tal como rspqr.h, rsabc.h, rsdef.h, rsxyz.h. Todos estos están relacionados con el código en el directorio rsmp, pero algunos de los encabezados están en rsmp y otros están en el directorio de inclusión central, que no tiene subdirectorios como rsmp en él. (Y repita para las otras áreas del código, hay encabezados en múltiples ubicaciones, necesarios al azar por otros bits de código.) Mover cosas es un problema importante porque el código se ha vuelto tan intrincado en los últimos años. Y los archivos MAKE no son consistentes en el que se proporcionan las opciones -I. En general, es una triste historia de negligencia no tan benigna durante un período de décadas. Arreglarlo todo sin romper nada va a ser un trabajo largo y tedioso.

+0

Parece ser consciente de todos los factores involucrados, por lo que esta no es realmente una pregunta. – shoosh

+0

Estoy comprobando si hay beneficios que he pasado por alto (porque odio la notación pero la sufro en el trabajo). Tengo menos problemas con la notación sin el "..." en ella. –

+0

Esto (usando rutas relativas) tiende a generar enormes dolores de cabeza cuando se usa un directorio de compilación separado. Es decir, cd tu proyecto; mkdir build; cd build; ../configure && make - Si va a seguir manteniendo el código, puede valer la pena el tiempo para solucionarlo. –

Respuesta

28

Prefiero la sintaxis de la ruta ya que deja muy claro a qué espacio de nombres o módulo pertenece el archivo de encabezado.

#include "Physics/Solver.h" 

Es muy autodescriptivo sin requerir que cada módulo prefija su nombre a archivos de encabezado.

Casi nunca uso el "..."Sin embargo, la sintaxis, en cambio tengo mi proyecto incluye especificar las ubicaciones de base correctas.

1

Porque a continuación, coloca el archivo relativo a la raíz del proyecto, y cuando lo comprueba en el control de código fuente y otro desarrollador lo comprueba en una ubicación diferente en su sistema local las cosas aún funcionan.

+3

Veo esto como un argumento en contra de los nombres de ruta absolutos, pero no pregunté sobre ellos (son inequívocamente malos AFAIAC). No estoy convencido de que este sea un argumento a favor o en contra de cualquiera de las variantes del nombre relativo. –

2

Piense en su árbol de fuentes como un espacio de nombres anidado y la ruta de inclusión le permite arrastrar directorios a la raíz de este espacio de nombres. uno de la formación de un espacio de nombres lógico para su base de código, independientemente de cómo el código está organizado en el disco

evitaría senderos como:.

  • "include/foo/bar.h" - la "incluyen" parece ilógico y redundante
  • "../foo/bar.h" - el ".." asume una ubicación relativa y es frágil
  • "bar.h" - a menos que bar.h esté en el directorio actual, esto contamina el espacio de nombres global y está pidiendo ambigüedades.

Personalmente, tiendo a agregar una ruta como la siguiente a mis proyectos incluyen ruta - "..;../..;../../..;../../../..".

Esto le permite aplicar una especie de regla de ocultación a su #include sy permite cierta libertad de mover encabezados sin romper otro código. Por supuesto, esto es a expensas de introducir un riesgo de vinculación al archivo de encabezado incorrecto si no tiene cuidado, ya que los nombres no completos pueden ser (o llegar a ser con el tiempo) ambiguos.

Tiendo a calificar completamente #include s en encabezados públicos para que los terceros que consuman mi código no necesiten agregar el "..;../..;../../..;../../../.." a su proyecto, es solo una conveniencia para mi código privado y sistema de compilación.

+1

¿Cuál es el propósito de ';' en tu camino? – Royi

+1

El ";" es un separador de ruta en Windows, específicamente, es la forma en que suministra un conjunto de directorios para buscar en Visual Studio. –

+0

¿Podría explicarlo? No estoy seguro de haber entendido. Gracias. – Royi

8

IANALL, pero no creo que deba poner .. en archivos fuente C o C++ reales, porque eso no es portátil y el estándar no es compatible. Esto es similar al uso de \ en Windows. Solo hazlo si tu compilador no puede funcionar con ningún otro método.

+3

Buen punto. El estándar ni siquiera parece garantizar que pueda usar barras inclinadas hacia adelante. "La implementación proporciona asignaciones únicas para las secuencias que constan de uno o más nondigits (lex.name) seguidos de un punto (.) Y un solo punto no incluido". Define nondigit como básicamente [_a-zA-Z] o \ uNNNN. – bk1e

+0

Esto es cierto, pero el software en cuestión ha estado compilando en una amplia gama de plataformas durante varios años (más de veinte), por lo que es más una responsabilidad teórica que práctica. –

+1

Cero éxitos de google para IANALL. ¿Asumo que es "No soy un abogado de idiomas"? –

22

El problema con #include "../include/header.h" es que a menudo funcionará por accidente, y luego un cambio aparentemente no relacionado hará que deje de funcionar más tarde.

Por ejemplo, considere la siguiente distribución fuente:

./include/header.h 
./lib/library.c 
./lib/feature/feature.c 

Y digamos que se está ejecutando el compilador con una ruta de inclusión de -I. -I./lib. ¿Lo que pasa?

  • ./lib/library.c puede hacer #include "../include/header.h", lo cual tiene sentido.
  • ./lib/feature/feature.c también puede hacer #include "../include/header.h", aunque no tiene sentido. Esto se debe a que el compilador probará la directiva #include relativa a la ubicación del archivo actual, y si eso falla, probará la directiva #include relativa a cada entrada -I en la ruta #include.

Además, si más adelante quita -I./lib del camino #include, a continuación, se rompe ./lib/feature/feature.c.

encuentro algo como la siguiente en ser preferible:

./projectname/include/header.h 
./projectname/lib/library.c 
./projectname/lib/feature/feature.c 

no añadiría ninguna ruta de inclusión entradas que no sean -I., y luego ambos library.c y feature.c usaría #include "projectname/include/header.h". Suponiendo que "projectname" es probable que sea único, esto no debería dar lugar a colisiones de nombres o ambigüedades en la mayoría de las circunstancias. También puede usar la ruta de inclusión y/o la función VPATH de make para dividir el diseño físico del proyecto en varios directorios si es absolutamente necesario (para acomodar código autogenerado específico de plataforma, por ejemplo; esto es algo que realmente se descompone cuando usa #include "../../somefile.h")

+1

sí, esa cosa que usa "projectname/include/header.h" fue lo que usé en mi último proyecto (pero comencé desde include/instead). siempre pongo solo una, que apunta a la ruta include/y luego la incluyo en base a eso. pero aún no analicé los "..." problemas en profundidad. Tienes buenos puntos. –

1

Otro problema en las ventanas con rutas relativas es MAX_PATH. Esto provocará problemas de compilación cuando, por ejemplo, compilación cruzada para Android y su camino crece más de 260 de largo.

Cuestiones relacionadas