Вопрос

В C ++ есть много способов, которыми вы можете написать код, который компилируется, но доходность неопределенное поведение (Википедия). Анкет Есть ли что -то подобное в C#? Можем ли мы написать код в C#, который компилируется, но имеет неопределенное поведение?

Это было полезно?

Решение

Как упоминали другие, практически все в «небезопасном» блоке может дать определяемое реализацией поведение; Злоупотребление небезопасными блоками позволяет вам изменить байты кода, которые составляют саму среду выполнения, и, следовательно, все ставки выключены.

Угловой случай целочисленного подразделения имеет поведение, определяемое реализацией.

Выбросить исключение и никогда не поймать его, вызывает определяющее реализацию поведение-заканчивает процесс, запустите отладчик и так далее.

В C# существует ряд других ситуаций, где мы вынуждены излучать код, который имеет определение реализации поведения. Например, эта ситуация:

http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambigage-overloads-part-two.aspx

Тем не менее, ситуации, в которых безопасная, благополучная программа C# имеет определяемое внедрением поведение, должны быть довольно редкими.

Другие советы

Да! Есть даже в безопасном контексте! (Ну, это реализация, определяемая, по крайней мере, неопределенная)

Вот один из Марека Сафара и Всадова в Рослин Проблемы. Существует несоответствие между C# и CLI в отношении bool.

C# считает, что есть только один вид true, и один вид false.

CLI верит в это false байт, содержащий 0, а все остальные значения true.

Это несоответствие означает, что мы можем принудить C# сделать немного (незначительно) интересный вещи вещь:

//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]);

Вышеуказанные выходы:

true

true

false

Интересно, что отладчик не согласен (должен по -разному оценивать истину?)

enter image description here

В любом случае, вывод, к которому, по -видимому, пришла команда C# (выделение добавлено):

Т.е. язык останется полностью не заботящимся о нестандартных булах. Конкретная реализация (как в MS C# на CIL) будет признавать существование нестандартных Bools и укажет их поведение как неопределенный

Глядя на вики, ситуации, в которых происходит неопределенное поведение, либо не допускаются, либо бросают исключение в C#.

Однако в небезопасном коде, я считаю, что неопределенное поведение возможно, так как это позволяет использовать указатели и т. Д.

РЕДАКТИРОВАТЬ: Похоже, я прав: http://msdn.microsoft.com/en-us/library/aa664771%28vs.71%29.aspx

Имеет пример неопределенного поведения в C#

Согласно документу ECMA-334 (стр. 473):

Программа, которая не содержит никаких случаев небезопасного модификатора, не может проявлять какого -либо неопределенного поведения.

Это способствует «определяемой реализации» в худшем случае, см. Ответ Эрика Липперта.

Многие и подпрограммы имеют требования, которые можно обобщить как:

  1. Когда даны допустимые данные, создайте действительный вывод.

  2. Воздержитесь от запуска ядерных ракет или отрицания законов времени и причинности, даже если получить недопустимый вклад.

Одной из основных целей дизайна Java и .net является то, что, если код не использует определенные, которые отмечены как «небезопасные», никаких особых усилий обычно не требуется для удовлетворения второго ограничения выше [хотя некоторые поведения, связанные с сбором мусора, и Finalize Может быть немного странным с точки зрения времени/причинности, их можно описать как исключения из нормальных правил причинности, а не как полное отзыв их]. Эта ситуация сильно отличается от ситуации в C, где многие виды ошибок, зависящих от данных (например, переполнение целого числа) могут привести к тому, что компиляторы ведут себя произвольным образом, включая все возможное, чтобы избежать переполнения. По -настоящему ужасные виды неопределенного поведения, которые поощряются в философии гипермодерна C, не существуют в C# или на других языках .NET за пределами «небезопасных» блоков.

Не совсем в точности вики, но я полагаю, что самый очевидный пример, который приходит мне на голову, - это просто писать какой -то резкий код, но тогда это так на любом языке.

В общем, я бы сказал нет.

Используйте автоматическую переменную, прежде чем она будет инициализирована.

Все переменные должны быть инициализированы. Если нет исключения.

Деление на ноль

Исключение брошено.

Индексировать массив из границ

Исключение брошено

Как отметил Aequitarum Custos, вы можете использовать небезопасную код. Опять же, это не совсем C#, вы явно отказываетесь от среды C#.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top