Флейм
GameDev.ru / Флейм / Форум / Ü (Programmiersprache) (21 стр)

Ü (Programmiersprache) (21 стр)

Страницы: 120 21 22 2327 Следующая »
Panzerschrek[CN]Участникwww20 июня 20185:38#300
Delfigamer
> ARM на мобилках всё ещё довольно часто 32-битный.
Думаешь, к выходу более-менее работоспособной версии Ü останутся ещё такие?

kipar
> до появления 128-битных доживет
128 бит никогда не будет нужно. 640кб 64 бит адресного пространства хватит всем.

> А микроконтроллеры ещё долго такими будут.
Микроконтроллеры? А на них есть потребность в чём--то кроме Си?

return [](){};
> Дизайнить язык так, чтобы поведение не зависело от размера указателей, очевидно
> (или зависело только в unsafe)
Тут не только в языке дело, но и в стандартой бибилотеке и много ещё где.
На 64-бит какой-нибудь std::vector должен возвращать 64-битный size(), а в 32-битной среде он должен быть 32-битным. Это требует заведения какого-то псевдонима вроде size_t. Если же в 32-битной среде сделать size_t=u64, то это будет неоптимально - будет больше потребление памяти и будут медленные вычисления с размерами.

kiparУчастникwww20 июня 20189:45#301
Panzerschrek[CN]
> Микроконтроллеры? А на них есть потребность в чём--то кроме Си?
Да. Си это стрельба в ногу и решето. Причём если в компах порча памяти это почти всегда access violation  и всякие там DEP, то в контроллере никакой защиты от неё нет. Да и цена этой стрельбы в ногу большая - это ж не кривой треугольник нарисуется или формочка упадёт, это лифт не туда поедет или конвейер заклинит. Конечно там везде ставят независимые от софта цепи безопасности, но все равно вот именно там бы язык не дающий стрелять в ногу пригодился. С другой стороны - там обычно память статически выделяется, поэтому все эти фишки с деструкторами и проверкой владения не очень актуальны. Актуальнее всякие "привёл указатель не к тому типу, передал в memcpy не тот размер, обратился за пределы массива, прочитал в одном потоке а записал из прерывания на середине чтения
return [](){};Участникwww20 июня 201814:51#302
Panzerschrek[CN]
Сделать указатели, size_t и любые структуры их содержащие псевдо-runtime sized.
sizeof от них нельзя будет использовать в const выражениях.
С точки зрения компилятора они все равно будут fixed-size и такой код успешно соптимизируется:
void foo(void* p)
{
  if (sizeof(p) == 4)
  {
    ...
  }
  else
  {
    ...
  }

}
Сконвертить size_t в fixed-size только специальной функцией, которая проверит, что значение влезает в диапазон.
Сконверчивание без проверки и использование sizeof от них как константы только в unsafe.
Panzerschrek[CN]Участникwww20 июня 201815:12#303
kipar
> Да. Си это стрельба в ногу и решето.
Тогда, пожалуй, будет size_type.

return [](){};
> Сделать указатели, size_t и любые структуры их содержащие псевдо-runtime sized

> Сконвертить size_t в fixed-size только специальной функцией, которая проверит,
> что значение влезает в диапазон.
> Сконверчивание без проверки и использование sizeof от них как константы только
> в unsafe.
А зачем такие пляски?
Чем не устраивает такой подход: https://github.com/Panzerschrek/U-00DC-Sprache/blob/master/Compil… lder.cpp#L133 ?

return [](){};Участникwww20 июня 201815:26#304
Panzerschrek[CN]
Чтобы не привязывать код к размеру указателей (а еще это, например, позволит jit-тить из одного ir и в 32 и в 64 бита)
Panzerschrek[CN]Участникwww20 июня 201815:32#305
return [](){};
> Чтобы не привязывать код к размеру указателей (а еще это, например, позволит
> jit-тить из одного ir и в 32 и в 64 бита)
Для всяких контейнеров вроде optional/variant нужен constexpr size_of, если сделать size_of для какого-то типа не constexpr, всё посыпется.
return [](){};Участникwww20 июня 201815:45#306
Panzerschrek[CN]
Нужны только dynamically-sized structs, которые полезны и без этого
Panzerschrek[CN]Участникwww20 июня 201815:57#307
return [](){};
> Нужны только dynamically-sized structs
Не согласен.
Всё-же, много где может быть полезен constexpr size_of. А JIT-компиляция одного и того же ir кода, кажется, нужна очень редко. Можно, накрайняк, генерировать в таких случаях два набора ir-кода.
Panzerschrek[CN]Участникwww20 июня 201816:22#308
Меж тем, я реализовал оператор typeinfo.

