Баг компилятора в работе со строками

Предыдущая тема Следующая тема Перейти вниз

Баг компилятора в работе со строками

Сообщение  DiG. GeRR в Чт Авг 27, 2009 8:14 pm

Сегодня целый день протрахался с модулем - не работала одна из функций. И все же, уже в самом конце дня, баг был побежден... но какой баг! Вот что оказалось на самом деле:

Код:
if (String(4, !"\0") = String(3, !"\0")) then
    print "Strings are equal"
 else
    print "Strings are not equal!!!"
 endif

Баг засел в функции String. Тут нужно дать некоторые пояснения. Дело в том, что встроенный тип String во fBasic - на самом деле структура следующего вида:

Код:
type String
      as char ptr data  '' указатель собственно на строку, которая динамически выделяется в памяти, используя malloc
      as integer len    '' длина строки в символах
      as integer size    "' размер буфера, который был выделен функцией malloc (он может не совпадать с длиной
 строки - так сделано для повышения быстродействия)
 end type

Встроенная функция сравнения строк сначала проверяет длины (String.len), и, только если они равны, переходит к посимвольному сравнению. А функция String, основываясь на том, что ей уже передана длина создаваемой строки, не удосуживается проверить РЕАЛЬНУЮ длину, и тупо записывает переданный ей аргумент в поле len. В результате получаются две строки, равные посимвольно (поскольку, строго говоря, символов в них вообще нет!), но различные по длине.

В довесок - цитата из манула (ну, если кто будет говорить, что типа так и надо...) -
FreeBASIC's internal functions will ignore this (null) character, and not treat it as part of the string.
-
Встроенные функции fBasic игнорируют нулевой символ и не расценивают его как часть строки.

Вывод: не стремитесь к чрезмерной оптимизации! Как говорил какой-то известный программер (не помню, кто, вроде Кнут) - сначала заставьте программу работать правильно, а уже потом быстро!

DiG. GeRR

Сообщения : 101
Дата регистрации : 2009-01-30
Возраст : 25
Откуда : Рудный, Казахстан

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Чт Авг 27, 2009 8:34 pm

Печально, но факт.
Во фрибэйсике тупо передрали строки, не доконца выверев алгоритм.
Я по этому и пытался свой тип создать.
Есть,есть ещё глюки с этим дурацким двоичным нулём!

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  DiG. GeRR в Чт Авг 27, 2009 8:47 pm

Да... Но для меня это было неожиданностью... Привык полагаться на компилер на сто процентов. Целый день потерял, разыскивая в своем коде ошибку, которой не было. Sad

DiG. GeRR

Сообщения : 101
Дата регистрации : 2009-01-30
Возраст : 25
Откуда : Рудный, Казахстан

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Чт Авг 27, 2009 9:41 pm

Есть есть глюки.

1.
это бинарные нули.
Дело в том, что
многие функции заточены именно под zstring, ptr но не string. И полагаються на 0 в определении конца строки.

Взять к примеру print. Всё что после двоичного 0 не выведеться.

Да и ещё несколько с другими функциями.


2.
Второй глюк это копирование объектов.
Они как-то слишком уж плодяться!
Особенно при передаче в функцию.
И нет конструктора копирования.
(или же я о нём не знаю)


Кстати, ведь функция
string(4, !"\0")
Можно написать и так
string(4, 0)

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 11:33 am

вай... я аж чуть кирпич не изготовил...
Для fb string и zstring абсолютно разные типы! И для каждого типа свои функции для обработки, те если для zstring 0 - это конец строки, и ниче тут не сделаеш, то для string 0 вполне может быть частью строки, и никак ни на что не повлияет (просто он не будет выводиться, тк нет соответствующего ему символу). Тип string скорее не просто строку может обрабатывать, а даже без проблем набор любых байт кодов, и поэтому и получается, что строка из разного количества нулей - это разные строки.
Взять к примеру print. Всё что после двоичного 0 не выведеться.
щас как стукнул бы Smile
Код:
dim as string pStr="hello"
pStr[2]=0
print pStr
выводит
he lo
DiG. GeRR и поэтому, если ты только буш явно указывать, что ето тип zstring, то код будет корректным
Код:
dim as zstring*3 pStr1=>string(3, 0)
dim as zstring*4 pStr2=>string(4, 0)
if pStr1=pStr2 then
    print "Strings are equal"
