Ошибки IDE PascalABC.Net

Не знаю, как правильно написать, в цикле по словарю при автовыводе переменной типа KeyValuePair не хочет показывать свойств Key и Value, а если указать этот тип, то показывает. И вообще, разные подсказки.

С автовыводом типа

%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA2

С указанием типа

%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA

Вроде была тема по ошибкам Intellisense, или не было?

Наведите мышку на x в первом случае - видно проблему. Анализатор кода считает что у него тип integer. Это #894, 1 из древних ошибок которые почему то никак не хотят исправлять.

Анализатор кода это часть IDE, поэтому вы правильно сюда кинули. Тема была, но администраниция решила что лучше их не плодить.

В Помощь>>О программе всюду показывает 2005-2018, хотя 2019 год уже давно.

image

На модулях копирайт вообще можно поставить хоть прошлым веком, это ни на что не влияет даже чисто юридически…

Program2.pas(15) : Нельзя преобразовать тип array of procedure() к array of procedure()

type
  TAProc = array of procedure;

procedure test(prc:TAProc);
begin
  prc[0];
end;

procedure test2();
begin
  writeln('TEST');
end;

BEGIN
  test(arr(test2))
END.

Это баг или действительно нельзя передавать массив процедур в качестве параметра?

Решение:

type
  TProcedure = procedure; // Или вместо определения своего типа используем Action0, что также есть System.Action.
  T = array of TProcedure;

procedure WithArray(a: T);
begin
end;

procedure P();
begin
end;

begin
  WithArray(Arr&<TProcedure>(P)); // Обязательно указываем в угловых скобках тип элементов массива.
end.

Такого ограничения нет в языке. Я думаю, что это баг (моё скромное мнение).

По подобным вопросам я Вам бы советовал обращаться к постоянным пользователям языка (например, @Sun_Serega, @RAlex). Ибо у меня иная специализация (в статусе посмотрите).

Кстати, почему Вы написали в данную тему? Это же баг (если баг) не самой IDE, а компилятора.

1 лайк

Большое спасибо за помощь!

Кстати, почему Вы написали в данную тему? Это же баг (если баг) не самой IDE, а компилятора.

Действительно. Не подумал как следует. В следующий раз, надеюсь, буду писать где нужно, ибо хаос на этом форуме ни к чему :slight_smile:

Это не баг, при у каждой процедуры свой тип:

begin
  var p1: procedure := ()->writeln(1);
  var p2: procedure := ()->writeln(2);
  writeln(p1.GetType=p2.GetType); // False
end.

Но, при объявлении:

TProcedure = procedure;

Вы создаёте единый тип делегата, в данном случае без параметра и возвращаемого значения. Теперь если написать:

type
  TProc = procedure;

procedure test(prc: array of TProc);
begin
  prc[0];
end;

procedure test2();
begin
  writeln('TEST');
end;

begin
  test(Arr(TProc(test2)));
end.

И в параметре test, и в выражении Arr(...) - используется одинаковый тип делегата.

Так же, как заметил @MrFresnel - можно:

  1. Использовать стандартные типы аля Action0, Action, Action2, Action3. (а для функций - Func0, Func, …)
    Они и есть точно такие же типы делегатов, как TProc в коде выше. Только их не надо руками объявлять, раз они есть. Если вам не хватает 3 параметров - можно ещё писать
    System.Action<*список типов через запятую*>
    и
    System.Func<*список типов через запятую*>
    они, вроде, до 16 параметров включительно поддерживают.

  2. Вместо приведения каждого параметра (TProc(*имя процедуры*)) - можно явно указать тип элементов массива, который создаётся, с помощью &<>.
    Или, ещё лучше, использовать создание массива с помощью new, оно, обычно, раза в 2 быстрее чем arr, но не может авто определять тип элементов. А раз нам как раз нужно без авто определения - так лучше:

procedure test(prc: array of Action0);
begin
  prc[0];
end;

procedure test2();
begin
  writeln('TEST');
end;

begin
  test(new Action0[](test2));
