Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Trucos (https://www.clubdelphi.com/foros/forumdisplay.php?f=52)
-   -   Uso de Const con parámetros String (https://www.clubdelphi.com/foros/showthread.php?t=80501)

marcoszorrilla 29-06-2006 22:51:31

Uso de Const con parámetros String
 
Como todos sabemos, Delphi permite utilizar el modificador const en la declaración
de un parámetro. Esto tiene un doble efecto:

Comprueba que el implementador de la rutina no realice modificaciones directas sobre
el parámetro. Como corolario, asegura al cliente de la rutina que no se realizarán
modificaciones sobre el parámetro, por lo que puede pasar sin problemas variables a
dicho parámetro.

El compilador puede optimizar el traspaso de parámetros cuya representación binaria tenga
más de 4 bytes (las variables reales se tratan de forma diferente).

El último punto es muy importante para poder programar aplicaciones eficientes. Cuando
un parámetro cuya representación ocupa más de 4 bytes se pasa por valor (es decir, sin
especificar var o const), la rutina debe realizar una copia del mismo, para que si se
realizan modificaciones sobre el parámetro, no sean visibles por el código que llama a
la rutina. Y, por supuesto, esta copia es una operación potencialmente costosa.

Retrocedamos a la época de Delphi 1, cuando el tipo string se representaba como un array
de 256 caracteres. Cada vez que se pasaba una cadena por valor a un procedimiento o
función, se producía la copia de 256 bytes desde la variable original hacia la memoria
de pila de la rutina. Sin embargo, si la cadena se hubiera pasado por referencia
(utilizando var), solamente se hubiera pasado a la rutina el puntero a la cadena original,
y la copia no se produciría. ¿El coste? Pues que la rutina podría potencialmente realizar
modificaciones sobre la variable original (todo un riesgo), y que solamente podríamos
pasar variables a la rutina, no constantes o expresiones en general.

Por eso Borland introdujo el modificador const, inspirado en C++. Este tipo de traspaso
ofrece lo mejor de ambos mundos: permite pasar un puntero a la variable, lo cual es más
eficiente. Si queremos pasar una expresión, el compilador genera una variable auxiliar
oculta, evalúa la expresión y la almacena allí, y pasa la dirección de la temporal. Y se
evita la copia de la cadena, pues el implementador tiene prohibido escribir sobre la cadena.

Hasta aquí bien, ¿no? El problema es que al aparecer Delphi 2 se cambió la representación
de las cadenas de caracteres. En vez de representarlas como un array de caracteres directo,
las nuevas versiones de Delphi y C++ Builder utilizan un puntero a dicho array. Tanto si
utilizamos const como si no lo hacemos, Delphi pasa un puntero a la rutina, y no saca
copia local de la cadena. ¿Tiene sentido seguir utilizado const? En primer lugar, recuerde
que siguen existiendo tipos de datos en Delphi que pueden seguir beneficiándose de este
modificador: los arrays y los records, por ejemplo. Pero también es beneficioso seguir
utilizando const con parámetros de cadenas.

¿Por qué? No es evidente, pero intentaré explicarlo en pocas palabras. Delphi evita la
copia de la cadena manteniendo un contador de referencias para cada cadena. Al asignar
una cadena a un parámetro o a cualquier otra variable, se incrementa este contador. Si
alguien intenta modificar la cadena, Delphi comprueba que no haya más de una referencia
a la misma. De haberlas, se produce lo que Borland denomina copy-on-demand
(copia por demanda): ahora sí se crea una nueva copia de la cadena, sobre la cual se
realiza la modificación.

Por lo tanto, si declaramos un parámetro de cadena mediante el modificador const, nos
ahorraremos el incremento y el decremento del contador de referencias del valor que
pasemos, operación que normalmente realizaría la rutina implícitamente. Aunque esta
actividad es menos costosa que una copia, si estamos llamando a la rutina en cuestión
dentro de un bucle puede ahorrarnos tiempo y, en cualquier caso, espacio de código.


La franja horaria es GMT +2. Ahora son las 19:13:52.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi