Hablamos entonces de referencias como -cualquier tipo de- objeto a ser localizado en el algoritmo.
No. Una referencia es cualquier miembro del código fuente que se incluyó en la tabla de símbolos. Puede ser desde una expresión, a un método, un tipo de datos complejo. La expresión será reducida y convertida (en general) a notación polaca inversa antes de hacerla consignar como lista para compilar... etc...
La tabla de símbolos es una tabla con estructura de árbol, por lo general montada sobre una tabla hash por eficiencia, y que recoge absolutamente todos los datos precisos del código de un módulo... los detalles exactos son propios de cada implementación.
En general antes de escribir nada a fichero, primero se lee el código en memoria y se realizan las fases primeras de análisis y en algún punto cada compilador decide escribir ya los ficheros, generlamente cuando pasa el análisis semántico sin errores 'graves' (los típicos ficheros de código objeto). Ya expliqué más arriba las razones frecuentes para escribirlos y todavía alterarlos...
Los pases son, en pocas palabras, un ordenamiento (en todo sentido) del proceso de compilacion.
y ¿como calcula el compilador el numero de pases que son necesarios, en ese caso (o cualquier otro)?
No. Un pase no tiene nada que ver con ordenar, ni tampoco se calculan la cantidad de pases.
El número de pases es una cuestión de diseño, de la forma en que haya sido concebido el compilador para manejar el lenguaje que compila.
De hecho las operaciones que realice en uno u otro pase, es también dependiente del diseño del compilador... yo simplemente señalo la 'separación lógica' (para entenderlo), en dos fases bien claras y definidas, en un pase suele hacerse en análisis léxico (para encontrar errores con 'tokens' no reconocibles y el análisis sintáctico (para ver que aunque cada token se reconoce la propia línea tiene sentido... y se reconoce como bien formada, esto como mínimo...
En el segundo pase se aborda como mínimo el análisis semántico, aunque habrá compiladores que lo realicen en el primer pase, una optimización de código y un pase a un código intermedio aunque esto suele dejarse para lo último.
Luego interviene el linker que toma todos los módulos y construye con todos el ejecutable, todavía suele proceder resolver algunas referencias como ya expliqué, aunque nuevamente dependerá del diseño, pudiera ser que el compilador haya resuelto ya las referencias y el linker simplemente ensamble todos los módulos junto y lo pase definitivamente al código intermedio o al código nativo... piensa que no hay reglas fijas... hay pasos que resolver pero cada cual diseña que pasos resuelve en que sitio y cuales en otro.
Tambén es frecuente que haya más de una fase de optimización del código. Aunque si son demasiadas puede sufrir demora.
El codigo objeto es entonces mas bien informacion que codigo, que el enlazador utiliza para enlazar.
No. El código que consta ahí, es como mínimo una aproximación al código definitivo, si es cierto que pueda adjuntar cierta info precisa para que el linker utilice y que luego descarte. Nuevamente depende del diseño. En general esa info suele ser mínima y tan mínima que lo típico es que se pase en la cadena de comandos... si fueran tan amplia que algún límite en el string lo pudiera cortar, pués puede que el diseñador haya decidido volcar dicha info en algún fichero.
Por ejemplo la cadena de comandos puede estar solicitando que se cree una dll, en vez de un exe... o un driver, o que adjunte también métodos para depuración etc, etc...
Esto me genera un poco de confusion.
Entonces seria algo asi: el compilador se encarga del ordenamiento del algoritmo principal, en forma de "arbol" (digamos).
No hay nada que ordenar a no ser que te refieras a poner las cosas en su sitio... pero no precisa ningún orden específico salvo el lógico que mantiene el propio proyecto.
Si un proyecto se compone de 12 módulos (por ejemplo), uno de ellos será el primero sin duda, el resto no tiene tanta relevancia que posición ocupen, puede que el compilador los tome por orden alfabético del nombre del fichero o puede que haya alguna pesquisa adicional que el propio proyecto aporte y que pueda utilizar para seguir cierto orden (caso de varios proyectos, donde siempre hay uno que es el principal y los otros secundarios)... en general si hay dependencias dichos módulos se compilan antes... el diseño del proyecto suele aportar dicha info, pero si no hay dependencias, y todos los módulos tienen igual relevancia no importa el orden en que se tomen.
Y el enlazador se encarga del ordenamiento de su interaccion con este exterior compuesto de librerias de enlace dinamico, librerias estaticas, etcetera. ¿no?
No sé porque insistes en un 'orden'.
A ver, lo más parecido a 'orden' que te haya indicado es la palabra 'correlativo'...
Supongamos que eres un profesor y x niños van a acudir a un cine y tu los vas a llevar... a medida que suben al bus, si la lista está vacía, tu anotas el nombre de cada uno de forma correlativa (uno debajo del otro), por claridad, no anotando en una línea 3 en otra uno , 5 líneas vacías...
Y si la lista ya está ocupada (porque en otro pase previo ya la completaste), pués ahora señalas una x o tachas cada nombre... antes de salir con el bus repasarás la lista si falta alguno, lo buscarás o puede que haya una nota y ponga que el padre del niño lo entrega 30 km mas allá... (imagina que los llevas al cine en otra ciudad, o al zoo que no lo hay e cualquier sitio)... igual que tienes que resolver esa lista, con cada detalle, problema y anotación, no es disitnto resolver el asunto de las referencias... puede que un niño quisier air pero no haya espacio en el bus, aún así lo tienes anotado, imagina que ahora te llama el padre de2 de ellos y te dice que Pedrito y Juanito no irán porque tienen fiebre, pués tienes que remplazarlos por esos que anotaste al final d ela lista y queen principio no cabían en el bús,, llamas a sus padres y ves si todavía están interesados, etc... imagina los posibles vericuetos y entiende que resolverlos requiere más o menos pasos, pero ya conocidos y cada viaje es disitnto tendrá sus cosas disitntas a otro previo...
Cuando el compilador encuentra en un módulo, 20 variables a nivel de módulo, 15 métodos, 3 subclases, 3 enumeraciones y 2 estructuras... pués las variables las pondrá juntas al comienzo, en el bloque de datos (pero no importa el orden en que estén lo normal es que se pongan correlativas tal y como se las ha encotnrado en el código. Debajo pondrá las direcciones de las métodos en la raíz del módulo porque son métodos estáticos igual que las variables... en cambio todo lo que es dinámico, como las clases y estructuras aunque también las ponga debajo, en realidad cuando se invoquen (en tiempo de ejecución se clonarán los datos que tengan para ser puestos en la pila (típicamente. admeás ese conado suele ser que se colocan en orden inverso a como aparecen en el código, de hecho es una forma de reconocer que están en la pila), la dirección de entrada al código seguirá estando debajo (también correlativo), junto con su código, pero cada instancia usará el bloque de datos que se haya clonado en la pila... las constantes de enumeración igualmente constarán donde las variables, si bien en los ejecutables pueden ser eliminados pues remplazan en el código el valor que corresponde allí donde se nombran, en cambio en librerías permanecen, como enumeración (con su nombres y valor) porque se usarán por su nombre, forman parte d ela propia autodocumentación de una librería... Nuevamente en ese caso es cosa del diseñador edel lneguaje donde y como ubicar esa ayuda de la documentación de las librerías. es típico hacer una copia en un ficheor aparte que luego se imorta o referencia desde el IDE cuando se está programando (como sucedes con las famosas librerías TLB, por ejemplo).
En fin, no hay que ordenar solo recorrer y poner valores correlativos...
1 byte direccion X, un entero de 4 bytes x +1, un string x+5, una estructura de 37 bytes x +9, una estrucutra de 8 bytes x + 46... un metodo estatatico x+54, otro método, x+54 más lo que ocupe el código del anterior, etc... pero al principio es solo una aproximación, si hay alguna referencia que resolver se anota donde queda atrancado, y desde ahí en adelante habrá que reasignar direcciones correlativamente desde donde se quedó... La tabla de símbolos asiste en todo momento con esos detalles que están presentes y que faltan.
Por ejemplo imagina que hay una directiva include... que coloca cierto código en una parte... pués tocará dejar hueco para realojar ese include... aunque lo general es que cuando un lenguaje admite directivas include, hace un preprocesamiento como fase previa en el compilador, antes incluso de la fase d eanálisis léxico, justamente ahí es importar código fuente, al código fuente que tenía el programador, pero a veces una directiva, puede solicitar que por eficiencia haga un 'inline' esto es que en vez de hacer una llamada a cierta librería, si solo aparece en el código 3 veces y apenas son unas instrucciones las incluye en el código en vez de hacer una llamada a la función de una determinada librería, especialmente si se llamará muchas veces (caso de bucles), por lo que donde antes había una llamada y ocupada x bytes de espacio, ahora hay que alojar quizás y bytes remplazando esa llamada...
Y ¿es el compilador o el enlazador el que auna los algoritmos de un mismo proyecto? Por deduccion de lo anterior pensaria que es el compilador.
El compilador no entiende de 'algoritmos' eso es solo a nivel del programador... un compilador solo entiende el lenguaje en el que está escrito el código, ni mas, ni menos. Dehecho una vez que pase la fase del análisis semántico es cuando se empieza a escribir el código intermedio y ahí ya ni el análisis sintáctico ni el sintáctico saben ya nada de eso, se etapa empieza con el código fuente y acaba cuando lo entrega a l analizador semántico y dispone ya de la tabla de símbolos...
El compilador tiene la misisón de compilar cada módulo que tenga un proyecto, pero quien finalmente los une todos en un solo fichero (o librería), es el linker...
Uf. Cuanto necesitaba leer este articulo.
Me parece interesante que la ignorancia pueda ser una fuente de creatividad. Yo no conocia las maneras en las que se realiza esto y como consecuencia invente varias maneras de hacerlo.
Un compilador tiene demasiados detalles como para describirlos en mensajes, lo que no impide que de una manera imprecisa pueda darse explicaciones que den un bosquejo que aclare ciertas dudas. La exactitud de cada detalle en cambio requiere meterse a fondo.
Corrijo ortografía... se me escapan letras, porque escribo muy rápido y en el teclado se traba a veces alguna tecla por culpa de algunas miguitas que van dando vueltas rebotando entre las teclas...