HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Наш форум > Флуд > Заметки на полях
Разработка С++ совместимой виртуальной машины
Страницы (11): « Первая ... « 2 3 4 5 [6] 7 8 9 10 » ... Последняя »   Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Сделал шаблоны, ну пока только на классы. Может показаться, что шаблон на функцию ввести легче, однако это не так. Потому что перегрузка функций, блин! А шаблонные функции учитываются дедуктором тоже, что его значительно осложняет. Как вы знаете если у вас есть шаблонная функция, то вовсе необязательно при её вызове указывать foo<int>, можно просто написать foo, она должна корректно обнаружиться (даже при условии, что инстанцирование вообще не было произведено), затем, будет выполнено сравнение по кол-ву аргументов, чтобы решить, надо ли в данном случае вообще выполнять инстанцирование, или пока еще рано, затем собственно, сконструировать такую функцию и запустить её в общее пространство. С классом гораздо проще - если встретился незнакомый тип, за которым идёт скобка < то это полюбому шаблон. Возможно, необъявленный, но шаблон. Как вы знаете шаблон класса объявить неявным образом нельзя.
Хотя хрен знает, может быть в каких-то новых студиях и можно, я уже запутался в этих стандартах. Так же хочу отметить, что исходник класса для шаблона хранится и парсится целиком, без какого-либо разбора на отдельные функции. Это приводит к забавному эффекту - если внутри шаблонного класса были объявлены всяческие конструкторы и копи-конструкторы, то компилятор немедленно начинает их требовать у класса-аргумента typename. Настоящая студия, как вы помните так себя не ведёт - она не конструирует шаблонные функции класса до последнего момента или делает их во время надписи Generating code... Соответственно, если функция не была вызвана, то она даже распарсена не будет, таким образом ошибки в шаблонах могут годами лежат незамеченными, главное не вызывать явным образом функцию, содержащую ошибку. Но вот теперь я даже прямо не знаю - это баг или фича? Оставить или сделать как в настоящей студии, хотя это довольно непростая задачка и я её в любом случае напотом оставлю.
Так же более-лименее разобрался с конструкторами тривиальных типов.
Ну я выше про них писал. Оказывается что компилятор различает ГДЕ был вызван это конструктор - в теле шаблона или просто пограммист баловался. Так вот если в теле шаблона, то обычный конструктор для тривиальных типов не делает вообще ничего, а копи-конструктор инициирует либо присвоение, либо вызов копи-конструктора у самого класса-аргумента, либо вызов memcpy. У меня лично нет вызова memcpy, хотя по сравнению С++ в моём языке копировать объекты через Memcpy даже с виртуальными функциями абсолютно безопастно. Ну потому что в C++ виртуальная таблица наглухо встроена в сам объект и её адреса - локальные. А в у меня это просто хэндл на индексированную структуру RTTI, которую компилятор строит в любом случае, даже если никаких виртуальных методов у класса нет. Строит для доступа в бакэнде к любой переменной, для сериализации, ну и вообщще для манипуляции с верхнего уровня, как говорится, ведь в этом и смысл виртуальной машины - для возможности такого доступа. Поэтому у меня копирование объектов через memcpy абсолютно безопасно, но компилятор пока что сам не провоцирует подобные вызовы вместо copy constructora.
Я пока не определился как будет лучше. Учтите, что это один из самых стрёмных моментов в плюсах, когда неявно сгенерированный вызов memcpy в MSVC потом порождает порчу кучи и вообще цепочку трудно-объяснимых багов, которые лечатся созданием корректного копи-конструктора, но естественно никакого сообщения об ошибке, которое могло бы натолкнуть программиста на мысль об этом не выдаётся.

Добавлено 25-09-2022 в 13:47:

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

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211231

Старое сообщение 25-09-2022 10:47
-
a1batross
Житель форума

Дата регистрации: May 2016
Проживает: Москва
Сообщений: 516
Возраст: 26

Рейтинг



Дядя Миша к слову, да, помнится по неопытности затирал классы memset, пока не выстрелил в колено пустым vtable.

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

__________________
Xash3D FWGS форк

Сообщить модератору | | IP: Записан
Сообщение: 211249

Старое сообщение 27-09-2022 09:20
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
a1batross писал:
к слову, да, помнится по неопытности затирал классы memset

У меня это тоже можно, т.к. хэндл vtable находится в самом начале памяти объекта. Но нулевой объект - это заглушка, так что приложение не упадёт, а просто взорвётся сообщениями про pure virtual method и продолжит свою работу. Впрочем уронить "до винды" тоже можно. Хотя я конечно и принял все возможные меры для противодействия этому. Но раз есть указатели, взятие указателей и дереференс, возможности выстрелить себе в ногу кратно возрастают.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211254

Старое сообщение 27-09-2022 10:52
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Начал вот тут разбираться с анализатором недостижимого кода и обратил внимание, что студии в принципе плевать на такие условия как if( 0 )
Она их не считает за мёртвый код. То есть вот такое вот:

