From: Leandro Lucarella Date: Sun, 29 May 2005 22:46:37 +0000 (+0000) Subject: Terminado hasta el punto 4. X-Git-Tag: svn_import~8 X-Git-Url: https://git.llucax.com/z.facultad/75.31/presentacion.git/commitdiff_plain/3dcf13b94e63ba8711b64b7a9c36469234cc0ebd?hp=6d7a6a64987f5160f7d457cd8f6311ffb0ba1281 Terminado hasta el punto 4. --- diff --git a/ejemplos/copy_on_write.d b/ejemplos/copy_on_write.d new file mode 100644 index 0000000..20c5908 --- /dev/null +++ b/ejemplos/copy_on_write.d @@ -0,0 +1,27 @@ + +int[] copy(int[] a) +{ + a[0] = 55; + return a; +} + +int[] nocopy(int[] a) +{ + int i = a[0]; + return a; +} + +int main() +{ + int[2] a; + int[] b = copy(a); + printf("COPY:\n"); + printf("Direccion de a = %x\n", cast(int*) a); + printf("Direccion de b = %x\n", cast(int*) b); + printf("\nNO COPY:\n"); + b = nocopy(a); + printf("Direccion de a = %x\n", cast(int*) a); + printf("Direccion de b = %x\n", cast(int*) b); + return 0; +} + diff --git a/ejemplos/pasaje_por_ref.d b/ejemplos/pasaje_por_ref.d new file mode 100644 index 0000000..4b46164 --- /dev/null +++ b/ejemplos/pasaje_por_ref.d @@ -0,0 +1,18 @@ + +class C { int i; } + +void f(C c) +{ + printf("fin: dir c = %x\n", c); + c.i = 1; +} + +int main() +{ + C c = new C; + printf("c.i = %d [%x]\n", c.i, c); + f(c); + printf("c.i = %d [%x]\n", c.i, c); + return 0; +} + diff --git a/presentacion_d.lyx b/presentacion_d.lyx index 7893921..28a50be 100644 --- a/presentacion_d.lyx +++ b/presentacion_d.lyx @@ -772,6 +772,11 @@ Las estructuras, al igual que en C, se almacenan de forma cont compilador optimiza. \layout Subsubsection + +\begin_inset LatexCommand \label{sub:repr-class} + +\end_inset + class \layout Standard @@ -848,12 +853,131 @@ Mencionar operaciones b \layout Subsection Punteros +\layout Standard + +Este lenguaje soporta punteros y referencias, aunque estas últimas son implícita +s (el compilador decide cuando usar una referencia y cuando una copia). + En términos generales, las instancias de clase siempre se referencian a + través de una referencia (jamás se copia un objeto implícitamente). + Como se explicó en la sección +\begin_inset LatexCommand \vref{sub:Operaciones} + +\end_inset + +, se proveen operaciones para tomar la dirección de una variable (su +\emph on +almacén +\emph default +) y desreferenciamiento y aritmética de punteros. + Además se pueden convertir punteros de forma implícita siguiendo algunas + reglas. + Por ejemplo cualquier puntero puede ser convertido implícitamente a un + puntero a +\emph on +void +\emph default + (sin tipo) o a un puntero a una clase ancestro (si es una instancia de + clase). + También se ha dicho que, al igual que en C, hay una relación muy estrecha + entre puntero y array, por lo que cualquier array puede ser convertido + implícitamente a un puntero. \layout Subsection Recolección de basura +\layout Standard + +D provee un recolector de basura, aunque aún no hay muchas definiciones + con respecto a su tipo. + Por el tipo de API que se provee para controlar el recolector de basura, + parece ser del tipo +\emph on +mark-sweep +\emph default + o +\emph on +copy collection +\emph default + ya que se proveen funciones para agregar raices y también parece implementar + algún tipo de algoritmo generacional ya que además de proveer un método + para realizar una recolección completa, provee uno para realizar una recolecció +n generacional. +\layout Standard + +Aunque no parece haber nada definido aún con respecto al recolector de basura + (más que estudiar empíricamente la implementación actual o basarse en lo + que provee la biblioteca estándar para manipular al recolector), se menciona + en varios lugares que el ciclo de colección sólo puede ser lanzado cuando + se intenta alocar nueva memoria. + Es decir, que se puede confiar en que el recolector no va a interrumpir + la ejecución del programa en un fragmento de código en el que no se aloca + memoria. + De cualquier manera, la biblioteca estándar también provee métodos para + desactivar momentáneamente al recolector, por si hay partes críticas del + programa que no deban ser interrumpidas. +\layout Standard + +Además se menciona que el ciclo de recolección debe correr solo; es decir, + que mientras corre el ciclo de recolección no puede haber ningún otro hilo + del programa corriendo al mismo tiempo (cosa que tiene mucho sentido, de + otra forma sería virtualmente imposible seguir el rastro de la memoria). +\layout Subsubsection + +Casos límite +\layout Standard + +D se enfrenta a un problema poco común en la recolección de basura, ya que + la mayor parte de los lenguajes que lo implementan no permiten un manejo + de bajo nivel de la memoria. + Hay varias circunstancias en las cuales el recolector de basura de D puede + fallar. + Veamos algunos casos: +\layout LyX-Code + +void* p; +\layout LyX-Code + +... +\layout LyX-Code + +int x = cast(int)p; +\layout Standard + +En este caso, el comportamiento es indefinido ya que el recolector no verifica + raices que no sean punteros. + Otro caso: +\layout LyX-Code + +void* p = cast(void*)12345678; +\layout Standard + +Si por casualidad la dirección de memoria está siendo manejada por el recolector + de basura, estamos ante un problema. + Otros caso que podrían resultar un tanto confuso es que no se puede confiar + en que un puntero conserve la dirección a la que apunta de forma invariante, + ya que el recolector de basura puede moverlo. + Por lo tanto un código como el siguiente: +\layout LyX-Code + +int* p1, p2; +\layout LyX-Code + +... +\layout LyX-Code + +if (p1 < p2) ...; +\layout Standard + +tiene un comportamiento aleatorio. + Y esto sólo por nombrar algunos problemas que puede acarrear el manejo + de bajo nivel de la memoria usando un recolector de basura. + Claro que si uno necesita un manejo de tan bajo nivel, para estos casos + se puede usar memoria no administrada por el recolector. \layout Subsection Instrucciones +\layout Comment + +por ahora vuela porque no sé a qué se refiere \layout Subsection @@ -864,23 +988,172 @@ Instrucciones Rutinas \layout Standard -Los procedimientos son un caso particular de funciones que no devuelven - nada (void) +D provee varios tipos de rutinas, aunque todos basado en el mismo tipo básico, + las funciones. +\layout Subsubsection + +Funciones planas (sin contexto) +\layout Standard + +Estas son las funciones más básicas. + Son funciones de nivel 0 (en cuanto a anidamiento) o estáticas (ya sean + anidadas o de clase), por lo que no necesitan de un contexto (cadena estática) + más que la ubicación de la porción de variables globales (estáticas). + Toman exáctamente la cantidad de parámetros que se especifica en su declaración. +\layout Standard + +Por supuesto estás funciones tienen acceso sólamente a las variables estáticas + (conocidas en tiempo de compilación y almacenadas en el bloque de datos + del programa), ya sean variables estáticas locales de una función o variables + estáticas de clase (recordar que son todas variables globales con un +\emph on +scope +\emph default + limitado). +\layout Subsubsection + +Funciones con contexto +\layout Standard + +Como ya hemos visto, en D hay algunas funciones que necesitan un +\emph on +contexto +\emph default +. + En esta categoría caen tanto los métodos de una instancia de clase como + las funciones anidadas. +\layout Standard + +En el caso de los métodos es muy claro y simple, además de la función, se + necesita saber sobre qué objeto se está aplicando, así que simplemente + se agrega a los parámetros declarados un puntero (o referencia) a una instancia + de la clase. +\layout Standard + +Con las funciones anidadas puede resultar un poco más confuso. + Estás funciones necesitan el +\emph on +frame pointer +\emph default + de la función +\emph on +padre +\emph default + (lexicográficamente hablando) para poder obtener sus variables locales. + Podría pensarse entonces, como si estás funciones agregan un parámetro + extra con el puntero a ese +\emph on +frame pointer +\emph default +. +\layout Subsubsection + +Funciones virtuales +\layout Standard + +Las funciones virtuales tienen la particularidad de no conocerse su dirección + de memoria en tiempo de compilación, por lo tante es necesario agragar + un nivel de indirección al llamarlas. + Es por esto también que es imposible que exista algún tipo de función virtual + sin contexto, ya que debe haber algún contexto que indique, como mínimo, + la dirección de la función a llamar. + D provee funciones virtuales solamente como métodos de instancias de clase + y lo hace de forma implícita (queda en manos del compilador determinar + si una función debe ser virtual o no), es por esto que guarda, como se + explicó en la sección +\begin_inset LatexCommand \vref{sub:repr-class} + +\end_inset + +, una tabla virtual, en donde se almacena el puntero a cada función virtual + de una clase. + Entonces para llamar a una función virtual, se obtiene el objeto al que + pertenece ( +\emph on +contexto +\emph default +) que tiene una tabla virtual. + El offset de esa función en la tabla virtual sí se conoce en tiempo de + compilación así que simplemente se ejecuta la función apuntada por vtable+4+off +set (el 4 es porque lo primero que se almacena en la vtable es el puntero + al objeto de tipo ClassInfo). \layout Subsubsection Pasaje de parámetros \layout Standard -Por copia en demanda (copy on write) y objetos por referencia. +Las funciones toman parámetros, que son siempre por copia en su implementación + real. + El pasaje por referencia se resuelve al igual que en C, utilizando punteros. + Hay un caso muy particular en D, que son las clases, que siempre son pasadas + por referencias. + Es decir, una variable de clase (que referencia una instancia de una clase) + es siempre de tipo puntero, auque sintácticamente sea utilizada como una + variable común, semánticamente se comporta como un puntero. +\layout Standard + +Varias veces se menciona que los parámetros se copian si hay escritura ( +\emph on +copy on write +\emph default +) en la documentación de D, pero se comprobó empíricamente que, como se + especifica en la sección de manejo de memoria, la copia por demanda se + realiza solamente en la biblioteca estándar, no es algo que provea el lenguaje. \layout Subsubsection -Anidamiento +Funciones con parámetros variables +\layout Standard + +Además soporta, al igual que C, parámetros variables, simplemente proveyendo + métodos para obtener variables de la pila arbitrariamente. + Es decir, a la hora de compilarse un llamado a una rutina con parámetros + variables, se apilan todos los parámetros, se hace el +\emph on +call +\emph default +, y luego se desapilan. + La función llamada tiene entonces, métodos para obtener esos parámetros + extra que no figuraban en la declaración de la función. +\layout Subsubsection + +Sobrecarga de funciones +\layout Standard + +D permite sobrecargar funciones. + Es decir, tener 2 funciones con el mismo nombre pero distintas firmas (cantidad + y/o tipo de parámetros). + Al igual que C++, no permite sobrecargar por el tipo de retorno solamente, + ya que por proveer conversiones implícitas sería imposible desambiguar + muchos casos. + Por supuesto esto también debe poder traducirse a funciones planas por + lo que debe haber una forma de identificar unívocamente a cada función + (con un nombre único, asociado a su dirección de memoria). + Para esto se utiliza una técnica conocida como +\emph on +name mangling +\emph default +, que consiste en transformar los nombres de funciones a un nombre único, + aunque no hay ninguna definición aún al respecto de como debe hacerlo D + (fundamental para poder interactuar entre distintos compiladores, ya que + de otra manera no podría encontrar los símbolos en código objeto compilado + por otro compilador). +\layout Standard + +Entonces el compilador, a la hora de evualuar la dirección de una función + sobrecargada, debe fijarse su nombre y sus parámetros, hacer el +\emph on +name mangling +\emph default + para obtener su identificador único y ahora si proseguir como si fuera + un función común y corriente. \layout Section Estructura del programa \layout Subsection Módulos, espacios de nombres, Interfaces +\layout Standard + \layout Section Orientación a objetos