Posible Duplicar:

Podría alguien explicar estos indefinido comportamientos (i = i++ + ++i , i = i++, etc…)

De acuerdo con el estándar de c++,

i = 3;
i = i++;

va a resultar en un comportamiento indefinido.

Utilizamos el término «comportamiento indefinido», si es que puede llevar a más de un resultado. Pero aquí, el valor final de i será de 4 no importa lo que el orden de evaluación, por lo que no debería esto ser llamado «sin especificar el comportamiento»?

  • No creo que este es un duplicado. OP no quiere una explicación de «un comportamiento indefinido». OP quiere una explicación de los términos utilizados. Tal vez de migrar a english.stackexchange.com? 🙂
  • De donde sacas «voy a ser de 4». No, va a ser indefinido. Se podría igualar a «Queso». Esto podría provocar que los demonios para volar fuera de su nariz.
  • hmm supongo..por eso es indefinido..no no especificado donde el resultado puede ser documentado por la particular aplicación
  • Exactamente que int valor es de queso? 🙂
  • printf("%d", (int)"Cheese");
  • Pensé más a lo largo de las líneas de 0xC63353 😉
  • catb.org/jargon/html/N/nasal-demons.html
  • Posibles duplicados de ¿por Qué son estas construcciones (utilizando ++) comportamiento indefinido en C?

InformationsquelleAutor user388338 | 2011-02-11

