Pregunta

en C, tengo este código de la pieza:

int a;
a = 10 + 5 - 3

Quiero preguntar:donde es (10+5-3) almacenados en?(Hasta donde yo sé, a se encuentra en la pila, acerca de cómo (10+5-3)?¿Cómo puede esta r-value se calcula?)

¿Fue útil?

Solución

Normalmente, el valor r se "almacena" dentro del propio programa.

En otras palabras, el propio compilador ( antes de que el programa está vez se ha quedado ) calcula el 10 + 5 - 3 valor (que puede hacerlo, ya que desde que se basa todo en los valores inmediatos constantes), y emite el código ensamblador para almacenar el resultado de este cálculo en cualquier l-valor para la asignacion (en este caso, la variable llamada a, que el compilador probablemente conoce como una dirección con relación a un origen segmento de datos de tipo).

El valor R, que tiene un valor de 12 es, por tanto, sólo se encuentra en el interior del binario del programa, dentro de un conjunto de instrucciones que ve como

  mov <some dest, typically DS-relative>, $0C 

$ 0C es el "valor r".

Si el valor r pasó a ser el resultado de un cálculo que sólo se puede hacer en tiempo de ejecución, por ejemplo si el código subyacente era c: a = 17 * x; // x algún tiempo de ejecución var, el valor r sería demasiado ser "almacenada" (o más bien se materializó) como una serie de instrucciones dentro del programa binario. La diferencia con el simple "mov dest, imm" anterior es que sería tomar varias instrucciones para cargar la variable x en un acumulador, se multiplica por 17 y almacenar el resultado en la dirección donde la variable a es. Es posible que el compilador puede "autorizar a sí mismo" ;-) utilizar la pila durante algún resultado intermedio, etc, pero como se
a)
completamente dependiente del compilador b) transiant
c) y normalmente sólo implicaría parte del valor r
por lo que es seguro decir que el valor r es un concepto de tiempo de compilación que se encapsula en partes del programa (no los datos), y no se almacena en cualquier lugar, pero en el programa binario.

En respuesta a paxdiablo: la explicación ofrecida anteriormente es, en efecto restrictivo de las posibilidades porque el estándar c efectivamente hace no dictan nada de esa naturaleza. Nunca lo menos, la mayoría de cualquier valor r finalmente se materializó, al menos en parte, por algunas instrucciones que prepara las cosas para que el valor adecuado, ya sea calculado (en tiempo de ejecución) o inmediato se dirigió correctamente.

Otros consejos

Las constantes se simplifican probablemente en tiempo de compilación, por lo que su pregunta planteada, literalmente, no puede ayudar. Pero algo como, por ejemplo, i - j + k que no necesita ser computado en tiempo de ejecución de algunas variables, pueden ser "almacenada" siempre que el compilador le gusta, dependiendo de la arquitectura de CPU: el compilador normalmente tratará de hacer todo lo posible para utilizar registros, por ejemplo

 LOAD AX, i
 SUB AX, j
 ADD AX, k

para calcular una expresión "almacenar" en el AX registro acumulador, antes de asignarlo a algún puesto de almacenamiento con STORE AX, dest o similares. Estaría muy sorprendido si un moderno compilador de optimización en una arquitectura incluso semi-decente de la CPU (sí, incluido x 86 -!)! Necesaria para derramar registros en la memoria para cualquier expresión razonablemente simple

Este es el compilador dependiente. Por lo general, el valor (12) se calculará por el compilador. Se almacena entonces en el código, típicamente como parte de una carga / mover instrucciones de montaje inmediata.

¿Dónde se almacena en realidad es completamente hasta el compilador. La norma no dicta este comportamiento.

típica lugar puede ser visto por realidad compilar el código y mirando a la salida del ensamblador:

int main (int argc, char *argv[]) {
    int a;
    a = 10 + 5 - 3;
    return 0;
}

que produce:

        .file   "qq.c"
        .def    ___main;
            .scl    2;
            .type   32;
        .endef
        .text
.globl _main
        .def    _main;
            .scl    2;
            .type   32;
        .endef
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        addl    $15, %eax
        addl    $15, %eax
        shrl    $4, %eax
        sall    $4, %eax
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        call    __alloca
        call    ___main
        movl    $12, -4(%ebp)         ;*****
        movl    $0, %eax
        leave
        ret

El bit correspondiente está marcado ;***** y se puede ver que el valor es creado por el compilador y simplemente inserta directamente en una instrucción de tipo mov.

Tenga en cuenta que es sólo este sencillo debido a que la expresión es un valor constante. Tan pronto como se introduce valores no constantes (como las variables), el código se vuelve un poco más complicado. Esto se debe a que hay que mirar esas variables en memoria (o que ya pueden estar en un registro) y luego manipular los valores en en tiempo de ejecución , no en tiempo de compilación .

En cuanto a cómo el compilador calcula cuál debe ser el valor, eso es que ver con la evaluación de la expresión y es una cuestión de otro conjunto: -)

  • El resultado del cálculo en el RHS (a mano del lado derecho) se calcula por el compilador, en una etapa que se llama "propagación constante".
  • A continuación, se almacena como un operando de la instrucción conjunto móvil el valor en a

Aquí hay un desmontaje de MSVC:

  int a;
  a = 10 + 5 - 3;

0041338E  mov         dword ptr [a],0Ch 

Su pregunta se basa en una premisa errónea.

La propiedad definitoria de lvalue en C es que no tiene un lugar en el almacenamiento, es decir que es almacenado . Esto es lo que diferencia a partir lvalue rvalue . Rvalue es no almacenado en ningún lugar. Eso es lo que lo convierte en un valor de lado derecho. Si se almacena, sería lvalue por definición.

Los términos "lvalue" y "r-value" se utilizan para bisecar el mundo de las expresiones.Es decir, (10+5-3) es una expresión que pasa de ser una r-value (porque no se puede aplicar el operador & a, en C++ las reglas son más complicadas).En tiempo de ejecución, no hay expresiones, lvalues o rvalues.En particular, no se almacenan en cualquier lugar.

Usted se preguntaba donde el valor de 12 años se almacenan, pero el valor de 12 no es ni un lvalue ni un r-value (como contraposición a la expresión 12 lo cual sería un r-value, pero 12 no aparece en el programa).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top