Опять баги?!


#1

И сегодня я, как обычно, кодю свой ЯП с 12 утра до 12 ночи.

БАГ 1 - При установке паскаля, в файл “\PascalABC.NET\pabcworknet.ini” записывается путь “C:\PABCWork.NET”, а если установить паскаль при винде расположенной НЕ на диске “C:”, то установщик всё равно запишет в файл “\PascalABC.NET\pabcworknet.ini” путь “C:\PABCWork.NET”, хотя такой папки нет, хотя была создана папка “диск_с_виндой:\PABCWork.NET” [тестировал на Windows XP SP3, расположена в “D:\Windows” , установщик паскаля специальный под XP].

БАГ 2 - Если в “PABCWork.NET\PascalABCNET.ini” прописать ConvertTabsToSpaces равным False, то эта функция всё равно будет работать и будет автоматически заменена на True, хотя код с табами (написал в блокноте) прекрасно компилируется и работает. В чём проблема, нельзя ли сделать режим с табами?

БАГ 3 - Некоторый код (не могу привести пример) при Ctrl+F9 выдаёт одну ошибку, а при F9 - совершенно другую, хотя настроек отображения ошибок не изменял.

БАГ 4 - Если компилировать очень часто, то вылетает компилятор и IDE перезапускает его заново:

БАГ 5 - После форматирования кода к словам internal, private, public, protected добавляется один ненужный пробел, после else (который относится к case) добавляется столько новых ненужных строк, сколько ты форматнёшь код, после end (которое относиться к case) добавляется один ненужный пробел

БАГ 6 - Создаём любой рабочий код -> компилируем -> компилируем ещё раз и получаем: %D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9

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

БАГ 7 - этот код работает прекрасно:

, а вот этот код (который делает тоже самое) компилируется, но:

Это баг или вы просто забыли запретить объявление extern-подметодов?

БАГ 8 - Директива есть а программа для него где?:

Чтобы сделать совершенно простое действие (вшить иконку в приложение) мне пришлось писать крики о помощи на сайберфоруме, где мне кинули ссылку на Resource Compiler.

Я считаю, что с такими недочётами паскаль далёко не уйдёт, исправьте пожалуйста!


#2

Ах да, а как же:

БАГ 9 - компилировать namespace через IDE не имея проекта нельзя, но напрямую через компилятор - можно


#3

И вот ещё этот зловещий код:

{$apptype windows}

program test;

{$reference System.dll}
{$reference System.Windows.Forms.dll}

uses
    System,
    System.Windows.Forms;

/// Убрать форму из Alt+Tab
procedure HideFromAltTab(f: Form);
    
    function SetWindowLong(window: IntPtr; index, &value: integer): integer; external 'user32.dll';
    
    function GetWindowLong(window: IntPtr; index: integer): integer; external 'user32.dll';

begin
    SetWindowLong(f.Handle, -20, GetWindowLong(f.Handle, -20) or 128);
end;

var
    f := new Form;

begin
    HideFromAltTab(f);
    Application.Run(f);
end.

#4

А ещё вопросик - почему при запуске этого кода всё время пишется число “16”? Куда уходят драгоценные overhead-миллисекунды?

begin write(MilliSeconds) end.


#5

Баг 2: Эта функция IDE не работает, потому что её сложно реализовать качественно. А делать это некому. Уже было об этом разговор, вроде, больше года назад.

Баг 3:

Так дело не пойдёт. Как по вашему кто то должен догадываться? Если пишите об ошибке - надо предоставить всё для её воспроизведения. Иначе ваши слова - шум.

Баг 4:

Приложите ка текст ошибки компилятора. И - это какая то плавающая ошибка, я так понимаю? То есть она вылетает тогда - когда хочет? У меня что то похожее бывает по 1 разу после спящего режима, но не после слишком быстрых компиляций. В общем ловить такое вообще отдельное искусство, можно даже отдельную тему создать. Но исправлять такую ошибку - далеко не первоочерёдная задача, если я правильно понял что она возникает только при насиловании кнопки компиляции.

Баг 5:

Опять же, код. Слов “я был там, не знаю где, словил то, не знаю что” - мало.

Баг 6:

Давайте более подробно, я 1 и тот же файл 2 раза подряд - ни раз компилировал. Значит вы что то недоговариваете. Хотя ошибку что вы говорите - иногда таки встречал.

Баг 7:

Я же вам уже давал ссылку, будьте внимательнее:

Раз у вас всё ещё нет ошибки с адекватным текстом, зато есть вылет - значит у вас устаревшая версия компилятора. Всегда обновляйтесь перед тем как сообщить ошибку:
http://pascalabc.net/ssyilki-dlya-skachivaniya
Но, конечно, это медленно и нудно. Я сам часто баги ищу, поэтому для себя сделал это:

Этот установщик обновляет паскаль за ~10 сек. Но работает только с параметрами по-умолчанию (то есть пути установки будут только на C).

Баг 8:

Я вам ответил на киберфоруме, вшивать компилятор ресурсов в установщик паскаля - нельзя из за каких то там лицензий. По крайней мере я так понял проблему.

Баг 9:

“напрямую” это как? Из контекстного меню (ПКМ) в папке, кнопкой “компилировать”? IDE использует pabcnetc.exe, а компиляция из папки - это pabcnetcclear.exe. Но то что эти 2 компилятора работают НЕ одинаково - вот это уже баг.

Ибо нефиг так мерить время. Используйте System.Diagnostics.Stopwatch, он не только начинает отсчёт там - где вам надо, а ещё умеет использовать вшитые в железо устройства для замера времени. Они дают более точные результаты и не тратят время CPU так же как DateTime.Now, используемый в Milliseconds.

Куда - на JIT-компилятор, наверное.
.exe и .dll файлы созданные .Net языком - хранят исходный код на языке CIL, а не машинный код, поэтому при запуске их ещё раз компилирует. Но каждый класс компилирует не прямо при запуске, а тогда - когда его первый раз упомянут.
Поэтому моя теория такова: сначала компилируется класс, в котором инициализируется переменная, используемая в MilliSeconds и MilliSecondsDelta, а затем всё что связано с write (там полно всего, код write очень сложный).




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

  1. Исправление багов - не магический процесс. Разработчики проводят точно такую же отладку как вы в своих программах. Только в больших масштабах. Поэтому чтоб подтвердить ошибку и найти строчки кода компилятора/IDE, приводящие к этой ошибке - им нужны точные условия, при которых ошибка однозначно воспроизведётся.

    К примеру, в баге 9 надо указать список действий в виде точного списка, а ещё желательно приложить код (даже если он в 3 строчки).

  2. Обновления выходят, обычно, по 2 раза в неделю (прямо сейчас чуть реже). В каждом обновлении исправляют по несколько багов. Поэтому надо всегда проверять обновления перед тем как говорить о новом баге.

  3. Вылет компилятора, внутренние ошибки (что тоже вылет, кстати), ошибки в точке Undefined Filename - уже сами по себе баги. Даже если код вызывающий их, не должен компилироваться - об этом тоже надо сообщать. Тексты ошибок должны быть адекватные.

  4. На форуме уже есть несколько тем, куда можно сувать части содержимого этой темы (но переносить уже не надо, это на будущее):

Если вы чего то не понимаете:

Замечания и предложения:

Баги:

Как отличить баг компилятора от бага IDE? Баг компилятора это то, что происходит после нажатия на кнопку компиляции. Включая компиляцию и из IDE, и из папки. И не важно, необходима IDE для воспроизведения или нет.

Так же, для багов есть багтрагеры (тоже разделение на компилятор и IDE):

Однако там ожидаются настоящие баг репорты, более высокого качества. Давайте, пока что, пишите в соответствующие темы форума. Я (и, возможно, ещё кто то, вроде разработчиков) буду(т) говорить вам что подправить и что уточнить, перед отправкой в issue.


#6

Они работают одинаково


#7

Баг 5 - при любом коде, главное чтобы в нём были эти слова и будет вам этот баг


#8

Нет не любой:

type
  t1 = class
    internal i: integer;
  end;

begin
  if true then
    case 0 of
      0: ;
    end else
  begin
    
  end;
end.

Тут тоже есть проблемы, но эти проблемы не там - где вы говорите. Именно поэтому и надо прилагать конкретный код. Вы думаете что любой, потому что не дотестили. А если бы вы давали конкретный код - вы бы не смогли оставить его недотесченым.