C++ Source Code:
1
void TestDeadCode( void )
2
{
3
  return;
4
 
5
  Msg( "dead-code\n" );
6
}

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

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211346

Старое сообщение 10-10-2022 10:41
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



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

Вот скажем, чтобы определить постфиксный оператор ++ или --, надо добавлять дополнительный аргумент оператору, который... не будет использоваться. А как иначе отличить префиксный оператор от постфиксного?

Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.

Ксерокс, ЕМНИП вообще был уверен, что перегрузка постфиксного оператора невозможна. Потом опять же, в теории каждый оператор должен обходиться двумя операндами. Вернее говоря, каждое выражение должно быть разобрано таким образом, чтобы получилось максимум два операнда.
И да, это практически во всех случаях соблюдается. Кроме одного случая - оператора []. Ведь мы же не знаем скольки мерный массив там может быть в теории? Значит нам нужно как минимум распарить вперёд всю цепочку [][][] чтобы подсчитать хотя бы кол-во операндов. Да и сам принцип, когда каждый аргумент соответствует каждому индексу доступа в массиве несколько неинтуитивен. Прикол в том, чтоб это обычно юзают максимум для одномерных массивов, поэтому считается, что проблемы нет.
Так же неинтуитивны все эти копи-конструкторы, который по сути является неявным оператором присвоения, но вам надо как минимум точно отделить ситуацию когда вызывается именно копи-конструктор, а когд оператор присвоения. В противном случае у вас при попытке копирования классов с виртуальными методами будет гарантированный крэш. Прикол еще и в том, что С++ никак не предупреждает об отсутствии пользовательского копи-конструктора и оператора присвоения. Камрад Ксерокс мне так и сказал, а зачем? Это мол штатная ситуация, здесь и нет никакой ошибки. Это работа для статистических анализаторов. Да, разделение труда - всё-таки великая вещь. Так вот товарищи, по факту т.н. "поэлементное копирование класса" на самом деле скорее всего через memcpy происходит. Либо там не вызывается дефолтный конструктор при подобном копировании. Корочи говоря, будет вылет и вы даже не поймете почему. Я в своём языке стараюсь все ситуации которые меня бесили в оригинальном С++ вешать на новые варнинги, чтобы пограммист был в курсе событий. Хотя кто его знает, может в новых студиях эти варнинги уже имеются, а в шестёрке их ещё не было?
Так же предстоит сделать кастомные операторы приведения типов, это вообще отдельный механизм, но сперва надо правильно расставить приоритеты встроенным операторам.

Добавлено 29-11-2022 в 18:45:

ЗЫ. совсем забыл. Я планирую сделать возможность превращать свойства в операторы. Но не так по идиотски как это сделано в делфи, а с возможностью множественного выбора. Они будут одновременно и операторами копирования и приведения типов и индексированного доступа.
И свойства в этом плане гораздо нагляднее всех этих копи-конструкторов.
Хотя традиционные подходы С++ тоже останутся, разумеется.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211864

Старое сообщение 29-11-2022 15:45
-
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34509
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
Дядя Миша писал:
Ксерокс, ЕМНИП вообще был уверен, что перегрузка постфиксного оператора невозможна.

Глупости какие. Там дополнительный неиспользуемый инт в сигнатуру добавляется и всё.
Цитата:
Дядя Миша писал:
Так вот товарищи, по факту т.н. "поэлементное копирование класса" на самом деле скорее всего через memcpy происходит.

Нет, там делается поэлементное копирование мемберов. Это и есть копи конструктор по умолчанию. То есть мембер std::string скопируется вполне корректно, т.к. у него есть копи-конструктор, который и будет вызван.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 211865

Старое сообщение 29-11-2022 15:51
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



ЗЗЫ. Если вдруг кто не знал, у операторов && и || при перегрузке исчезает ленивость, что на мой взгляд делает их перегрузку полностью бессмысленной.

Добавлено 29-11-2022 в 18:53:

Цитата:
XaeroX писал:
Нет, там делается поэлементное копирование мемберов

Тогда почему vtable херится?

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211866

Старое сообщение 29-11-2022 15:53
-
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34509
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
Дядя Миша писал:
у операторов && и || при перегрузке исчезает ленивость

Очевидно, исчезает, потому что теперь это функции со своими правилами sequencing.
Цитата:
Дядя Миша писал:
делает их перегрузку полностью бессмысленной

Нет, не делает: http://cpptruths.blogspot.com/2014/...-and-using.html

Добавлено 29-11-2022 в 10:58:

Цитата:
Дядя Миша писал:
Тогда почему vtable херится?

А она херится?

__________________

Сообщить модератору | | IP: Записан
Сообщение: 211867

Старое сообщение 29-11-2022 15:58
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Тернарка в шаблоне для возвращения ленивости?

Добавлено 29-11-2022 в 18:59:

