2010-05-06 12 views
6

¿Cómo son los siguientes válidos e inválidos como se muestra y qué significan? ¿Cuándo surgiría tal situación para escribir este fragmento de código? operadoresOperadores de incremento y decremento

++x = 5;  // legal 
--x = 5;  // legal 
x++ = 5;  // illegal 
x-- = 5;  // illegal 
+0

posible duplicado de http://stackoverflow.com/questions/1860461/why-is-i-i-1-unspecified-behavior –

+1

tarea? Pregunta de examen? –

+0

No son realmente los dos. Solo curiosidad por saber. – ckv

Respuesta

13

El postfix (x ++/x--) no devuelven un valor izquierdo (un valor que puede asignar a).

devuelven un valor temporal, que es una copia del valor de la variable antes del cambio

El valor es un valor de lado derecho, por lo que se podría escribir:

y = x++ y obtener el valor antiguo de x

+0

Debe agregar ese código como ese nunca debe ser utilizado. –

+2

@ Bruno: ¿Por qué no? Ese es el punto completo para el operador de incremento posterior. –

7

Todos estos modifican el valor de x más de una vez entre puntos de secuencia y, por lo tanto, son un comportamiento indefinido, que debe evitar cuidadosamente. No veo dónde entra la distinción entre "legal" e "ilegal", ya que el comportamiento es legal, cualquier comportamiento (incluido el envío de correos electrónicos variados al Secretario de Estado) está perfectamente de acuerdo con el Estándar.

5

Suponiendo que la pregunta se trata de operadores incorporados ++ y --, ninguno de estos enunciados es estrictamente legal.

El primero dos son bien formado, es decir, que simplemente compilable porque el resultado de la subasta prefijo es lvalue. Los dos últimos son mal formado, ya que el resultado del incremento postfix no es un valor r, por lo que no se puede asignar.

Sin embargo, incluso los primeros dos no son legales en el sentido de que producen un comportamiento indefinido. Es ilegal modificar el mismo objeto más de una vez sin un punto de secuencia intermedio. (Tenga en cuenta también que los compiladores pueden negarse a compilar código bien formado que produzca un comportamiento indefinido, lo que significa que incluso el primer par podría no ser compilable).

9

Dado que tanto operator =() como operator ++() pueden estar sobrecargados, es imposible decir qué hace el código sin saber más sobre el tipo de cosa a la que se están aplicando los operadores.

+1

Curioso por qué esto fue votado negativamente - el hombre tiene un punto válido. Espero que el OP trate con ints, pero no se menciona ningún tipo. – Puppy

+0

Creo que incluso es posible que esto no dé como resultado un comportamiento indefinido si x es un tipo no escalar. –

+0

@DeadMG: La gente rechazó cosas cuando no pensaban en ellas o pensaban que eran demasiado "elegantes" o "pedantes". –

1

Francamente, nunca debes escribir eso. El postincremento y el preincremento (y los decrementos) solo deben usarse por sí solos. Son solo recetas para la confusión.

+2

Si solo los usa por su cuenta, entonces el incremento de publicación es un operador sin valor. –

+0

Creo que cuando DeadMG dijo "por su cuenta" quiso decir que no hagas doble asignación. Él no quiso excluir cosas como 'if (x ++) {/*...*/}' etc. Right, DeadMG? –

+0

Absolutamente quise excluir esos. El postincremento y el preincremento son azúcares sintácticos, no son buenos cuando se usan realmente en una expresión. Si necesita esto desesperadamente, hágalo manualmente, deje que el compilador lo convierta en la otra forma. Pero no veo en qué condición posible podrías necesitarlo de todos modos. – Puppy

1

El único lugar en el que puedo pensar donde ocurriría tal situación es con una sobrecarga del operador ++ y operador =. Incluso entonces, la definición no está clara. Lo que el código dice básicamente es agregar uno a x, luego asignarle 5. Se plantearía una pregunta como ¿por qué necesitarías incrementar x antes de asignarle 5? La única explicación posible es si tienes algún tipo de clase donde el operador ++ de alguna manera incrementa un contador interno, luego la asignación. Sin embargo, no tengo idea de por qué se necesita tal cosa.

2

++x y --x tanto va a devolver x (después de que se ha incrementado/decrementa). En ese punto, puede hacer lo que quiera con él, incluso asignarle un nuevo valor.

x++ y x-- tanto que devolver lo que fue x (justo antes de se incrementa/decrementa).La alteración de este valor no tiene más sentido que el cambio de valor de retorno de una función ordinaria:

obj->getValue() += 3; // pointless 
Cuestiones relacionadas