Ещё подобная ошибка:
Procedure A(n:integer);
Begin
if n < 0 then Exit;
A(n-1)
End;
Begin
End.
“Program8.pas(4) : Обнаружена бесконечная рекурсия”
Ещё подобная ошибка:
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); уже не выдается. Не знаю, выложено ли исправление в релиз или нет. В любом случае в следующей версии предупреждения.
это как? компилятор не даст скомпилировать
всм тот кто программирует не будет замечать, если привыкнет не замечать предупреждение
а почему название функции не может быть передано как var параметр если Result может, а если присваивать то оба работают одинаково?
Имя функции может использоваться только в левой части оператора присваивания. И вообще это атавизм турбо паскаля. И надо всегда использовать Result.
я не против результа и всегда им пользовался, но вспомнилась учительница информатики из 8 класса, когда я только узнал на практике что такое программирование и она лично предпочитала использовать название функции, а паскальABC.Net вроде бы пытается не отбегать от старых паскалей в стиле чтоб не путать учителей… ну про турбо паскаль я согласен, я изи перевожу код с C++ но мучаюсь если приходится переводить с турбо паскаля
это печально, конечно.
Лямбды не хотят уживаться с переходами по меткам. С одной стороны это хорошо, как бы подталкивает держаться в рамках структурного программирования, но с другой…
"Употребление слов из четырех букв типа 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, выдавая соответственное сообщение об ошибке.
А сюда не писать? Я туда пишу тоже временами, когда мне кажется, что это ошибка. А тут я сомневался, может это “фича, а не бага”. И потом, туда ведь не станешь цитировать Кнута, а без этого как-то постно )))
Запретить проще всего… эх, не любите вы пользователей! )))
Вуз - отличное место работы. А если бы там еще и студентов не было… (подслушано в коридоре вуза)
begin
Println('1'*0);
end.
Program2213.pas(2) : Ошибка времени выполнения: Значение MaxCapacity должно быть больше или равно единице. Имя параметра: maxCapacity
begin
Println('10'*0);
end.
А так нет ошибки.
Исправили
Справка → Классы → Переменная Self, опечатка в последнем предложении: Фактически в любом нестатическом методе перед именем любого поля и методу этого класса неявно присутствует Self.
К сожалению, в справке еще полно неточностней и опечаток. Вот, еще, к примеру:
На странице “Условная операция”, в строке var min := a < b & a : b;
стоит знак &
вместо ?
На странице “Подпрограммы для работы с динамическими массивами” – неточное описание параметров процедуры:
Должно быть: “Изменяет порядок элементов на противоположный в диапазоне динамического массива длины count, начиная с индекса index” (там еще и запятой не было);
+
Там же рядом:Должно быть: “Изменяет порядок элементов на противоположный в диапазоне списка длины count, начиная с индекса index”
Должно быть:
В справке нет информации о новой “безопасной” форме срезов:
a?[from:to]
и
a?[from:to:step]
С справке в дереве Содержание (Contents) нет ни одного раздела или страницы, с которой была бы прямая ссылка на страницу описания директив компилятора – её можно найти только через индексированный поиск.
В свою очередь, уже на самой этой странице нет даже краткого упоминания (или ссылки) о существовании директив 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. В данном случае - Вы занимаетесь безобразиями, а компилятор абсолютно прав