Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-12-2011
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
¿Por que funciona al revés el "For to"?

Depurando un código me encontré con este comportamiento raro, primero veamos la imagen:

La variable i como vemos la inicializo "a fuerza" en 1 antes de entrar al bucle, como podemos ver, ya dentro del bucle teóricamente la variable tendría que ir valiendo desde 1 hasta 12, sin embargo como se ve en el watchlist empieza en 12!! Si seguimos dando F8 para irnos paso a paso la variable va disminuyendo hasta 1, es decir, como si hubiera puesto un "For downto".

¿Alguien tiene alguna idea de por qué pasa esto o a alguien más le ha pasado?
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #2  
Antiguo 16-12-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola César.

Esto se debe a la manera en que el compilador genera el código máquina. A fin de optimizar éste, si la variable contador no es referida dentro del For, su existencia es obviada y el código máquina solamente cumple el requisito de repetir el ciclo tantas veces como la cabecera del for lo indica.
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
Var
  I :Integer;
begin
  For I := 1 To 12 Do
    Caption := Caption + 'x';
end;

En cambio, si la variable contador es referida dentro del ciclo, ésta contendrá el valor que se espera.
Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
Var
  I :Integer;
begin
  For I := 1 To 12 Do
    Caption := Caption + IntToStr (I);
end;

Puedes comprobar lo que hay detrás de segmentos de código como los anteriores, ejecutando paso a paso y mirando la ventana CPU del depurador. Notarás que para el primero usa una instrucción DEC mientras que para el segundo emplea una instrucción INC.

Como dato adicional, algo de la ayuda de Delphi que lleva cierta relación con el tema:
Cita:
Empezado por apartado "For statements"
After the for statement terminates (provided this was not forced by a break or an exit procedure), the value of counter is undefined.
Saludos y que haya concluido aquella restricción de teclados.

Al González.
Responder Con Cita
  #3  
Antiguo 16-12-2011
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 22
Crandel Va por buen camino
Cita:
Empezado por Al González Ver Mensaje
Esto se debe a la manera en que el compilador genera el código máquina. A fin de optimizar éste, si la variable contador no es referida dentro del For, su existencia es obviada y el código máquina solamente cumple el requisito de repetir el ciclo tantas veces como la cabecera del for lo indica.
ok, eso es asi. Pero en su caso si utiliza la variable i dentro de su ciclo, salvo que lo halla modificado en tiempo de ejecución.

Un poco extraño lo que sucede.
__________________
[Crandel]
Responder Con Cita
  #4  
Antiguo 16-12-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por Crandel Ver Mensaje
ok, eso es asi. Pero en su caso si utiliza la variable i dentro de su ciclo, salvo que lo halla modificado en tiempo de ejecución.

Un poco extraño lo que sucede.
Tengo entendido que mientras el compilador determine que no exista alguna condición de "orden" o que afecte o condicione la relación entre las sentencias que forman a bloque por más que se referencie la variable dentro dentro del ciclo seguirá implementando, internamente por optimización, un ciclo descendente.

Es decir: a menos que existan instrucciones que afecten el flujo normal de las operaciones, o mientras no existe cierta dependencia de orden entre las propias instrucciones el for será descendente.

Si te fijas en la imagen, da lo mismo que se empiece por CampoDif[1] como por campoDif[12]... siempre logrará hacerlo, en cualquier sentido. Distinto sería si por ejemplo el valor i-ésimo se viera afectado por alguna otra condición o dependencia incluso de algún otro CampoDif[j-ésimo].

Otra manera de "forzar" el for a seguir el camino correcto es desactivar la optimización.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 16-12-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por Crandel Ver Mensaje
ok, eso es asi. Pero en su caso si utiliza la variable i dentro de su ciclo, salvo que lo haya modificado en tiempo de ejecución.

Un poco extraño lo que sucede.
Gracias por la observación, Crandel. Es como si esa I no fuera esa I, algo está faltando...

Delphius: Lo que dices tiene lógica, pero creo que sería muy difícil para el compilador determinar si una referencia de la variable contador dentro del ciclo puede o no puede alterar el resultado de las cosas, cuando tal referencia forma parte de una expresión como "FieldByName...AsFloat". Asumiendo que estamos hablando del FieldByName de TDataSet, esas sentencias involucran llamadas a varios métodos virtuales que según su implementación podrían realizar cualquier cosa. Dichos métodos serían ejecutados en primer lugar con un campo o con otro, dependiendo de si la variable es incrementada o disminuida.

En un código como el que ha mostrado AzidRain, el compilador no debería realizar la optimización mencionada.

César, ¿qué versión del compilador es? Y, aunque la pregunta parezca tonta, ¿el código que muestras es real? ¿Podrías pegar más del mismo aquí?

Saludos.
Responder Con Cita
  #6  
Antiguo 16-12-2011
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Gracias por las respuestas, luego les traigo otras más a modo de curiosidades.
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
El programa se queda "colgado" mientras copia y luego "despierta" NeWsP OOP 5 10-03-2010 22:05:40
No funciona "AGREGAR O QUITAR PROGRAMAS" soler Varios 3 13-01-2008 23:28:12
"(nombre + ' ' + apellidos)" no funciona molina669 SQL 9 07-12-2007 16:36:08
Necesito llamar a métodos de clases "hija" desde su clase "padre" Flecha OOP 17 20-04-2007 00:03:53
Código "erroneo" pero que funciona ixMike Varios 8 11-04-2007 18:57:08


La franja horaria es GMT +2. Ahora son las 10:16:04.


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
Copyright 1996-2007 Club Delphi