Consideremos el siguiente código:
int main() {
int i = 2;
int b = ++i++;
return 3;
}
Se compila con lo siguiente con un error:
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
Esto me parece justo. El incremento de postfix tiene mayor prioridad que el incremento de prefijo, por lo que el código se analiza int b = ++(i++);
y i
es un valor r. De ahí el error.
Consideremos ahora esta variante con paréntesis para anular las prioridades predeterminadas:
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
Este código compila y devuelve 3. Por sí solo, esto me parece justo, pero parece estar en contradicción con el primer código.
La pregunta: ¿por qué (++i)
es un lvalue
cuándo i
no?
¡Gracias!
ACTUALIZACIÓN: el mensaje de error que se muestra arriba era de gcc (x86-64 9.2). Aquí está la representación exacta: error con gcc
Clang x86-64 9.0.0 tiene un mensaje bastante diferente: error con clang
<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
Con GCC, tiene la impresión de que el problema está en el operador de postfix y luego puede deambular por qué ++i
está bien y i
no, de ahí mi pregunta. Con Clang es más claro que el problema está en el operador de prefijo.
Respuestas:
i
y++i
son ambos valores, peroi++
es un valor.++(i++)
no puede ser válido, ya que++
se está aplicando el prefijoi++
, que es un valor r. Pero(++i)++
está bien porque++i
es un valor.Tenga en cuenta que en C, la situación es diferente;
i++
y++i
son ambos valores. (Este es un ejemplo de por qué las personas deberían dejar de asumir que C y C ++ tienen las mismas reglas. Las personas insertan estos supuestos en sus preguntas, que luego deben ser refutadas).fuente
Esta declaración
es equivalente a
El operador de incremento de postfix devuelve el valor del operando antes del incremento.
Del estándar C ++ 17 (8.2.6 Incremento y disminución)
Mientras que el operador de incremento unario devuelve lvalue después de su incremento. Entonces esta declaración
es válida. Podrías por ejemplo escribir
Del estándar C ++ 17 (8.3.2 Incremento y decremento)
Tenga en cuenta que en C los dos operadores devuelven un valor en lugar de lvalue. Entonces en C esta declaración
es inválido.
fuente
No.
i
no es un valor.i
es un valori++
es un rvalue (prvalue para ser específico).fuente