Foro de elhacker.net

Programación => Programación General => Mensaje iniciado por: z3nth10n en 28 Septiembre 2013, 21:12 pm



Título: Un if realmente se lee cuando la condición es falsa?
Publicado por: z3nth10n en 28 Septiembre 2013, 21:12 pm
Hola buenas, pues puede parecer una pregunta un poco lógica, pero realmente un if (de cualquier lenguaje de programación) es leído por el compilador de dicho lenguaje (aunque no se ejecute lo que contenga dentro) cuando su condición es falsa?

Un saludo.



Según he estado leyendo, el compilador, lee todo, y luego, va clasificando, y si un if es falso, se lo salta...

Ahora la pregunta, como la gente puede saber eso? Como es de fácil o difícil? :huh:

Puede que este tema venga a parecer un poco offtopic, pero bueno, realmente nunca se han cuestionado esto? >:D


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: leogtz en 28 Septiembre 2013, 21:23 pm
No he entendido bien la pregunta.
Código:
if(condicion == true) {
    // SE EJECUTA.
} else {
    // Si la condición es falsa.
}


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: z3nth10n en 28 Septiembre 2013, 21:25 pm
A ver, no es dentro del código, dentro del compilador, como dije:

Citar
el compilador, lee todo, y luego, va clasificando, y si un if es falso, se lo salta...

Me pregunto, como la gente llega a esas conclusiones, bueno, a no ser que sean los mismos programadores del compilador, entonces... Como pueden llegar a extraer dicha información y conclusiones? :huh:


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: Juan. en 28 Septiembre 2013, 21:28 pm
Depende del lenguaje, en C# y por ende VB no se evalua si el compilador puede deducir que es falsa, no solo con los if, las variables no inicializadas nunca llegan a reservarse memoria por poner otro ejemplo. En ese sentido es algo inteligente y predice lo que ocurrirá

Otros lenguajes no tienen esa capacidad


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ~ en 28 Septiembre 2013, 21:52 pm
Si hablamos en tiempo de compilación, incluso compiladores antiguos como el de Turbo C++ (para DOS) tenían la capacidad de detectar cosas como si había variables que nunca se usaban o código que nunca se iba a ejecutar (si estaba despúes de un return y no había ningún goto hacia este).

La dificultad de hacer eso depende de la complejidad del problema y es una tarea mejor realizada por un proceso automático porque requiere llevar el control de las variables que nunca se modificaron y también de las porciones de código que quedaron fuera del flujo normal de ejecución en todos los casos.





Si hablamos en tiempo de ejecución, tenemos que recordar que los compiladores modernos aplican optimizaciones, y el código generado casi nunca refleja el código fuente original.

Pero en términos generales, tenemos que tener una idea de cómo corre el código de máquina o bytecode en cuanto a las decisiones condicionales.

Para un IF, se aplican un grupo de reglas de precedencia de paréntesis, y cómo actuar ante combinaciones de AND y OR lógicos.

Por ejemplo, si tenemos 5 variables con AND:

Código:
if(variable1 && variable2 && variable3 && variable4 && variable5)
{

}


El programa tiene que asegurarse de que ambas variables/condiciones/expresiones se cumplan. Si la primera, o segunda o tercera variable/condición/expresión no se cumple, entonces efectivamente llega hasta ahí y se salta comprobar el resto de expresiones. Un AND debe comprobar hasta el final, o saltarse el resto de la comprobación del IF sin ejecutar lo que contiene tan pronto como una condición no se cumpla.


Por ejemplo, si tenemos 5 variables con OR:

Código:
if(variable1 || variable2 || variable3 || variable4 || variable5)
{

}


En este caso, si la primera, o segunda variables se cumplen, entonces se salta el resto de la comprobación y ejecuta lo que contiene el IF. Con OR, lo que contiene el IF se ejecuta tan pronto como se cumple una condición, ejecuta lo que contiene, y se salta el resto de las expresiones del IF.

Con paréntesis y combinaciones de AND y OR esto se vuelve más complejo, pero es una cuestión de resolver paso a paso cada nivel de paréntesis en la secuencia correcta, y podemos ver para muchos casos qué partes de la expresión del IF se van a ejecutar y cuáles se van a saltar. Los casos en los que todas las expresiones de un IF se cumplen son una minoría.

