2010-03-22 18 views
6

Después de leer varias preguntas sobre problemas con la compilación (particularmente C++) y observar que en muchos casos el problema es un encabezado faltante #include. No pude evitar preguntarme en mi ignorancia y preguntarme (y ahora a usted):#include encabezados en C/C++

¿Por qué los encabezados que faltan no se comprueban automáticamente y se agregan o se solicitan al programador?

Esta característica está disponible para las sentencias de importación de Java en Netbeans, por ejemplo.

+4

¿Java funciona con archivos de encabezado? – Peter

+0

Se llaman declaraciones de importación – bragboy

+2

La 'importación' de Java es más parecida a 'usar' de C++, no como '# include'. – fredoverflow

Respuesta

12

¿Recuerda el choque en Java entre java.util.Date y java.sql.Date? Si alguien usa Date en su código, no puede decir si olvidó import java.util.Date o import java.sql.Date.

Tanto en Java como en C++, no es posible decir con certeza qué instrucción de importación/inclusión falta. Entonces ninguno de los dos idiomas lo intenta. Su IDE podría hacer sugerencias para los símbolos no declarados que se usan en su código.

El problema es aún más complicado en C++, porque el estándar dice que cualquier encabezado estándar puede incluir cualquier otro encabezado estándar. Por lo tanto, es muy fácil utilizar una función o clase sin incluir directamente el encabezado que la define, porque su compilador incluye indirectamente el encabezado correcto.El código resultante funciona en algunas implementaciones pero no en otras, según si comparten esa dependencia de encabezado.

En general, no es posible que un IDE de C++ indique si una dependencia de encabezado está "garantizada" o solo un detalle de implementación incidental en el que los usuarios no deben confiar. Obviamente, para las bibliotecas estándar solo podría saber qué se define en qué encabezados, pero tan pronto como llegue a las bibliotecas de terceros se vuelve bastante incierto.

Creo que la mayoría de los programadores de C++ esperan tener que buscar qué encabezados definen qué símbolos. Con Java, la regla de una clase pública por archivo simplifica esto considerablemente, y usted solo importa los paquetes/clases que desea. C++ no tiene paquetes, y la única forma de que el IDE encuentre una clase llamada my_namespace::something::MyClass es buscarla en cada archivo de encabezado.

+0

gracias por su explicación steve – Carlos

0

NetBeans es un IDE (Integrated Development Environment). Algunos IDE de C/C++ tienen esa característica ... pero no todos la conocen ni la utilizan.

2

Porque en el momento en que confíe en la computadora para piense en, tiene un caso importante de SkyNet en sus manos.

Las computadoras, en general, son muy malas para tomar decisiones, excepto las muy simples. Sacar algo del infierno de la dependencia simplemente no es una tarea que deba encomendarse, porque ese tipo de pensamiento conduce a una codificación descuidada y un código defectuoso.

4

Por último recuerdo, Java también arroja un error si se pierde una instrucción de importación. Es la GUI de NetBeans que hace su vida más fácil.

Probablemente deberías tratar de encontrar una GUI inteligente para tu código C/C++.

7

¿Por qué los encabezados que faltan no se comprueban automáticamente y se agregan o se solicitan al programador?

Pero se revisan automáticamente.

  1. Mi compilador falla la compilación cuando no puede encontrar un encabezado.
  2. Mi IDE (eclipse) agrega una pista visual cuando no puede encontrar un archivo de encabezado que he #incluido, subraya la línea #include y proporciona una información sobre herramientas que me dice cuál es el problema.

No agregará automáticamente una inclusión porque no puede saber cuál incluye I forgot. Los compiladores no son psíquicos.

0

Porque en general es un problema difícil saber qué archivos de encabezado debe incluir para definir algo correctamente. Sería una buena característica tener tu IDE capaz de adivinar casos simples y ofrecer ayuda.

1

El compilador no debería tener que pensar por usted. ¿Qué pasa si hay una función del mismo nombre en dos bibliotecas diferentes? ¿Cómo sabría qué encabezado incluir y qué biblioteca vincular? Tener un compilador o un IDE que solucione silenciosamente tu código descuidado es una mala idea en mi opinión.

1

Parte de la diferencia se debe a unas pocas decisiones de diseño fundamentales que se hicieron de forma diferente entre los dos. En particular, Java requiere que el nombre de una clase coincida con el nombre del archivo, por lo que el nombre de la clase que utiliza le dice lo que necesita importar.

En C o C++, el nombre que le dé a un encabezado no necesariamente tiene que coincidir con el contenido en absoluto. Si lo deseabas lo suficiente, podías nombrar tus encabezados 1.h, 2.h, 3.h, y así sucesivamente - o incluso 1.bas, 2.pas, 3.java, 4.ada y cualquier otra cosa nombres engañosos que prefieras. Esa es obviamente una mala idea, pero si lo hicieras de todos modos, al compilador no le molestaría en absoluto.

Como tal, es mucho más difícil para una herramienta C o C++ adivinar qué encabezado debe incluirse para obtener la definición de un tipo particular. En teoría, podría (por ejemplo) construir una gran base de datos de todas las funciones, clases, tipos, etc., en todos los encabezados que haya escrito, y cuando use uno, le dirá qué encabezado (s) define qué nombres , pero no conozco un IDE que realmente lo haga.

2

Si hago referencia a una función llamada sqrt, ¿cómo sabe el compilador qué archivo buscar, si no lo he especificado? Podría ser absolutamente cualquier archivo en mi disco duro completo.

A diferencia de Java, C++ realmente no considera ningún archivo "especial". Java tiene su biblioteca de clases gigante (hinchada), que se pone automáticamente a disposición del programador.

En C++, este concepto no existe. Le dice al compilador qué rutas buscar, y siempre que # incluya un archivo, buscará el nombre del archivo en esas rutas.

Si eso sucede para encontrar un archivo de biblioteca estándar, lo usará. Si encuentra un archivo de un tercero, lo usará.

El compilador no sabe sqrt que se define en la cabecera math.h. O que es también típicamente definido en cmath De hecho, las funciones definidas por un encabezado pueden variar. Quizás, si defino # el símbolo del preprocesador apropiado, algunas funciones se eliminarán de un encabezado específico, y otras se habilitarán.

Pero a diferencia de Java, donde las funciones y clases definidas por una biblioteca se pueden determinar simplemente examinando los metadatos del archivo de biblioteca, en C++, el encabezado debe compilarse.Y el resultado de compilarlo puede variar según el contexto en el que está incluido.

Así que el compilador de C++ no puede adivinar qué encabezado se debe incluir para definir la función que acaba de utilizar.

+0

gracias amigo que tiene mucho sentido – Carlos