end.
2 лайка
    Сначала решил посмотреть код стандартного модуля и заметил интересную особенность:
    В функции  Abs(x) не было замечено принятия параметра в типе данных byte (0..255), размер 1 байт.
    Ниже код:
    ///-function Abs(x: число): число;
    /// Возвращает модуль числа x
    function Abs(x: integer): integer;
    ///--
    function Abs(x: shortint): shortint;
    ///--
    function Abs(x: smallint): smallint;
    ///--
    function Abs(x: BigInteger): BigInteger;
    ///--
    function Abs(x: longword): longword;
    ///--
    function Abs(x: int64): int64;
    ///--
    function Abs(x: uint64): uint64;
    ///--
    function Abs(x: real): real;
    ///--
    function Abs(x: single): single;

    ------------------------------------------------
    Далее решено было создать тестовую программу на использование этой функции:
    begin
    var a:byte;
    a:=255;
    a:=abs(a);
    write(a);//FIXME: выводит неправильное значение модуля 255, в подпрограмме нет функции для byte.
    end.
На вывод (при успешной компиляции) программа дает:
1

Если переменной a присвоить значение 254 то выводит: 2;  253: 3 и т. д.

При шаге со входом в подпрограмму вычисление происходит в функции

function Abs(x: shortint): shortint;
begin
  Result := Math.Abs(x);
end;

Но shortint (-128..127)
При a:byte:= 128 выводит ошибку: "Ошибка времени выполнения: Инвертировать минимальное значение двоичного дополнения невозможно."

Вопрос: В чём причина данной ошибки? Проблема в стандартном модуле или моём тестировании? 
Что нужно сделать, чтобы модуль числа возвращался правильно, не меняя при этом типа данных (byte) ?

P.S. Нет в функции и word(0…65535).

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

Да кстати, это наоборот, это:

и это:

лишнее…

byte, word, longword и uint64 - это форматы для беззнакового представления чисел. Строго, для них бессмысленно говорить о понятии модуля.

Пишите Issue. Это ошибочное поведение

Какое? То что нет для uint8 и uint16 или то что есть для uint32 и uint64?

Ну понятно же, что вот это.

1 лайк

Исправили

2 лайка

Я заметил интересную особенность, написав код:

begin
var a:word:=1;
inc(a);
end.

на что, при наведении на функцию inc(), был выведен комментарий: image

хотя у нас a имеет тип данных word, а в описании у нас символьный тип данных. Такое же сообщение есть и для longword, uint64, shortint, smallint, int64.
Для integer описание верное:
image
и для char:
image

Для byte в описании применен перечислимый тип данных:
image

Для biginteger нет перегруженной подпрограммы и описание неверное:

Далее я создал модуль biginc

unit biginc;
interface
uses PABCSystem;

function Inc(a:biginteger):biginteger;

implementation
function Inc(a:biginteger):biginteger;
  begin
  result:=a+1;
  end;
end.

после чего запустил код

uses biginc;
begin
var a:biginteger:=10;
write(Inc(a));
end.

Программа вывела верное значение 11 (в данном случае). Также работает и на других значениях.

Просьба:

1.Обеспечить правильный вывод описания над вышеописанными типами данных
2.Осуществить работу инкремента над BigInteger.
Благодарю за чтение сообщения до конца!
Информация для разработчиков:

PascalABCCompiler.Core v3.5.0.2167 (01.07.2019), debug version
Runtime version: 4.0.30319.42000
OS version: Microsoft Windows NT 6.1.7601 Service Pack 1
Processor count: 4
WorkingSet: 200452 kb

Для чего? Кому это нужно? Inc и Dec это просто процедуры из древнепаскальского диалекта, оставленные для совместимости. Используйте += и -=.

Кстати, это весьма интересная проблема. Ведь Ord(x: перечислимы тип) в PABCSystem нет. Это функция с внутренней реализацией. Собственно, бесполезная, ведь между перечислимым типом и целым число можно использовать просто явное приведение.

Это сразу сюда:

Описание и не должно быть верное в не верном коде.

Звучит как жуткая ошибка. Однако на вашем скриншоте вывод правильный, в отличии от того что вы говорите.