También debemos recordar el comportamiento de las instrucciones, por ejemplo para procesadores x86, que sirven para saltos condicionales. Tenemos, entre otras, ja (mayor sin signo), jae (mayor o igual sin signo), jb (menor sin signo), jbe (menor o igual sin signo), je (igual), jne (no igual), además de usar jmp (salto incondicional) como útlimo recurso cuando todo el IF no se cumplió. Para OR, es más eficiente usar el caso de la instrucción directamente reflejada por la expresión lógica, y para AND, es más eficiente usar la operación de salto condicional opuesta al de la expresión en el código fuente.


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: z3nth10n en 28 Septiembre 2013, 22:15 pm
Y tu donde has aprendido todo eso? :o


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: $Edu$ en 28 Septiembre 2013, 23:39 pm
Tu lo que quieres saber es aprender ingenieria inversa junto con lenguaje ensamblador para aprender como funciona un procesador, la memoria, ahi sabras como se ejecuta cada cosa.


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: BlackM4ster en 30 Septiembre 2013, 08:25 am
Hay varios tipos de compiladores. Los hay que leen el código entero, lo compilan, y luego ejecutan y los que van compilando y ejecutando linea a linea.

Algunos de linea a linea, nunca llegan a compilar ciertas cosas


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: z3nth10n en 30 Septiembre 2013, 15:34 pm
Hay varios tipos de compiladores. Los hay que leen el código entero, lo compilan, y luego ejecutan y los que van compilando y ejecutando linea a linea.

Algunos de linea a linea, nunca llegan a compilar ciertas cosas

Y como se como funciona el mío? :P


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ABDERRAMAH en 1 Octubre 2013, 20:02 pm
hay que ver los códigos generados por el compilador, normalmente necesitaras dominar ensamblador para leerlo. compilar linea a linea esta mal expresado, porque compilar, la misma palabra hace referencia a juntar todos los codigos maquina necesarios para crear el programa. Eso se llama interpretar, y en ese caso deberias debuguear el codigo mientras se ejecuta, y todo sera mas ilegible.


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: BlackM4ster en 3 Octubre 2013, 08:27 am
ABDERRAMAH el sabio jajajajajajajaj


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: El Benjo en 4 Octubre 2013, 02:04 am
jajajajajajajajajajajajajaja Es que no debemos perder el tiempo, Frodo. XD

Bueno, aprovecho para comentar un mito que según sé es falso, pero quisiera saber si alguno de ustedes ha escuchado de él. Se dice que en las aplicaciones de VB.net cuando uno coloca un if de la forma:

Código
  1. If A = True And B = True Then
  2.  
  3. End If

Aunque la primera evaluación sea falsa se hace la segunda evaluación y por ello es mejor realizar un if anidado.