else
    print "Strings are not equal!!!"
endif
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 11:42 am

Если же использовать string, и пвтаться добиться повышения производительности (хотя для этого всетаки луше использовать zstring), то врядли че из етого получится, DiG. GeRR, из твоего примера, я так понял, вместо того, чтобы вычищать память от всей строки, ты хотел занулить первый, и получить типа пустую строку, но с типом string какраз нужно изменять значение size в самой структуре, только оно может указывать истинную длинну, но если жаде явно задезть в ее нутря и вручную поставить 0, то я боюсь деструктор строки потеряет весь хвост строки (те памяти, выделенной под нее) и не будет ее вычищать, поэтому придется это делать либо самому, либо всетаки сделать pStr="", смысл от чего будет тот же, но проблем (ошибок) меньше.
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  electrik в Пт Авг 28, 2009 12:52 pm

чтобы понять что там в компиляторе, нужно его ковырять. DiG. GeRR, а вы исходники не ковыряли? на форуме не однократно задавался вопрос, как бы с чего начать. я там ковырялся, но пока так и не пойму структуру. что-то мне подсказывает, что там все не сложно, но когда лезешь в какой-нибудь .bas файл, без начала непонять.
вот в rtlib, все понятно. предположим, я придумал свою функцию, как ее добавить в компилятор. я так понимаю, есть определенная структура, где зарегистрированы все функции, операторы, да и в парсере подправлять надо, а может и нет.
может кто-нибудь все же расскажет, точку старта, хоть как-нибудь. главное, чтоб один понял, а там может и перекопаем компилятор. я думаю, что eric, поклонник ооп, сможет реализовать это дело на высоком уровне. поскольку я, хоть как-нибудь знаю ассемблер, можно сделать некоторые оптимизации. конечно я не один такой умный.
просто, то что я вижу на оф сайте, как-то вяло там все идет. может, как сказал eric, они сами разочаровались в своем проекте. нет этого ненадо допустить. ведь FreeBasic, взято много полезного с других языков, словом, basic нового времени. жаль если он навернется. ведь для ленивых, это вариант, который может посоревноваться поскорости с c. да и реализовать на нем много можно, может ооп страдает, но без него можно написать прогу для управления ракетами. может напряжемся. сколько русские бились чтоб в космос полететь и полетели. хоть FreeBasic придумали не мы, но ведь идея хорошая. ведь ракеты, которые строил королев, часть была собрана из развалин вернера фон брауна, найденых в германии.

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 12:58 pm

electrik, я тоже после етого поста скатал сырец, ща сижу колупаю Smile
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Пт Авг 28, 2009 12:58 pm

Electrik, fbc начинаеться компилироваться с makefile.
Если хочешь понять что и с кем компилиться, то вся инфа именно там.
Я туда как раз вчера заглянул и мне стало плохо.
Я то привык к простеньким, а там такая жуткая мясища.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 1:18 pm

Просто копиляция расчитана на инструменты автоматической сборки, воткак я собрал его под линухом:
auroreconf
chmod +x configure
cd obj/linux
../../configure
make
echo 'print "hello"'>test.bas
./fbc_new test.bas
./test
hello
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Пт Авг 28, 2009 1:21 pm

tux пишет:
щас как стукнул бы Smile
Код:
dim as string pStr="hello"
pStr[2]=0
print pStr
выводит
he lo

У меня только
he

А символ для chr(0) есть. Там такая рожица должна быть.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 1:24 pm

хм, ну мож потомучто я все в уникоде пишу...
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Пт Авг 28, 2009 1:26 pm

Уникод тут роли не играет.
Скорее всего разница между твоим linux и моим windows.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 1:28 pm

хотя какая разница, ведь англиские буквы в любой кодировке одинаковые
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 1:29 pm

ну если учесть что для вывода на терминал используется везде ncurses, то и выглядеть должно одинаково!
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Пт Авг 28, 2009 1:32 pm

Мало ли что должно.
Опять мелкомягкие чего-нибудь перемудрили.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  tux в Пт Авг 28, 2009 1:42 pm

