while visual una tablas tabla studio multiplicar hacer form con como c# optimization visual-studio-2015 roslyn

visual - tabla de multiplicar en c# windows form



El compilador de Roslyn optimiza la multiplicaciĆ³n de llamadas de funciĆ³n ausente con cero (1)

Sí, definitivamente es un error. <expr> * 0, no debe optimizarse en 0 si <expr> tiene efectos colaterales.

¡Gracias por informar el problema!

Puede seguir el progreso del error / solución en https://github.com/dotnet/roslyn/issues/13486

Ayer encontré este extraño comportamiento en mi código C #:

Stack<long> s = new Stack<long>(); s.Push(1); // stack contains [1] s.Push(2); // stack contains [1|2] s.Push(3); // stack contains [1|2|3] s.Push(s.Pop() * 0); // stack should contain [1|2|0] Console.WriteLine(string.Join("|", s.Reverse()));

Supuse que el programa imprimiría 1|2|0 pero de hecho imprimió 1|2|3|0 .

Al observar el código IL generado (a través de ILSpy), se puede ver que s.Pop() * 0 está optimizado para simplemente 0 :

// ... IL_0022: ldloc.0 IL_0023: ldc.i4.0 IL_0024: conv.i8 IL_0025: callvirt instance void class [System]System.Collections.Generic.Stack`1<int64>::Push(!0) // ...

Descompilación ILSpy :

Stack<long> s = new Stack<long>(); s.Push(1L); s.Push(2L); s.Push(3L); s.Push(0L); // <- the offending line Console.WriteLine(string.Join<long>("|", s.Reverse<long>()));

Primero probé esto inicialmente en Windows 7 con Visual Studio 2015 Update 3 con el modo Release ( /optimize ) y el modo Debug y con varios frameworks de destino (4.0, 4.5, 4.6 y 4.6.1). En los 8 casos, el resultado fue el mismo ( 1|2|3|0 ).

Luego lo probé en Windows 7 con Visual Studio 2013 Update 5 (de nuevo con todas las combinaciones de modo Release / Debug y framework objetivo). Para mi sorpresa, la declaración aquí no está optimizada y arroja el resultado esperado 1|2|0 .

Entonces, puedo concluir que este comportamiento no depende de /optimize ni del indicador de marco objetivo, sino más bien de la versión del compilador utilizada.

Fuera de interés, escribí un código similar en C ++ y lo compilé con la versión actual de gcc. Aquí una llamada de función multiplicada por cero no se optimiza y la función se ejecuta correctamente.

Creo que tal optimización solo sería válida si stack.Pop() fuera una función pura (que definitivamente no lo es). Pero dudo de llamar a esto un error, ¿supongo que es solo una característica desconocida para mí?

¿Está documentada esta "característica" en algún lugar y existe una forma (fácil) de desactivar esta optimización?