En C++ hay muchas maneras de escribir código que compila, pero produce undefined behavior (Wikipedia). ¿Hay algo similar en C#? ¿Podemos escribir código en C# que compila, pero tiene un comportamiento indefinido?Código con comportamiento indefinido en C#
Respuesta
Como han mencionado otros, casi cualquier cosa en el bloque "inseguro" puede generar un comportamiento definido por la implementación; El uso indebido de bloques inseguros le permite cambiar los bytes de código que componen el tiempo de ejecución, y por lo tanto todas las apuestas están desactivadas.
El caso de la esquina de la división de enteros tiene un comportamiento definido por la implementación.
Lanzar una excepción y no atraparla ocasiona un comportamiento definido por la implementación: finaliza el proceso, inicia un depurador, y así sucesivamente.
Hay una serie de otras situaciones en C# donde nos vemos obligados a emitir código que tiene un comportamiento determinado por la implementación. Por ejemplo, esta situación:
http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx
Sin embargo, las situaciones en las que un buen comportamiento de programa # segura, C tiene un comportamiento definido por la implementación debe ser bastante raro.
Ouch, ese problema de sobrecarga es realmente extraño. Y pensé que DivisionByZeroException era el comportamiento esperado en '1/0'. De todos modos, voy a +1 esto mañana ... –
¿Quién dijo algo acerca de la división por cero? –
@Eric: Pensé que el caso de la esquina que mencionaste era el habitual 1/0. Busqué y encontré que en realidad es 'int.MinValue/-1'. –
Al mirar el Wiki, las situaciones en las que ocurre un comportamiento indefinido no están permitidas o arrojan una excepción en C#.
Sin embargo, en código no seguro, un comportamiento indefinido Creo que es posible, ya que le permite utilizar punteros etc.
Editar: Parece que estoy en lo cierto: http://msdn.microsoft.com/en-us/library/aa664771%28VS.71%29.aspx
tiene un ejemplo de un comportamiento indefinido en C#
Cuando dice "Wiki", ¿a qué Wiki se está refiriendo? –
SÍ, usar código inseguro puede producir un comportamiento indefinido. +1 –
@Jeff Yates: el vínculo "comportamiento indefinido" en la pregunta va a Wikipedia. – Powerlord
No exactamente en el sentido exactamente Wiki pero supongo que el ejemplo más obvio que se me viene a la mente es simplemente escribir algún código enhebrado, pero luego es así en cualquier idioma.
Eso no es definitivo, no está definido. Todavía tienes la garantía de lo que hará cada hilo. Simplemente no sabes el orden exacto en el que suceden las cosas, por lo que puedes obtener resultados sorprendentes. – jalf
@mfloryan: desafortunadamente, cada vez que genera un nuevo hilo en C# no puede esperar que se inicie un juego de NetHack. Ah, buenos días en los que puedes jugar ejecutando gcc ... –
En general, diría que no.
Utilice la variable automática antes de inicializarla.
Todas las variables deben inicializarse. Si no se produce una excepción.
División por cero
excepción.
Indexación de una matriz fuera de límites
excepción se produce
Como Aequitarum Custodio señaló que puede utilizar código no seguro. Por otra parte, esto no es realmente C#, estás expirando explícitamente del entorno C#.
El código inseguro * es * C#. Lo que está descartando son las garantías del código administrado. –
Esto es * no * C# inseguro { int * px1; int * px2 = & i; F (out px1, ref px2); Console.WriteLine ("* px1 = {0}, * px2 = {1}", * px1, * px2); // comportamiento indefinido } Sí, está escrito con C#. –
Claro, eso es perfectamente legal C#. Una implementación de C# que implementa el subconjunto opcional "inseguro" sigue siendo una implementación de C#. –
De acuerdo con el documento ECMA-334 (p.473):
Un programa que no contiene ningún ocurrencias del modificador inseguro no puede exhibir cualquier comportamiento indefinido .
que promueve 'definido por la implementación' a la peor de los casos, véase la respuesta de Eric Lippert.
No especificado, en lugar de Definido por Implementación, al menos como el término se usa en la especificación C.Si la especificación considera que una implementación está definida como Implementación, entonces se requieren implementaciones conformes para proporcionar documentación suficiente para que el programador sepa exactamente cómo se comportará. Una implementación podría especificar legítimamente que '(char firmado) 128 'arrojaría -126 durante la primera mitad de cada fase de la luna, y -127 durante la segunda mitad, pero solo si la implementación realmente determina la fase de la Luna. Las implementaciones no pueden simplemente decir "produce un valor arbitrario". – supercat
Sí! ¡Existe, incluso en un contexto seguro! (Bueno, es definida por la implementación que no está definido, al menos)
Aquí está uno de Marek Safar y VSadov en el Roslyn issues .Hay un desajuste entre C# y CLI en lo que respecta a bool
.
C# cree que solo hay un tipo de true
, y un tipo de false
.
CLI cree que false
es un byte que contiene 0, y todos los demás valores son true
.
Esta discrepancia significa que podemos obligar a C# para hacer algunos un (marginalmente) interesantes cosas cosa:
//non-standard bool
//We're setting a bool's value to a byte value of 5.
var a = new bool[1];
Buffer.SetByte(a, 0, 5);
//non-standard bool
//We're setting a bool's value to a byte value of 10.
var b = new bool[1];
Buffer.SetByte(b, 0, 10);
//Both are true.
Console.WriteLine(a[0]);
Console.WriteLine(b[0]);
//But they are not the same true.
Console.WriteLine(a[0] == b[0]);
Las salidas anteriores:
true
true
false
Curiosamente, los discrepa depurador (deben evaluar la verdad de otra manera?)
De todas formas, la conclusión de que aparezca el C# equipo que ha llegado a está (énfasis añadido):
ES DECIR el lenguaje permanecerá completamente despreocupado sobre los bools no estándar. La implementación particular (como en MS C# en CIL) reconocerá la existencia de Bools no estándar y especificar su comportamiento como indefinidos
Esto realmente me hizo reír a carcajadas. –
Muchas y subprogramas tienen requisitos que se pueden resumir en:
Cuando se le den datos válidos, produzca resultados válidos.
Absténgase de lanzar misiles nucleares o de negar las leyes del tiempo y la causalidad, incluso cuando se le den datos inválidos.
Uno de los principales objetivos de diseño de Java y.NET es que a menos que el código haga uso de ciertos que están marcados como "inseguros", generalmente no se requiere un esfuerzo particular para cumplir con la segunda restricción anterior [aunque algunos comportamientos relacionados con la recolección de basura y Finalize
pueden ser un poco raros desde el momento/causalidad punto de vista, se pueden describir como excepciones a las reglas normales de causalidad, en lugar de una revocación total de ellas]. Esa situación es muy diferente de la situación en C, donde muchos tipos de errores dependientes de datos (por ejemplo, desbordamiento de enteros) pueden dar como resultado que los compiladores se comporten de forma arbitraria, lo que incluye hacer cualquier suposición que sea necesaria para evitar el desbordamiento. Los tipos realmente horribles de Comportamiento Indefinido que se fomentan en la filosofía C hipermoderna no existen en C# u otros lenguajes .NET fuera de los bloques "inseguros".
- 1. Comportamiento indefinido con const_cast
- 2. ¿Es (++ i) ++ comportamiento indefinido?
- 3. Cómo detectar el comportamiento indefinido
- 4. Fallo en el código C++ debido a un comportamiento indefinido o error del compilador?
- 5. ¿Es este comportamiento indefinido const_cast?
- 6. ¿`y = x = x + 1;` comportamiento indefinido?
- 7. Comportamiento de una expresión: ¿definido o indefinido?
- 8. ¿Este código produce un comportamiento indefinido o simplemente es un comportamiento no especificado?
- 9. ¿INT_MIN% -1 produce un comportamiento indefinido?
- 10. Aliasing del puntero de matriz: ¿comportamiento indefinido?
- 11. ¿Llama explícitamente el resultado de destructor en Comportamiento indefinido aquí?
- 12. Desbordamiento de enteros y comportamiento indefinido
- 13. ¿Por qué es este comportamiento indefinido?
- 14. ¿Cuál es la diferencia en el comportamiento indefinido entre C++ 03 y C++ 11?
- 15. ¿Cuál es el comportamiento indefinido/no especificado común para C con el que te encuentras?
- 16. ¿Está leyendo un comportamiento indefinido de valor indeterminado?
- 17. ¿Cómo hacer un doble fragmento sin un comportamiento indefinido?
- 18. ¿Por qué está llamando al destructor por segunda vez el comportamiento indefinido en C++?
- 19. ¿Limita la confusión causada por el comportamiento indefinido?
- 20. ¿La "optimización del valor de retorno" causa un comportamiento indefinido?
- 21. ¿Qué ejemplos de código perl pueden conducir a un comportamiento indefinido?
- 22. índice indefinido con $ _POST
- 23. Si desbloqueas un mutex ya desbloqueado, ¿el comportamiento está indefinido?
- 24. Común ceceo, comportamiento indefinido de la función de intersección?
- 25. comportamiento indefinido sobre la supresión de carbón gama trought void *
- 26. Adjuntar comportamiento en código detrás de
- 27. ¿La modificación del comportamiento indefinido de literales de cadena de acuerdo con el estándar C89?
- 28. indefinido C struct declaración adelantada
- 29. Código bacteria: comportamiento matemático en evolución
- 30. C# - orden de procesamiento de código - comportamiento extraño
+1 buena pregunta! –