Цитата:
XaeroX писал:
А она херится?

естественно

Добавлено 29-11-2022 в 19:01:

Возьми класс с виртуальными методами, сделай шаблонный массив и покопируй из него элементы при условии что никаких явных копиконструкторов и операторов присвоения у него нет. vtable будет испорчена.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211868

Старое сообщение 29-11-2022 16:01
-
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34509
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
Дядя Миша писал:
естественно

Да кто тебе сказал такую глупость.

Добавлено 29-11-2022 в 11:09:

Цитата:
Дядя Миша писал:
Возьми класс с виртуальными методами, сделай шаблонный массив и покопируй из него элементы при условии что никаких явных копиконструкторов и операторов присвоения у него нет. vtable будет испорчена.

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

__________________

Сообщить модератору | | IP: Записан
Сообщение: 211869

Старое сообщение 29-11-2022 16:09
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
XaeroX писал:
у тебя один и тот же тип и идентичная втабля

Как она может быть идентичной, если в С++ она таскается вместе с объектом?
ну то есть да, по содержимому она идентична, но адреса-то все разные там.

Добавлено 29-11-2022 в 19:13:

Цитата:
XaeroX писал:
Её и копировать-то не надо.

Так понятно, что не надо, но этож не я с ней что-то делаю, а компилятор.

Добавлено 29-11-2022 в 19:14:

Цитата:
XaeroX писал:
Я думаю, здесь проблема не в наличии копи-конструктора, а в том, что компилятор не может вывести правильный тип.

Поэкспериментируй сам. Может быть компиляторы со времён шестёрки поумнели и больше так не делают.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211871

Старое сообщение 29-11-2022 16:14
-
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34509
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
Дядя Миша писал:
ну то есть да, по содержимому она идентична, но адреса-то все разные там.

Там разве не оффсеты хранятся? Этот момент я запамятовал.
Цитата:
Дядя Миша писал:
Поэкспериментируй сам

Ну я сделал простой эксперимент с классом с данными, без копи конструктора и с виртуальными функциями, всё копируется правильно. Но я брал GCC какой-то свежей версии.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 211876

Старое сообщение 29-11-2022 16:31
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
XaeroX писал:
Там разве не оффсеты хранятся?

Не, там поидее уникальные адреса. Хотя для GCC может как-то иначе это реализуется? Реализация vtable кроме общих моментов разве предмет стандартизации? Помоему даже её размер никак не регламентирован.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211878

Старое сообщение 29-11-2022 18:27
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32202
Нанёс повреждений: 392 ед.

Рейтинг



Так товарищи, самый важный вопрос!

Попробуйте скомпилировать этот код:

C++ Source Code:
int		i = 0, j;
 
j = ++i++;

Шестёрка выдает error C2105: '++' needs l-value по вполне понятным причинам. Интересно как ведут себя другие компиляторы.

Между прочим, знаменитая пугалка
C++ Source Code:
j = ++i++ + ++i++;

Аналогично не компилируется, и у меня в языке оно аналогично.
Вот и думаю, вкорячить туда UB чтоб собиралось или действительно пусть выдаёт ошибку?

Добавлено 02-12-2022 в 11:49:

Я поясню, почему происходит именно так.
Первым вызывается префиксный инкремент, однако для него ещё нет переменной, поэтому рекурсивно вызывается парсер очередного выражения, который разбирает постфиксный инкремент.
На уровне опкодов, это выглядит примерно так:

C++ Source Code:
c = a; a += 1;


Тонкость в том, что c, это lvalue перед =. Оно приходит в префиксное выражение, но не приходит в постфиксное. Его туда без проблем можно пропустить, но нужно ли?

Добавлено 02-12-2022 в 11:52:

Проще говоря UB заключается в нагромождении дополнительных условий внутри операторов, ну типа если lvalue == void, взять i как lvalue.
Вот так оно и появляется, например. Но есть ли в этом смысл?

Добавлено 02-12-2022 в 11:53:

Вот я пропустил lvalue j внутрь суффиксного инкремента. Для выражения

C++ Source Code:
j = ++i++ + ++i++;

у меня получился результат
i = 2, j = 3
не думаю что это правильно.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 211894

Старое сообщение 02-12-2022 08:53
-
FiEctro
Кот Арсис

Дата регистрации: Aug 2006
Проживает: код
Сообщений: 12893
Возраст: 32

Рейтинг



А где это можно использовать?

__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!

Отредактировано FiEctro 02-12-2022 в 11:22

Сообщить модератору | | IP: Записан
Сообщение: 211895

Старое сообщение 02-12-2022 11:19
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 08:43. Новая тема    Ответить
Страницы (11): « Первая ... « 2 3 4 5 [6] 7 8 9 10 » ... Последняя »   Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Наш форум > Флуд > Заметки на полях
Разработка С++ совместимой виртуальной машины
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Crystice Softworks © 2005 - 2024