Помощь новичкам

Когда вызывается Application.Run - весь вызвавший поток отдаёт на выполнение обработки событий. Может кто то объяснить, почему тут исключение не ловится:

{$reference System.Windows.Forms.dll}

begin
  var f := new System.Windows.Forms.Form;
  var main_thr := System.Threading.Thread.CurrentThread;
  
  f.Shown += (o, e)->
  begin
    writeln(System.Threading.Thread.CurrentThread=main_thr);//true, то есть это тот же поток
    Sleep(100);
    raise new Exception;
  end;
  try
    System.Windows.Forms.Application.Run(f);
  except
    writeln('got exception');//эта строчка не вызывается, в место этого оболочке передаётся исключение
  end;
end.

с Application.Run() всё не просто. Там может быть так, что графическая оболочка программы (именно с ней работает Application.Run()) является корневым, т.е. основным потоком программы. Если Вы пытаетесь обработать исключение, то предполагается наличие родительского потока, что невозможно по определению.

А можете дать ссылку на какую то статью где объясняется что такое этот ваш “корневой поток”. Я всегда думал что корневой это поток с Main.

И даже если это в каком то другом потоке - тогда бы
writeln(System.Threading.Thread.CurrentThread=main_thr);
выводило бы false, но это не так.

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

begin
  var c := System.Diagnostics.Process.GetCurrentProcess.Threads.Count;
  c.Print;
end.

У меня выводит 4.


Я ещё попробовал это:

procedure p1 := raise new Exception;

begin
  var m:System.Delegate := p1;
  try
    m.Method.Invoke(nil,new object[0]);
  except
    writeln('got exception');
  end;
end.

Но тут исключение ловит, так что дело не в Invoke.

Ссылку дать не могу, так как это моё мнение. Но вот то, что Application.Run работает крайне необычно я заметил уже давно. Этот метод запускает приложение с главной формой, переданной в качестве параметра. Мне кажется, если исключение происходит там(на форме), то его попросту невозможно обработать. Если исключение в дочерней форме, например в файловом диалоге, то да, но этим занимается главная форма. В графических программах всё гораздо сложнее, чем в консольных. :wink: Я с ними года 2 разбирался. А если представить, что в WPF…

begin
  var t1 := Arr(1, 2, 3);
  var t2 := Arr(1, 2, 3);
  if t1 = t2 then Println('t1=t2')
  else Println('t1<>t2');
  var u1 := (1, 2, 3);
  var u2 := (1, 2, 3);
  if u1 = u2 then Println('u1=u2')
  else Println('u1<>u2')
end.

Хотелось бы понять, что тут сравнивается - содержимое ссылок на созданные объекты? И тогда, поскольку кортежи одинаковы, обе ссылки адресуются к одному и тому же объекту? Или все намного мудрее?

Вроде там переопределяется operator= и operator<> для кортежей. Это декомпилятором смотреть надо.

Для кортежей - это надо, чтoбы не отставать от C#, где теперь можно написать

(int, int) t1 = (0, 1);
(int, int) t2 = (0, 1);

if (t1 == t2 )
{
     Console.WriteLine("t1=t2");
}

Для массивов - ссылки. Для кортежей - значения.

1 лайк

И это делает сравнение массивов на 99% восхитительно бессмысленным.

А как же на 100% бессмысленная проверка индексов массива в отлаженной программе?

Это лишь в простейшей. Да и то, В ОТЛАЖЕННОЙ. А мы помним известную фразу о том, что “Тестирование может доказать наличие ошибок в программе, но никогда не докажет их отсутствия”. Или это я помню, а Вы - нет? ))))

И многократно протестированной тоже.

Я то помню, только вот что даст исключение простому пользователю? Особенно если нет отладочной информации и проект с закрытым исходным кодом? Я понимаю, что Вы не верите, что эта проверка замедляет программу, но я уже приводил пример. И опять таки, 2,5 раза.

Как это - не верю? Любая проверка замедляет, это очевидно. Другой вопрос, что PascalABС.NET - он не для этого. Супероптимизацию при математических вычислениях и работе с массивами дает только Фортран и с этим нужно смириться, нравится Вам это, или нет. Ну вот просто он именно ради этого делался. Отрицать, что нечто специализированное хуже универсального - это не очень логично.

А я и не буду отрицать. Фортран - язык для объёмных научных вычислений. Вы правы. Только почему нельзя оптимизировать Паскаль? Это что, помешает ему?

Наверно, можно. Но вот нужно ли тратить на это время и силы, ответить могут только разработчики. Например, в части оптимизации указателей уже ответили: “нет”.

А можно ведь и с другой стороны зайти. Почему бы не сделать директиву компилятора, отключающую проверку на выход за границы массива? А её реализация будет использовать указатели, так как .NET иначе не умеет.

Т.е. дать возможность пользователю развалить свой код? Индекс вышел за границу, адресовались неизвестно куда, случайно попали с модификацией в какую-то ссылку… дальше что? " Ах-вах, шайтан какой, совсем этот Паскаль крышей поехал ! " ? Не знаю, мне это неинтересно, а “заднее слово” - оно, как обычно, за разработчиками.

Почему? Я же сказал, что эта возможность подключается ДИРЕКТИВОЙ, а по умолчанию отключена. Если пользователь уверен в том, что программа работает правильно, он может подписать сверху директиву и ускорить программу.

Это и называется “дать возможность…”.

Вы не замечаете, что все время пытаетесь предложить сделать Паскаль таким, каким он будет удобен лично Вам ? Несмотря на явно сдержанную в этом отношении позицию разработчиков.

Давайте сделаем опрос. Кто хотел бы такую директиву. Описать все за и против, как это сделал @Sun_Serega.