Оператор typeinfo позволяет получить constexpr-структуру с информацией о типе. Выглядит это как-то так:

+ Показать


Через typeinfo можно узнать следующее:
• вид типа - фундаментальный, массив, структура, перечисление
• размер и выравнивание
• наличие конструктора по умолчанию, конструктора копирования, оператора копирующего присваивания
• для фундаментальных типов - is_signed/is_unsigned, is_float, is_bool и т. д.
• для массивов - размер и typeinfo для типа элемента
• для перечислений - количество элементов и typeinfo для базового типа
• для классов и структур - количество полей

Пока что не реализовано более полное получение внутренностей классов и перечислений. Как это сделать, надо ещё думать.

DelfigamerПостоялецwww20 июня 201819:22#309
Panzerschrek[CN]
Не лучше будет сделать, как в крестах? Когда информация о типе извлекается применением операторов к типу, то есть - вместо
typeinfo</T/>.is_fundamental
писать
is_fundamental</T/>
(или is_fundamental</T/>.value - если шаблоны констант не предусмотрены).
Преимущество такого подхода в том, что его проще расширять: с одной стороны - можно добавлять свои собственные критерии объявлением своих шаблонов; с другой - настраивать значения существующих критериев для новых типов специализациями соответствующих шаблонов.

Что же до полей агрегатов, моя первая идея - наплодить вспомогательных типов и завернуть их в связный список. Что-то типа этого.
Опять же - свойства полей вынесены в отдельные операторы, что позволяет пользователю языка задавать свои собственные свойства, например - маркеры для сборщика мусора и для сериализации. Ну а для объявления - либо добавить вспомогательные шаблоны для выборки полей по именам/по порядку/по смещению; либо предусмотреть специальный синтаксис для заполнения вот таких вот трейтов прямо при объявлении поля, аналогично крестовым атрибутам.

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

Правка: 20 июня 2018 19:27

Panzerschrek[CN]Участникwww21 июня 20186:59#310
Delfigamer
> писать
>
> is_fundamental</T/>
Так тоже можно будет.
Type traits как в крестах планируются как часть стандартной библиотеки. Оператор typeinfo как раз нужен, чтобы их реализовывать.

> наплодить вспомогательных типов и завернуть их в связный список. Что-то типа
> этого.
Не рапарсил портянку крестошаблонопитушни по ссылке. Объясни словами, что ты имеешь в виду.

> свои собственные свойства, например - маркеры для сборщика мусора и для
> сериализации
Пожалуй, можно будет, но только в отдалённом будущем.

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


> вместо ковыряния в SFINAE, лучше сделай специальный механизм для добавления
> условий к перегрузкам.
Такое есть в планах - навешивать на функции оператор вроде enable_if, который включает функцию только если условие истинно. В условие можно пихать любое constexpr bool выражение, в том числе результаты type traits вычислений.

DelfigamerПостоялецwww21 июня 201810:32#311
Panzerschrek[CN]
> Не рапарсил портянку крестошаблонопитушни по ссылке. Объясни словами, что ты
> имеешь в виду.
Для каждого поля в каждой структуре генерируется свой дескриптор - точно так же, как автоматически генерируются дескрипторы типов.
Пусть у нас объявлена структура:
struct MyStruct
{
    int i;
    std::string str;
    MyStruct* ptr = nullptr;
};
Помимо описания самого типа MyStruct, компилятор так же генерирует дескрипторы для его полей. Эти дескрипторы соединяются в связанный список:
Field[MyStruct,i] -> Field[MyStruct,str] -> Field[MyStruct,ptr] -> FieldSentinel[MyStruct]
(в этом описании я воспользуюсь синтаксисом здорового человека)
Чтобы начать проход по полям - используется специальный оператор,
FirstField[MyStruct] = Field[MyStruct,i];
который возвращает дескриптор первого поля из списка.
Чтобы перейти на следующее поле в списке - вызывается соответствующий оператор к дескриптору,
NextField[Field[MyStruct,i]] = Field[MyStruct,str];
NextField[Field[MyStruct,str]] = Field[MyStruct,ptr];
NextField[Field[MyStruct,ptr]] = FieldSentinel[MyStruct];
который, в ответ на дескриптор поля в аргументе, возвращает дескриптор следующего за ним поля в агрегате.
Вслед за последним полем в списке следует специальный дескриптор-сентинел - он не описывает никакого поля, а только обозначает конец списка.
Чтобы его отследить - применяется выражение
IsSentinelField[Field[MyStruct,_]] = False;
IsSentinelField[FieldSentinel[MyStruct]] = True;