#9

Спасибо за ответы, но есть ещё вопросы!

=============================================================

Версия паскаля у меня всегда последняя, каждый день проверяю обновления с помощью соответствующей кнопкой.

=============================================================

А что вы скажете про БАГ 1, ведь его тоже надо исправлять (даже если он для Windows XP) ? Или вы думаете что на планете не осталось людей у которых стоит “XP” не на диске “C:” ?

=============================================================

Sun Serega, вы разработчик паскаля или просто крутой чел (дело в том, что я хочу видеть ответы не только от вас, но и от разрабов)?

=============================================================

Насчёт вашего ответа про пятый баг - вы меня не поняли, я имел ввиду вот такой код:

type
    test = class
    
    internal
        i1: integer;
    private
        i2: integer;
    protected
        i3: integer;
    public
        i4: integer;
    end;

begin
    case 0 of
        0: ;
    else
    end;
end.

Если его форматнуть, то: 1 - ко всем словам обозначающим уровень доступа добавиться 1 пробел, хотя он там не нужен 2 - после else добавляются NewLine’ы, также, как и действует бесконечно возрастающая арифметическая прогрессия (это не прикол, они реально в такой последовательности добавляются) 3 - после end (которое относиться к case) добавляется 1 пробел, который там совершенно не нужен

То есть в результате, например, пяти форматирований будет этот ужас:

type
    test = class
    
    internal 
        i1: integer;
    private 
        i2: integer;
    protected 
        i3: integer;
    public 
        i4: integer;
    end;

begin
    case 0 of
        0: ;
    else
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    end ;
end.

=============================================================

И ещё, меня просто задолбал :rage: этот круглосуточный (реально бесит и очень мешает разработке) БАГ 10 - На этот раз я не поленюсь и скину код, который в конце этого ответа.

Например: Скокипасте код в IDE -> Поставьте курсор в точку(703, 25) -> Отформатируйте код -> Курсор перепрыгнул в точку(339, 25) -> Вы бьётесь головой об стену, чтобы вспомнить в каком месте кода вы кодили.

Конечно же мой “case” на 366 строк - это ужасный говнокод, но всё-таки я имею право это делать.

Моё предложение, как частично решить эту проблему (допустим что это исходный код IDE переведённый на паскаль):

procedure FormatCode;
begin
    var TempCursorPosition := GetCursorPosition;
    ... // Здесь, собственно, само форматирование
    CursorPosition := TempCursorPosition;
end;

Такое решение проблемы полностью её не устраняет, но это всё-таки лучше, чем перепрыгивать с 4069568 строки на пару тысяч строк назад.

А вот и тот самый, небольшой демонстрационный код, с помощью которого была найдёна куча багов (юнит “SingleberryAddons” вам не нужен, вам же только баг с форматированием протестить):

Код не влезает, поэтому вот ссылка на него -

=============================================================

Кстати 4: Может добавите некоторые (а можно и все) процедуры в системные юниты?

=============================================================

Кстати 5: Мой метод “Swap” работает быстрее чем ваш “Swap” и потребляет меньше памяти.


#10

Кстати 6: “Resource Compiler” убран, а директива осталась - значит нужно добавить в справку паскаля пояснение “почему нету”, “почему убран”, “где достать”, “зачем эта директива нужна”.


#11

Ничего потому что я не тестировал. Не хочу для этого паскаль сносить. Сделайте видео с воспроизведением и залейте в issue IDE, будет достаточно. Ну и + можно выписать список действий для воспроизведения через 1. 2. 3. и т.д, так разработчики лучше поймут, а значит быстрее исправят.

Нет, но я активно участвую в развитии проекта. Разработчиков всего 2, @Admin и @ibond.

Конечно, потому что вы так объяснили. И я несколько раз сказал про это.

Да, ошибки вижу. Но надо разбить на 2 кода, потому что багов тут 2. И тогда можно заливать в issue IDE. В этот раз я за вас сделал:

Найдите минимальный код в котором воспроизводится. В чужом коде никто копаться не захочет.
То есть сделайте копию всего кода и в этой копии убирайте код пока не перестанет воспроизводится.

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

