Ошибки PascalABC.NET

Ещё подобная ошибка:

Procedure A(n:integer);
Begin
if n < 0 then Exit;
A(n-1)
End;
Begin
End.

“Program8.pas(4) : Обнаружена бесконечная рекурсия”

Тут правильное сообщение, видимо, “ВОЗМОЖНА бесконечная рекурсия”

Да это баг просто. Предупреждение о бесконечной рекурсии выдается, если нет веток

это довольно часто встречающаяся ситуация, очень похоже на эту:

function a:array of byte;
begin
SetLength(a,0);
end;

возвращаемое значение a не определено это сообщение можно легко убрать написав a := a или a := nil, но вот с рекурсивной функцией это так просто не уберёшь, а когда появляется предупреждение в списке ошибок это очень мешает, отвлекается от программирования, а если привыкнуть к тому что оно появляется - не будет замечать ошибок… лично мне нравится когда панелька с ошибками и вводом/выводом авто сворачивается и в таком случае она ещё и будет разворачиваться каждый раз когда появляется предупреждение…

это страница с ошибками и поэтому предлагаю тут же: если результат функции используется в её теле подпрограммой то не показывать предупреждение о возвращаемом значении, и если в подпрограмме есть exit или стоит вызов себя же под if то не показывать предупреждение о бесконечной рекурсивности

этот код вообще не компилируется и не должен. А предупреждение SetLength(Result,0); уже не выдается. Не знаю, выложено ли исправление в релиз или нет. В любом случае в следующей версии предупреждения.

это как? компилятор не даст скомпилировать :slight_smile:

всм тот кто программирует не будет замечать, если привыкнет не замечать предупреждение

а почему название функции не может быть передано как var параметр если Result может, а если присваивать то оба работают одинаково?

Имя функции может использоваться только в левой части оператора присваивания. И вообще это атавизм турбо паскаля. И надо всегда использовать Result.

я не против результа и всегда им пользовался, но вспомнилась учительница информатики из 8 класса, когда я только узнал на практике что такое программирование и она лично предпочитала использовать название функции, а паскальABC.Net вроде бы пытается не отбегать от старых паскалей в стиле чтоб не путать учителей… ну про турбо паскаль я согласен, я изи перевожу код с C++ но мучаюсь если приходится переводить с турбо паскаля :slight_smile:

это печально, конечно.

Лямбды не хотят уживаться с переходами по меткам. С одной стороны это хорошо, как бы подталкивает держаться в рамках структурного программирования, но с другой…

"Употребление слов из четырех букв типа goto может иногда быть уместным даже в самом лучшем обществе." Donald E.Knuth, “Structured Programming with go to statements”

Вот так программа работает.

label 10;
function f(i:integer):=i+i;
begin
  //var f:integer->integer:=i->i+i;
  var s:=0;
  for var i:=1 to 10 do begin
    if i>6 then goto 10;
    s:=s+f(i);
    end;
10:
  Print(s)
end.

А вот так уже нет. При этом выдается диагностика, по-видимому, предназначенная не рядовому пользователю. Т.е. понятно, что это связано с реализацией лямбд, т.е. сообщение идет не по исходному тексту программы, а по преобразованному, но все же первые несколько минут я усиленно искал упомянутый “составной оператор”, благо программа была весьма внушительных размеров (портировал монстрика из Фортрана, где “мильён” меток - нормальная практика)

label 10;
//function f(i:integer):=i+i;
begin
  var f:integer->integer:=i->i+i;
  var s:=0;
  for var i:=1 to 10 do begin
    if i>6 then goto 10;
    s:=s+f(i);
    end;
10:
  Print(s)
end.

Сообщение компилятора:

Program1.pas(7) : Переход внутрь составного оператора на метку 10 невозможен

Спасибо. Понятно.

Моя голубая мечта - чтобы Вы писали сюда: https://github.com/pascalabcnet/pascalabcnet/issues/434