Yo sigo creyendo que es un mito, pero qué dicen ustedes?


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: rir3760 en 4 Octubre 2013, 03:15 am
Una explicacion en detalle de ese tema se encuentra en la pagina Evaluación de "cortocircuitos" en Microsoft Visual Basic .NET (http://support.microsoft.com/kb/817250)

Un saludo


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: .:UND3R:. en 4 Octubre 2013, 03:27 am
Hola soy del subforo de Ing. Inversa paso para intentar aclarar algunas cosas, es que creo que estás algo confundido.

Creo que la pregunta que quieres plantear:
¿Cómo se elabora un if y cómo este actúa?

En cuanto a la elaboración de las instrucciones, estas se realizan en tiempo de compilación o interpretación (dependiendo del lenguaje), creo que entre tus dudas y otros comentarios (que son del todo correcto), no van al tema. Es que ~ tiene toda la razón, pero el plantea la forma de elaboración en tiempo de compilación. Si quieres más detalles, deberías estudiar Teoría atómata y de compiladores, una ciencia en donde podrías crear tu propio lenguaje de programación (si es que entiendes la teoría que hay detrás de los compiladores).

Ahora la pregunta es cómo el IF actúa, la estructura del if depende netamente del compilador, pero la comparación generalmente llega a una comparación CMP (instrucción de lenguaje ensamblador).

Código
  1. if (var_a == true) {
  2. return 0;
  3. }
  4. .....
  5. ....
  6. ..

Esto en lenguaje ensamblador sería más menos así (reitero esto depende del compilador):

Código
  1. mov eax, dword ptr:[40381200] ; mueve el contenido de una dirección de memoria a la variable eax
  2. cmp eax,1 ; compara si eax (variable cual posee el contenido de var_a) es 1.
  3. jne continuar ; si no se cumple se dirigirá al label o etiqueta continuar.
  4. retn ; retorna a la dirección apuntada al principio del stack o pila
  5. continuar:
  6. ......
  7. ....
  8. ..

Espero que se entienda más menos


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ABDERRAMAH en 4 Octubre 2013, 10:11 am
jajajajajajajajajajajajajaja Es que no debemos perder el tiempo, Frodo. XD

Bueno, aprovecho para comentar un mito que según sé es falso, pero quisiera saber si alguno de ustedes ha escuchado de él. Se dice que en las aplicaciones de VB.net cuando uno coloca un if de la forma:

Código
  1. If A = True And B = True Then
  2.  
  3. End If

Aunque la primera evaluación sea falsa se hace la segunda evaluación y por ello es mejor realizar un if anidado.

Yo sigo creyendo que es un mito, pero qué dicen ustedes?

pues te respondo co toda seguuridad, se comprueban las dos condiciones, y estoy tan seguro por la existencia de los operadores andalso y orelse, que sirven para ignorar las demas condiciones si la sentencia no puede ser verdadera


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: Eleкtro en 4 Octubre 2013, 15:15 pm
Aunque la primera evaluación sea falsa se hace la segunda evaluación y por ello es mejor realizar un if anidado.

En lugar de anidar podemos servirnos del resto de operadores del lenguaje (los que ya ha nombrado ABDERRAMAH),
solo es necesario leer la referencia de los operadores de VBNET para entender como funcionan y saber las expresiones que se evaluan y las que no...

-> Logical/Bitwise Operators (Visual Basic) (http://msdn.microsoft.com/en-us/library/2h9cz2eb.aspx)

Saludos!


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ivancea96 en 4 Octubre 2013, 17:04 pm
Hablando de C++:

En un IF con varias condiciones unidas por un AND (Ejemplo: "if(1 && 0);"), se leen en orden, y en el momento en que una sea falsa, acaba con el IF. Esto lo podemos ver fácilmente (¬¬ vagos) con un código como este:

Código
  1. #include <iostream>
  2. bool asd(){
  3. std::cout << "Hola";
  4. return false;
  5. }
  6. int main () {
  7. if(2==0 && asd());
  8. system("pause>nul");
  9. }

Compilado con MinGW*

Haced la prueba en VB, y los lenguajes que uséis, y así tenemos este hilo para saber que lenguajes leen todas las condiciones xD

Respecto a la pregunta original, Ikillnukes, el compilador lo que hace es compilar, no averiguar si las condiciones (excepto las del tipo "#if") son o no son verdaderas.


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ~ en 4 Octubre 2013, 22:16 pm
jajajajajajajajajajajajajaja Es que no debemos perder el tiempo, Frodo. XD

Bueno, aprovecho para comentar un mito que según sé es falso, pero quisiera saber si alguno de ustedes ha escuchado de él. Se dice que en las aplicaciones de VB.net cuando uno coloca un if de la forma:

Código
  1. If A = True And B = True Then
  2.  
  3. End If

Aunque la primera evaluación sea falsa se hace la segunda evaluación y por ello es mejor realizar un if anidado.

Yo sigo creyendo que es un mito, pero qué dicen ustedes?

No es cierto. Un código compilado que ejecutara todo el IF aunque este ya no cumpla una condición requerida sería extremadamente ineficiente. De hecho no es tan difícil programar a mano este tipo de optimización, y es más breve y hasta claro.

Por ejemplo para el código anterior sería más eficiente compilarlo así:
Código:
1. comparar A==TRUE
2. si es FALSE, terminar el IF en 6 (y no se ejecuta la siguiente condición)
3. comparar B==TRUE
4. si es FALSE, terminar el IF en 6

5. { Código dentro del IF }

6. terminar el IF


Que compilarlo así:
Código:
1. comparar A==TRUE
2. si es TRUE, seguir comparando en 3 (un salto inmediato poco inteligente)
3. comparar B==TRUE
4. si es TRUE, entrar en el IF en 6
5. ir a terminar el IF en 7

6 { Código dentro del IF }

7. terminar el IF


Son más comprobaciones ejecutadas sin razón cuando se sabe que si se usa AND y no se cumple no hay caso de seguir ejecutando, y requiere un salto incondicional como terminador del IF (en el segundo caso, que es más ineficiente). Y si el IF fuera mucho más complejo, la ejecución sería menos que óptima, y eso no sería aceptable en aplicaciones de grado industrial que tienen elementos mucho más complejos que esto.



Hablando de C++:

En un IF con varias condiciones unidas por un AND (Ejemplo: "if(1 && 0);"), se leen en orden, y en el momento en que una sea falsa, acaba con el IF. Esto lo podemos ver fácilmente (¬¬ vagos) con un código como este:

Código
  1. #include <iostream>
  2. bool asd(){
  3. std::cout << "Hola";
  4. return false;
  5. }
  6. int main () {
  7. if(2==0 && asd());
  8. system("pause>nul");
  9. }

Compilado con MinGW*

Haced la prueba en VB, y los lenguajes que uséis, y así tenemos este hilo para saber que lenguajes leen todas las condiciones xD

Respecto a la pregunta original, Ikillnukes, el compilador lo que hace es compilar, no averiguar si las condiciones (excepto las del tipo "#if") son o no son verdaderas.
Eso depende de la comprobación y de la forma en la que se optimiza el código. Si por ejemplo hay valores constantes que siempre van a evaluar a verdadero o a falso, el compilador haría bien en eliminarlos, entre otras optimizaciones más complejas. Tener que comprobar todas las condiciones determinables en tiempo de compilación debería ser una optimización básica. También es necesario realizar otras comprobaciones para las demás optimizaciones y para eso se necesita algún nivel de evaluación del IF (el simple hecho de tener que compilarlo requiere eso).


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: Juan. en 5 Octubre 2013, 16:45 pm
En VB no lo puedo confirmar, lo odio y no pienso probar nada, pero en C# si se evalua false el primero el otro no se realiza

Código:
public static Boolean a() {
    Console.WriteLine("Entro en A");
    return false;
}

public static Boolean b() {
    Console.WriteLine("Entro en B");
    return false;
}

private static void Main() {
    if (Program.a() && Program.b()) {
                Console.WriteLine("Entro");
        }
}

Este código solo imprime entro en a, nada de lo demás


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ABDERRAMAH en 8 Octubre 2013, 14:13 pm
¿C# no dispone del equivalente a andalso y orelse?


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ivancea96 en 8 Octubre 2013, 15:08 pm
Acabo de ver: los OR y los AND, en el momento que uno sea true o que uno sea false (respectivamente), ya no se evalúa nada más.

*Visual Basic*


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: Eleкtro en 8 Octubre 2013, 18:12 pm
¿C# no dispone del equivalente a andalso y orelse?

Si:

Código:
&& = AndAlso
|| = OrElse

Acabo de ver: los OR y los AND, en el momento que uno sea true o que uno sea false (respectivamente), ya no se evalúa nada más.

*Visual Basic*

Eso no es correcto, ocurre todo lo contratio a lo que has comentado,
para simular un OrElse y/o AndAlso en VB6 habría que agrupar expresiones:

Código:
(<Boolean Value 1> Or <Boolean Value 2>) And <Boolean Value 3>

Porfavor vuelvan a leer el comentario del compañero ABDERRAMAH sobre estos operadores.

Voy a poner un ejemplo para dejarlo todavía más claro si cabe sobre And y AndAlso en VB.NET:

Código
  1.        Private str As String = Nothing
  2.  
  3.        ' Esto dará una excepción de referencia a objeto no establecida,
  4.        ' Porque la segunda expresión se evalua de todas formas,
  5.        ' y esta intentará leer la longitud de un objeto que es NADA.
  6.        If str IsNot Nothing And str.Length <> 0 Then
  7.            ' Blah blah blah
  8.        End If
  9.  
  10.        ' Esto no dará ningún tipo de excepción,
  11.        ' Porque la segunda expresión no se evaluará si la primera no se cumple.
  12.        If str IsNot Nothing AndAlso str.Length <> 0 Then
  13.            ' Blah blah blah
  14.        End If

Saludos



Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: ivancea96 en 8 Octubre 2013, 18:26 pm
Eso no es correcto, ocurre todo lo contratio a lo que has comentado
En cuanto la expresión va a dar verdadero seguro, o falso seguro, no evalua el resto. Esto viene de MSDN de Windows.


Título: Re: Un if realmente se lee cuando la condición es falsa?
Publicado por: rir3760 en 9 Octubre 2013, 01:55 am
And Operator (Visual Basic) (http://msdn.microsoft.com/en-us/library/sdbcfyzh.aspx):
Citar
In a Boolean comparison, the And operator always evaluates both expressions, which could include making procedure calls. The AndAlso Operator (Visual Basic) performs short-circuiting, which means that if expression1 is False, then expression2 is not evaluated.

Un saludo