Pull to refresh

Comments 10

Мораль: если вы используете с#, не используете unsafe.
Мораль должна быть другой. Увы, иногда требования по производительности не дадут отказаться от unsafe. Просто в эти моменты нужно быть предельно внимательным.
Если бы этот оператор был не нужен — его бы не добавляли.
Вы можете работать со сторонним кодом, в т.ч. неуправляемым (unmanaged), а, значит, и unsafe.
Но об этом после.
Полезной информации больше по сравнению с первой частью статьи, но ответа на главный вопрос всё ещё нет: как сделать так, чтобы ноги-то целыми остались? Заголовок статьи вселят надежду узнать не только «Кто виноват?», но и «Что делать?». Общая идея понятна: инвариант стандартных типов может быть испорчен. Не хватает:
  • Реального примера приложения, в котором по недосмотру может возникнуть такая проблема (в то время, как хорошие программисты на С/С++ (мне хочется верить) пользуются статическими анализаторами и ошибок вида if (i = 1) не возникает).
  • Как такую ситуацию опознать, найти проблему и решить её.
Спасибо за советы, помогающие направить мысль. Все будет.
Насчет общей идеи:
«инвариант стандартных типов может быть испорчен.»

Одно дело, если мы испортим намеренно или ненамеренно (например, при взаимодействии с неуправляемым кодом) внутреннее представление стандартных, но относительно сложных типов данных, например, строки. Тут сами виноваты.

Но булев тип? Если исторически его придумали для устранения коллизий фактически:
«Hence, if X is an integer variable, the statement: if X then ...; generates a compilation error.»,
зачем же порождать новые коллизии?
В C# это можно сделать с помощью небезопасного кода, в Delphi вообще возможно приведения целочисленного типа к булеву стандартным образом.
Про Delphi полный бред, простите.

Код
program Project1;
{$mode delphi}
{$apptype console}
var
  bool: Boolean;
  ref: PByte;
begin
  bool := False;
  ref := @bool;
  ref^ := 5;
  if (bool) then
    WriteLn('True');
  if (bool = True) then
    WriteLn('Still true');

  WriteLn('Bool actual value is: ', bool);
  WriteLn('Ref value is: ', ref^);
  WriteLn('Bool value by ref is: ', PByte(@bool)^);
  ReadLn();
end.


Результат
True
Still true
Bool actual value is: TRUE
Ref value is: 5
Bool value by ref is: 5

В целом, пост смахивает на какие-то свои мысли и несет больше вреда, чем пользы.
Даааа, Delphi она такая, всегда всё проверяет, за нами подтирает. За то и любим )
Поведение конкретной реализации компилятора ни о чем не говорит, и рассчитывать на такое проведение не следует.

Важно, какое поведение документировано. Про это написано в статье. Если комментируете, будьте добры вначале прочитать внимательно.

Эту часть статьи я немного уточнил после вашего комментария (за что спасибо, несмотря на не самую вежливую его форму), но и до этого было четко написано про разницу документированного и неопределенного поведения.

Кстати, попробуйте модернизировать ваш код:
пусть значение переменной «bool» с внутренним кодом 5 сравнивается не с True, а с другой переменной, в которую помещено валидное значение True.
Sign up to leave a comment.

Articles

Change theme settings