Чтобы пройтись по этому списку, применяется хвостовая рекурсия:

PrintFieldList = Function[{field, object},
  If[!IsSentinelField[field],
    PrintField[field, object];
    PrintFieldList[NextField[field], object]]];
PrintStructFields = Function[{object},
  PrintFieldList[FirstField[TypeOf[object]], object]];

Чтобы получить реальную информацию о поле - к дескриптору применяются соответствующие операторы:

FieldOwner[Field[MyStruct,ptr]] = MyStruct;
FieldType[Field[MyStruct,ptr]] = Pointer[MyStruct];
FieldOffset[Field[MyStruct,ptr]] = 40;
FieldName[Field[MyStruct,ptr]] = "ptr";
FieldGet[Field[MyStruct,ptr], object_] := object[["ptr"]];
FieldSet[Field[MyStruct,ptr], object_, value_] := (object[["ptr"]] = value);

Например:

PrintField = Function[{field, object},
  Print[FieldName[field], ": ", FieldType[field], " = ", FieldGet[field, object]]];

В примере по ссылке - приведена общая функция по итерации по полям:

FoldFieldList = Function[{functor, field},
  If[!IsSentinelField[field],
    functor[field];
    FoldFieldList[functor, NextField[field]]]];
FoldStructFields = Function[{functor, objtype},
  FoldFieldList[functor, FirstField[objtype]]];
А затем эта функция используется в двух сценариях - вывод информации о типе
FoldStructFields[
  Function[{field},
    Print[FieldType[field], " ", FieldName[field], " // ", FieldOffset[field]]],
  MyStruct];
и отладочный вывод произвольной структуры:
b = MyStruct[];
FoldStructFields[
  Function[{field},
    Print[FieldGet[field, b]]],
  MyStruct];
А немалая часть лапшы - это условные выборы через SFINAE.
А ещё я настоятельно рекомендую подтянуться в функциональной парадигме программирования - ибо шаблоны именно этим и являются, только с совершенно неинтуитивным синтаксисом.

Правка: 22 июня 2018 6:59

Panzerschrek[CN]Участникwww21 июня 201816:19#312
Delfigamer
> Для каждого поля в каждой структуре генерируется свой дескриптор - точно так
> же, как автоматически генерируются дескрипторы типов.

> Эти дескрипторы соединяются в связанный список

О, понял, крутая идея!
В связный список можно объединять разнотипные описатили и итерироваться по ним рекурсивно.

Panzerschrek[CN]Участникwww23 июня 201817:38#313
Подумываю тут, стоит ли всё же сделать возможность объявлять сущности в модуле в произвольном порядке, да так, чтобы сразу были видны символы, объявленные позже.
Стоит ли вообще? Или лучше забить?
AdlerПостоялецwww24 июня 201812:17#314
Panzerschrek[CN]
> Подумываю тут, стоит ли всё же сделать возможность объявлять сущности в модуле
> в произвольном порядке, да так, чтобы сразу были видны символы, объявленные
> позже.
> Стоит ли вообще? Или лучше забить?
Самый жир когда в шаблонном коде окажется что-то типа вот такого и нужно будет сгенерировать внятное сообщение об ошибке определения размера структуры.
struct A{B b;};struct B{С с;};struct C{A a;};

Правка: 24 июня 2018 12:17

Страницы: 120 21 22 2327 Следующая »

/ Форум / Флейм / ПроЭкты

2001—2018 © GameDev.ru — Разработка игр