да, запретить совместное использование современных лямбд и запрещенного goto, выдавая соответственное сообщение об ошибке.

А сюда не писать? Я туда пишу тоже временами, когда мне кажется, что это ошибка. А тут я сомневался, может это “фича, а не бага”. И потом, туда ведь не станешь цитировать Кнута, а без этого как-то постно )))

Запретить проще всего… эх, не любите вы пользователей! )))

Вуз - отличное место работы. А если бы там еще и студентов не было… (подслушано в коридоре вуза)

1 лайк

begin Println('1'*0); end. Program2213.pas(2) : Ошибка времени выполнения: Значение MaxCapacity должно быть больше или равно единице. Имя параметра: maxCapacity

begin Println('10'*0); end. А так нет ошибки.

Исправили

Справка → Классы → Переменная Self, опечатка в последнем предложении: Фактически в любом нестатическом методе перед именем любого поля и методу этого класса неявно присутствует Self.

К сожалению, в справке еще полно неточностней и опечаток. Вот, еще, к примеру:

  1. На странице “Условная операция”, в строке var min := a < b & a : b; стоит знак & вместо ?

  2. На странице “Подпрограммы для работы с динамическими массивами” – неточное описание параметров процедуры:

Должно быть: “Изменяет порядок элементов на противоположный в диапазоне динамического массива длины count, начиная с индекса index” (там еще и запятой не было);

  1. + Там же рядом:

Должно быть: “Изменяет порядок элементов на противоположный в диапазоне списка длины count, начиная с индекса index”

  1. Раздел “Справочник по языку / Структура программы / Идентификаторы и ключевые слова” – устаревшая информация насчет обязательной латиницы:
  1. Раздел справки “Справочник по языку / Типы данных / Процедурный тип” – ошибки в определении:

Должно быть:

  1. В справке нет информации о новой “безопасной” форме срезов: a?[from:to] и a?[from:to:step]

  2. С справке в дереве Содержание (Contents) нет ни одного раздела или страницы, с которой была бы прямая ссылка на страницу описания директив компилятора – её можно найти только через индексированный поиск.

  3. В свою очередь, уже на самой этой странице нет даже краткого упоминания (или ссылки) о существовании директив OpenMP, хотя есть целый раздел про это в главном дереве.

@Admin Похоже, вы не до конца с этим багом разобрались, по-прежнему чертовщина какая-то творится при попытке выполнения:

begin // Компилируется всё всегда ОК
  var x := 123;
  var y := object(x);
  writeln(x, y);            // Здесь всё без проблем печатается -> 123123
  //writeln(x, object(x));  // Тут уже -> Ошибка времени выполнения: Ссылка на объект не указывает на экземпляр объекта.
  writeln(x, y, object(x)); // А здесь вообще сразу вылет -> Exception processing message 0xC0000005 ...
end.

@Admin Вот еще кое-какие странности обнаружил с проверками на недостижимость кода (см. комментарии):

label _1, _2;
begin
  loop 2 do
  begin
    writeln('In cycle A');
    break;
    writeln('unreachable code'); // OK, недостижимый код обнаружен
  end;
  loop 2 do
  begin
    writeln('In cycle B');
    continue;;
    writeln('unreachable code'); // ??? недостижимый код уже НЕ обнаруживается из-за пустого оператора выше (;)
  end;
  loop 2 do
  begin
    writeln('In cycle C');
    goto _1;
    var x := 'unreachable definition'; // !!! эта строка уже достижима для определения переменной и вывода её типа?
    goto _2;
    _1:
    writeln(x); // ??? это нормально, что i=nil, а не "Неизвестная переменная x"?
  end;
  _2: 
end.

Что-то все метками увлеклись - это прямо сумасшествие какое-то

Первые два предупреждения - да - принимаем.

i=nil - это правильно - а как Вы хотели? Переменная i имеет тип на этапе компиляции, а до первого присваивания в ней - nil. В данном случае - Вы занимаетесь безобразиями, а компилятор абсолютно прав