switch sintaxis resueltos funciones ejemplos dev declaracion comandos codigos basicos c++ c language-lawyer

resueltos - sintaxis de c++ pdf



¿Por qué se permiten múltiples preincrementos en C++ pero no en C? (4)

Esta pregunta ya tiene una respuesta aquí:

Por que es

int main() { int i = 0; ++++i; }

C ++ válido pero no válido C?


C y C ++ dicen cosas diferentes sobre el resultado del prefijo ++. En C ++:

[expr.pre.incr]

El operando del prefijo ++ se modifica agregando 1. El operando debe ser un valor l modificable . El tipo del operando debe ser un tipo aritmético distinto de cv bool, o un puntero a un tipo de objeto completamente definido. El resultado es el operando actualizado; es un valor l , y es un campo de bits si el operando es un campo de bits. La expresión ++ x es equivalente a x + = 1.

Entonces ++ se puede aplicar al resultado de nuevo, porque el resultado es básicamente el objeto que se incrementa y es un valor l. En C sin embargo:

6.5.3 Operadores unarios

El operando del operador de incremento o disminución del prefijo debe tener un tipo de puntero o de puntero real, calificado o no calificado, y debe ser un valor l modificable.

El valor del operando del operador de prefijo ++ se incrementa. El resultado es el nuevo valor del operando después del incremento.

El resultado no es un valor l; es solo el valor puro del incremento. Por lo tanto, no puede aplicar ningún operador que requiera un valor l, incluidos ++.

Si alguna vez le dicen que C ++ y C son superconjunto o subconjunto uno del otro, sepa que no es el caso. Hay muchas diferencias que hacen que esa afirmación sea falsa.


En C, siempre ha sido así. Posiblemente porque pre-incrementado ++ se puede optimizar a una única instrucción de código de máquina en muchas CPU, incluidas las de la década de 1970, que fue cuando se desarrolló el concepto ++ .

En C ++, sin embargo, hay que tener en cuenta la simetría con la sobrecarga del operador. Para que coincida con C, el pre-incremento canónico ++ tendría que devolver const & , a menos que tuviese un comportamiento diferente para los tipos integrados y definidos por el usuario (lo que sería un olor). Restringir el retorno a const & es una invención. Por lo tanto, el retorno de ++ se relaja de las reglas de C, a expensas de una mayor complejidad del compilador para explotar cualquier optimización de CPU para los tipos incorporados.


Las otras respuestas explican la forma en que los estándares difieren en lo que requieren. Esta respuesta proporciona un ejemplo motivador en el área de la diferencia.

En C ++, puede tener una función como int& foo(int&); , que no tiene ningún análogo en C. Es útil (y no oneroso) para C ++ tener la opción de foo(foo(x)); .

Imagine por un momento que las operaciones en tipos básicos se definieron en alguna parte, por ejemplo int& operator++(int&); . ++++x sí no es un ejemplo motivador, pero se ajusta al patrón de foo anterior.


Supongo que entiendes por qué está bien en C ++, así que no voy a profundizar en eso.

Para lo que sea, este es el resultado de mi prueba:

t.c:6:2: error: lvalue required as increment operand ++ ++c; ^

En cuanto a CppReference :

Expresiones de objetos no-lvalue

Coloquialmente conocidas como expresiones de objeto rvalues, non-lvalue son las expresiones de tipos de objetos que no designan objetos, sino valores que no tienen identidad de objeto o ubicación de almacenamiento. La dirección de una expresión de objeto no-lvalue no puede tomarse.

Las siguientes expresiones son expresiones de objetos que no son lvalue:

  • todos los operadores no especificados para devolver lvalues , incluyendo

    • operadores de incremento y decremento (nota: los formularios son lvalues ​​en C ++)

Y la Sección 6.5.3.1 de n1570:

El valor del operando del operador de prefijo ++ se incrementa. El resultado es el nuevo valor del operando después del incremento.

Por lo tanto, en C, el resultado de los operadores de incremento de prefijo y de decremento de prefijo no es necesario que sea lvalue , por lo que no se puede incrementar de nuevo. De hecho, tal palabra se puede entender como "requerida para ser valor real".