А с чего её убирать? Эта программа - не единственный способ получить .res файл.
Дополнить справку - да, стоило бы. Страница с директивами вообще довольно скупа.

  1. Какой памяти? Стек не считается. Если насиловать его излишней рекурсией - он в любом случае переполнится. А если нет - память на нём практически бесконечна, а значит и не важно сколько её тратить.

  2. С чего вы решили что ваш способ быстрее? Он наоборот медленнее, потому что в отличии от оригинального - тут на 3шт больше операций разъименования указателя (чтение/запись значения var-параметра) и есть дополнительные операторы xor. Всего остального - столько же.

Такой способ - был актуален в древности, когда был смысл экономить память на стеке. Но он никогда не был быстрее.

Всё что вы привели - имеет довольно локальное применение, а многое ещё и не эффективно реализовано.

К примеру Command - лучше передавать по несколько команд.

Switch - лучше q := not q. И методы такие есть, Inc и Dec выполняют одинаковую операцию в случае boolean. И кроме того, это выполнение простейшей операции через отдельный метод, что само по себе бред и говнокод. Даже если не говорить про то, что это процедурное программирование в языке с уклоном на функциональное.

А ещё вы явно ещё не слышали как работает форматная строка, раз пользуетесь методами вроде FormatTo0. А ещё не слышали что сложение строк - ужасно медленная операция, и что есть метод string.PadRightLeft тоже).


#12

Кстати, продвинутые люди форматируют код ручками. Потому что стиль стандартного форматирования никогда не может равняться личному. Я уже давно не страдал от переставления курсора и т.п., потому что использую автоформатирование только в коротеньких кодах которые заливаю в issue.

Ну а так - можете использовать Ctrl+G, он хоть как то поможет если вы всё же используете автоформатирование.


#13

К сожалению это я тестил в середине июля (2-ой месяц лета), а как увидел этот баг - сразу же обиделся на разработчиков и снёс винду и все остальные винды и поставил семёрку на диск "C:\ ".

Вы внимательнее посмотрите, я там код привёл.

Спасибо, а давайте свяжемся где-нибудь в соц сети?

Я сделал через яндекс, потому что превысил максимальное количество символов в сообщении - 32000

Нет, объясняю вам ещё раз - нужен именно этот код, потому что во-первых он большой, чтобы доказать что IDE плохо работает с большим кодом, а во-вторых если case будет маленький, то нервы гореть не будут

Я имел ввиду то, что Swap<T> происходит через стороннюю переменную или по-вашему эта переменная по выходу из метода испаряется и не занимает RAM?

Буду знать, спасибо

Согласен, но всё-таки char.ToLower я считаю нужно добавить. А вот насчёт Command - поясните по-подробнее, что вы имели ввиду?

Буду знать.

Это называется не “продвинутые”, а “смирившиеся с недостатком IDE”.

Кстати 7: нужно добавить фичу по нажатию на Ctrl+H (посмотрите в блокноте что за фича) - очень полезная возможность, а чтобы ей воспользоваться приходится открывать код с помощью блокнота и делать там Ctrl+H


#14

Я не понял эту вашу фразу. Вы видели что FormatTo0 - это моя самодельная функция, которая возвращает число-строку в более красивом виде, с нулями?


#15

У меня тоже семёрка и на диске C. А вашего объяснения, как и в случае с форматированием - не достаточно чтоб делать баг-репорт.

А обижаться можете разве что на себя, за то что не сообщили баг а вместо этого нашли кривой способ от него избавится.

Я говорю не текст кидать а именно файл. Текстом как раз плохо.

Нет. Если есть ошибка с переставлением курсора - будет и более маленький кусок кода, в котором курсор переставит. Дело не может быть в размере кода. У меня были файлы и на 40к строк, и так IDE хоть и лагала, но всё же работала.

Нет. Это локальная переменная, память под неё выделяется на стеке.

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

А его нету?

После запуска cmd - можно во входной поток передавать любое кол-во команд. По 1 - не эффективно.

Ctrl+R

Вот то же самое можно сделать дополнительными параметрами форматной строки, и будет это ещё и быстрее работать чем .PadRight. Не помню точно как, но я вам дал ссыль, там всё объясняется.


#16

Опять бяки


#17

Да, всеми любимые (особенно разработчики, у них аж слюни текут от багов)