2009-12-07 20 views

Respuesta

33

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.

+0

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 ... –

+1

¿Quién dijo algo acerca de la división por cero? –

+4

@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'. –

13

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#

+6

Cuando dice "Wiki", ¿a qué Wiki se está refiriendo? –

+0

SÍ, usar código inseguro puede producir un comportamiento indefinido. +1 –

+1

@Jeff Yates: el vínculo "comportamiento indefinido" en la pregunta va a Wikipedia. – Powerlord

-1

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.

+3

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

+2

@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 ... –

0

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#.

+2

El código inseguro * es * C#. Lo que está descartando son las garantías del código administrado. –

+0

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#. –

+5

Claro, eso es perfectamente legal C#. Una implementación de C# que implementa el subconjunto opcional "inseguro" sigue siendo una implementación de C#. –

11

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.

+0

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

23

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?)

enter image description here

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

+2

Esto realmente me hizo reír a carcajadas. –

1

Muchas y subprogramas tienen requisitos que se pueden resumir en:

  1. Cuando se le den datos válidos, produzca resultados válidos.

  2. 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".

Cuestiones relacionadas