Esta es la solución más correcta que te podemos compartir, pero obsérvala pausadamente y valora si es compatible a tu trabajo.
Solución:
en la expresión (i, ++i, 1)
la coma utilizada es el operador de coma
el operador de coma (representado por el token
,
) es un operador binario que evalúa su primer operando y descarta el resultado, y luego evalúa el segundo operando y devuelve este valor (y tipo).
Debido a que descarta su primer operando, generalmente es solo es útil donde el primer operando tiene efectos secundarios deseables. Si no se produce el efecto secundario del primer operando, el compilador puede generar una advertencia sobre la expresión sin ningún efecto.
Entonces, en la expresión anterior, el más a la izquierda i
será evaluado y su valor será descartado. Después ++i
se evaluará y se incrementará i
por 1 y de nuevo el valor de la expresión ++i
será descartado, pero el efecto secundario de i
es permanente. Después 1
será evaluado y el valor de la expresión será 1
.
es equivalente a
i; // Evaluate i and discard its value. This has no effect.
++i; // Evaluate i and increment it by 1 and discard the value of expression ++i
i = 1 + 1;
Tenga en cuenta que la expresión anterior es perfectamente válida y no invoca un comportamiento indefinido porque hay un punto de secuencia entre la evaluación de los operandos izquierdo y derecho del operador coma.
citando de C11
capítulo 6.5.17
, operador de coma
El operando izquierdo de un operador de coma se evalúa como un void expresión; hay un punto de secuencia entre su evaluación y la del operando derecho. Luego se evalúa el operando derecho; el resultado tiene su tipo y valor.
Entonces, en tu caso,
(i, ++i, 1)
se evalúa como
i
se evalúa como un void expresión, valor descartado++i
se evalúa como un void expresión, valor descartado- finalmente,
1
valor devuelto.
Entonces, la declaración final parece
i = 1 + 1;
y i
llega a 2
. Supongo que esto responde a sus dos preguntas,
- Cómo
i
obtiene un valor de 2? - ¿Por qué hay un mensaje de advertencia?
Nota: FWIW, ya que hay un punto de secuencia presente después de la evaluación del operando de la mano izquierda, una expresión como (i, ++i, 1)
no invocará UB, como uno mayo generalmente piensa por error.
i = (i, ++i, 1) + 1;
Vamos a analizarlo paso a paso.
(i, // is evaluated but ignored, there are other expressions after comma
++i, // i is updated but the resulting value is ignored too
1) // this value is finally used
+ 1 // 1 is added to the previous value 1
Entonces obtenemos 2. Y la asignación final ahora:
i = 2;
Lo que sea que estaba en i antes de que se sobrescriba ahora.
Aquí tienes las reseñas y valoraciones
Puedes añadir valor a nuestra información contribuyendo tu experiencia en los comentarios.