¿Cómo saben los compiladores sobre otras clases y sus propiedades?

14

Estoy escribiendo mi primer lenguaje de programación que está orientado a objetos y hasta ahora es bueno crear una 'clase' única. Pero, digamos que quiero tener clases, digamos ClassA y ClassB . Si estos dos no tienen nada que ver el uno con el otro, entonces todo está bien. Sin embargo, digamos que ClassA crea un ClassB - esto plantea 2 preguntas relacionadas:

-¿Cómo sabría el compilador cuando compila ClassA que ClassB existe y, si lo hace, cómo sabe que son sus propiedades?

Hasta ahora, mis pensamientos habían sido: en lugar de compilar cada clase a la vez (es decir, escanear, analizar y generar código) cada "archivo (no realmente el archivo, per se, sino una" clase ") ¿necesito escanear ¿Analizar primero cada uno, luego generar código para todos?

    
pregunta OnResolve 27.06.2012 - 23:02

3 respuestas

13

Diferentes idiomas (y, por lo tanto, compiladores) abordan esto de manera diferente.

En la familia C, los diferentes módulos tienen un archivo de encabezado correspondiente que se usa al crear el objeto. Los archivos de encabezado proporcionan información sobre el tamaño del objeto y qué funciones o métodos existen que pueden invocarse. Esto permite la información necesaria para la asignación de memoria y "¿existe ese método / función / procedimiento?" que se utiliza cuando se realiza la compilación de una sola unidad que no necesita tener acceso a la fuente en sí.

En Java, el compilador es consciente de las cosas en su ruta de clase e inspecciona los objetos para vincularlos (verificando que los métodos existen, tienen el número correcto de argumentos, etc.). Java también puede enlazar dinámicamente en tiempo de ejecución cargando en otras clases de las que no sabe nada cuando se compiló. Consulte Class.forName para un ejemplo de carga dinámica.

Ambas opciones son bastante válidas y tienen su propio conjunto de ventajas y desventajas. Proporcionar archivos de encabezado algunos ven como engorroso y violar en seco . Por otro lado, si no tiene bibliotecas de archivos de encabezado, el compilador y el enlazador deben poder inspeccionarlos: es probable que un archivo .so o .dll no tenga suficiente información para crear una instancia de los objetos o validar las llamadas a métodos ( y sería dependiente de la máquina).

    
respondido por el user40980 27.06.2012 - 23:18
0

Hablando en términos prácticos, con Java, el IDE mira un programa completo a la vez; cuando se hace referencia a ClassB, el compilador IDE lo verá. Todo, incluidas las bibliotecas, es un todo completo. Una vez que el programa está listo, puede cambiar las rutas de clase, intercambiar y eliminar archivos .class individuales y cambiar las versiones de la biblioteca. También puede compilar archivos .java individuales sin usar el IDE (o de alguna manera evitar sus comprobaciones). El resultado no necesita ser coherente en absoluto, y si no es así, obtendrá las excepciones en tiempo de ejecución. (Una de las muchas cosas que un IDE está tratando de hacer por usted es convertir los errores en tiempo de ejecución en tiempo de compilación, o más bien, en tiempo de edición, errores).

C # es más o menos igual, y no creo que C y C ++ sean realmente tan diferentes, ya que lo que están haciendo los IDE de Java y C # es simplemente crear encabezados de estilo C / C ++ detrás de escena.

    
respondido por el RalphChapin 28.06.2012 - 16:25
0

Los idiomas más antiguos a veces son más estrictos; Considera lo que es posible en Java:

public interface Ifc {
    public static final Ifc MY_CONSTANT = new Implem();
}

public class Implem implements Ifc {
}

He visto el anti-patrón de arriba, y es realmente feo (lo habría prohibido). Ambas unidades de compilación se utilizan entre sí. Pero Ifc puede compilarse a código sin tener un Implem compilado. El código compilado, .class, comparable a un C .obj, contiene "información de enlace:" una importación de Implem, que llama a un constructor sin parámetros Implem() . La clase Implem puede entonces compilarse sin problema. En parte, el ClassLoader, haciendo inicialización / compilación de datos de clase JVM, y en parte la propia Máquina Virtual de Java, juega un poco como enlazador , integrando todo.

Por ejemplo, compilar con una versión de una biblioteca específica y ejecutar con otra versión de esa biblioteca reconocerá los errores de tiempo de ejecución.

Por lo tanto, la respuesta: La compilación entrega unidades de código de objeto compilado, que uno tiene que ver como código + datos + API para vincularlos.

El compilador debería luego también hacer un empaquetamiento y verificar la API de vinculación; una segunda fase.

Esto puede irritar y parecer poco elegante, pero las pruebas matemáticas pueden funcionar de la misma manera: al probar toda la corrección, es posible que una parte sea válida hasta la verificación.

    
respondido por el Joop Eggen 24.03.2014 - 23:35

Lea otras preguntas en las etiquetas