8 Comentarios

  1. 28

    La frase, «…el valor final de i será de 4 no importa lo que el orden de evaluación…» es incorrecta. El compilador puede emitir el equivalente de esto:

    i = 3;
    int tmp = i;
    ++i;
    i = tmp;

    o este:

    i = 3;
    ++i;
    i = i - 1;

    o este:

    i = 3;
    i = i;
    ++i;

    Cuanto a las definiciones de los términos, si la respuesta era garantizados para ser de 4, que no ser indeterminado o indefinido comportamiento, sería comportamiento definido.

    Tal y como está, no se ha definido el comportamiento de acuerdo a la norma (Wikipedia), por lo que es aún libre para hacer esto:

    i = 3;
    system("sudo rm -rf /"); //DO NOT TRY THIS AT HOME … OR AT WORK … OR ANYWHERE.
    • modded en la esperanza de que el OP va a entender por qué el «resultado final» no es de ninguna manera predecible, incluso en un buen comportamiento de la interpretación de la norma (es decir, no hay monos o queso).
    • +5 por decir que el sistema(«sudo rm-rf /»);
    • sudo rm -rf / no hacer nada en las versiones modernas de rm donde usted necesita para agregar --no-preserve-root
    • ¿Por qué el compilador siempre «emiten» la última? El operador de sufijo (a mi entender) siempre «devuelve» el valor antes de su operación…estoy de acuerdo en decir que el OP es incorrecto decir que el resultado será 4….a pesar de que su último escenario parece sugerir que podría ser (me refiero a que si este es realmente indefinido yo no cuestionaría. Yo no veo por qué es de mí…)
    • Encuentra la respuesta aquí: stackoverflow.com/questions/4362501/…
  2. 9

    No, no utilizamos el término «comportamiento indefinido» cuando se puede simplemente llevar a más de uno aritmética resultado. Cuando el comportamiento está limitado a diferentes aritmética resultados (o, más en general, a un conjunto de predecible resultados), es lo que normalmente se conoce como no especificado comportamiento.

    Un comportamiento indefinido significa completamente impredecible y consecuencias ilimitadas, como formatear el disco duro de su ordenador o simplemente hacer su programa de choque. Y i = i++ es indefinido comportamiento.

    De dónde sacó la idea de que i debe ser de 4 en este caso no es claro. No hay absolutamente nada en lenguaje C++ que permita llegar a esa conclusión.

    • +1: La única respuesta completa, en mi opinión.
    • Si Java & C# puede definir el comportamiento de i=i++ entonces, ¿por qué C & C++ no se puede?
    • Conocer: ¿por Qué iba a querer? La UB es una consecuencia de la libertad introducidas deliberadamente/izquierda en el lenguaje de especificaciones con el fin de facilitar diversos relacionados con el rendimiento de optimizaciones, hasta el ahorro específico de ciclos de CPU. Esto tiene sentido en la nativo del código de la máquina, que es lo que C y C++ se utilizan normalmente para las. Java fue originalmente desarrollado como una plataforma completamente diferente (VM-based). En que plataforma virtual de la caza específico de ciclos de CPU en el código a nivel de usuario no tiene sentido, ya que la sobrecarga de la VM ya es mucho mayor que el de todos modos. Bajo tales circunstancias, Java optado por la más estricta de la especificación.
    • En otras palabras, C/C++ y Java son muy diferentes plataformas con muy diferentes conjuntos de prioridades, especialmente cuando se trata de bajo nivel de optimizaciones de rendimiento.
  3. 6

    En C y también en C++, el orden de cualquier operación entre dos la secuencia de puntos es completamente hasta el compilador y no puede ser dependiente. El estándar define una lista de cosas que hace que la secuencia de puntos, de la memoria este es

    1. el punto y coma después de una declaración
    2. el operador coma
    3. evaluación de todos los argumentos de la función antes de llamar a la función
    4. el && y || operando

    Mirando la página en la wikipedia, la lista es más completa y se describe más en detalle. La secuencia de puntos es un concepto muy importante y si no ya sabes lo que significa, se benefician en gran medida por el aprendizaje inmediato.

    • sir..he leído esto..es por eso que me dijo que su indefinido de acuerdo a la norma…pero estoy recibiendo la razón por la que su indefinida cuando el valor final es independiente de la orden de la evolución de los operandos
    • Mi interpretación del significado de los indefinidos es que nada menos que implica algunas limitaciones de lo que el compilador está permitido hacer, y no quiero tener que cuando la redacción de la norma.
    • Secuencia punto # 5. el ?: operador
  4. 4

    i= y i++ ambos son efectos secundarios que modificar yo.

    i++ no implica que yo sólo se incrementa después de la declaración entera es evaluada, simplemente que el valor actual de i ha sido leído.
    Como tal, la asignación, y el incremento, podría suceder en cualquier orden.

    • pero independiente de la orden el valor final de la ll permanecer mismo..aunque estoy de acuerdo con este código a[i]=i++; puede provocar diff resultado
    • el valor final puede ser 3 o 4.
  5. 4

    1.
    No, el resultado será diferente según el orden de evaluación. No hay ninguna evaluación de la frontera entre el incremento y la asignación, por lo que el incremento puede ser realizado antes o después de la asignación. Considerar este comportamiento:

    load i into CX
    copy CX to DX
    increase DX
    store DX in i
    store CX in i

    El resultado es que i contiene 3, no 4.

    Como una comparación, en C# no es una evaluación de la frontera entre el evaulation de la expresión y la asignación, por lo que el resultado siempre será 3.

    2.
    Incluso si el comportamiento exacto no está especificado, la especificación es muy clara sobre lo que se cubre y qué no cubre. El comportamiento se especifica como indefinido, no sin especificar.

    • plusone para el C# contraste!
    • inc 1 de la pseudo-código de la asamblea
  6. 2

    Para responder a sus preguntas:

    1. Creo que «un comportamiento indefinido» significa que el compilador del lenguaje/que implementa es libre de hacer lo que cree mejor, y no se que podría dar lugar a más de un resultado.
    2. Porque no no especificado. Es claramente especificado que su comportamiento es indefinido.
  7. 0

    No vale la pena, a las de tipo i=i++ cuando usted podría simplemente de tipo i++.

    • Dónde está tu sentido de la de aventura?
  8. 0

    Vi la pregunta en OCAJP la práctica de la prueba.
    IntelliJ IDEA de decompiler se convierte de esta

    public static int iplus(){
        int i=0;
        return i=i++;
    }

    en este

    public static int iplus() {
        int i = 0;
        byte var10000 = i;
        int var1 = i + 1;
        return var10000;
    }

    Crear FRASCO de módulo, a continuación, importar la biblioteca & inspeccionar.
    Es el comportamiento de los i = i++ realmente indefinido?

Dejar respuesta

Please enter your comment!
Please enter your name here