хе, специально скатал под винду компилятор, под вайном скомпилил, вывел строку
helo
те просто пропустил етот символ Smile
похоже ето зависит от какойто системной функции операционки, которая обращается к терминалу, и просит его вывести символ с нулем, и от того, как в нем реализована обработка таких ситуаций, мы и видим такой результат
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Пт Авг 28, 2009 1:46 pm

Всё может быть.
Я с консолью близко не ковырялся.
Под dos'ом было дело на qbasic.
Там тоже какие-то глюи были с некоторыми символами.
Даже и не помню, как их укрощал и что были за глюки.
но под dos'ом на chr(0) точно была рожица.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  electrik в Пт Авг 28, 2009 3:15 pm

короче, попробовал всякие методы. через open cons, open scrn, все одна фигня. пишу код типа:

Код:

#define a !"hello\0world"
print a

или

Код:

#define a !"hello\0world"

open cons for output as #1
print #1,a
close
sleep

одна фигня. выводит только hello. тут действительно надо лезть в тонкости консоли. по логике все правильно, нуль- это завершающий символ строки, обрабатывать нечего.
поповоду dos, там все просто. пишем напрямую в видяху, а она выводит.
если иметь ввиду stdout и stdin, так в досе, вообще там был терминал знак $. если хочешь его вывести, пиши два раза. а вот в консоли windows, надо копаться.
поидее, open scrn, это как-раз прямое обращение, но видимо собачий print#, не реализован для этого. сделали бы так, ставлю двойной нуль и все, первый выводится, второй- терминал строки.
вот кстати, чего еще можно было б добавить во FreeBasic. поддержка вывода в консоль любого символа.
конечно, если пишут FreeBasic, несколько человек, counting_pine, i_am_drv, так все и не предусмотришь. кстати, последние изменения только от них, давно я не видел кого-нибудь другого.
кстати, мне понравилось последнее изменение, 153 файла, вот список изменений:
http://cia.vc/stats/project/fbc/.message/3e6b77

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  DiG. GeRR в Пт Авг 28, 2009 3:58 pm

но под dos'ом на chr(0) точно была рожица.

Я могу ошибаться, но...



пропущенный ноль... Тут дело такое. Функция print под винду обращается к API WriteConsoleOutput, которой передается не строка, а форматированный массив байт (ну там цвет, фон и сам символ). Функция общего назначения, поэтому используется для всего - и строку вывести, и фон залить... Поэтому ей передается не длина строки, а размер буфера данных, причем неправильный (из-за вставленного нуля) Ноль она пропускает, поскольку видимого символа для него нет (см. рисунок). Вот и получается лабуда. А под линухой все это дело происходит по-другому, вот и результат другой.

А вот тема исходников... Насчет структуры строк - это получено под gdb. В исходниках я как-то начинал копаться, но в тот момент у меня было маловато теоретических знаний, так что ничего из этого не вышло. Недавно я увлекся теорией компилирования, и в один момент снова взялся за сорцы фб. Оказалось, что они имеют довольно неплохую внутренную организацию (хотя комментов, конечно, маловато). Естественно, даже для простого чтения нужно иметь некоторую базовую подготовку (хотя бы в общих чертах понимать, что такое нисходящий синтаксический анализ, LL-грамматики, AST, таблицы символов, RISC, и прочая шелуха ну и конечно иметь представление о том, как работают компиляторы)

DiG. GeRR

Сообщения : 101
Дата регистрации : 2009-01-30
Возраст : 25
Откуда : Рудный, Казахстан

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Eric-S в Пт Авг 28, 2009 4:06 pm

Ну я в компиляторах тоже немного разбираюсь.
Сейчас вот пытаюсь один написать.
Как раз синтаксический анализ...
Второй день его отлаживаю.
Тема уже знакомая, но пишу на C++, причём на довольно низком уровне.

А вот лезть в сорци фрибэйсика страшно. Когда я в прошлый раз полез, меня приплющило и долго не отпускало.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  vbman в Вс Авг 30, 2009 3:35 pm

тут все забыли, что есть еще ассемблер встроенный - тому все пофиг... Twisted Evil
avatar
vbman

Сообщения : 52
Дата регистрации : 2008-11-19
Возраст : 35
Откуда : Украина, Кировоград

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Баг компилятора в работе со строками

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения