Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - Berserker

Страницы: 1 [2] 3 4 ... 17
16
Не похоже:

Цитировать
8.1.8 Pointer types

All pointers in Rust are explicit first-class values. They can be copied, stored into data structures, and returned from functions. There are four varieties of pointer in Rust:
Managed pointers (@)

These point to managed heap allocations (or "boxes") in the task-local, managed heap. Managed pointers are written @content, for example @int means a managed pointer to a managed box containing an integer. Copying a managed pointer is a "shallow" operation: it involves only copying the pointer itself (as well as any reference-count or GC-barriers required by the managed heap). Dropping a managed pointer does not necessarily release the box it points to; the lifecycles of managed boxes are subject to an unspecified garbage collection algorithm.
Owning pointers (~)

These point to owned heap allocations (or "boxes") in the shared, inter-task heap. Each owned box has a single owning pointer; pointer and pointee retain a 1:1 relationship at all times. Owning pointers are written ~content, for example ~int means an owning pointer to an owned box containing an integer. Copying an owned box is a "deep" operation: it involves allocating a new owned box and copying the contents of the old box into the new box. Releasing an owning pointer immediately releases its corresponding owned box.
Borrowed pointers (&)

These point to memory owned by some other value. Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers, or by applying the borrowing operator & to some other value, including lvalues, rvalues or temporaries. Borrowed pointers are written &content, or in some cases &f/content for some lifetime-variable f, for example &int means a borrowed pointer to an integer. Copying a borrowed pointer is a "shallow" operation: it involves only copying the pointer itself. Releasing a borrowed pointer typically has no effect on the value it points to, with the exception of temporary values, which are released when the last borrowed pointer to them is released.
Raw pointers (*)

Raw pointers are pointers without safety or liveness guarantees. Raw pointers are written *content, for example *int means a raw pointer to an integer. Copying or dropping a raw pointer is has no effect on the lifecycle of any other value. Dereferencing a raw pointer or converting it to any other pointer type is an unsafe operation. Raw pointers are generally discouraged in Rust code; they exist to support interoperability with foreign code, and writing performance-critical or low-level functions.

17
Пришло время таки взглянуть на Rust.

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

const — указатель не изменяемый, инициализация по месту объявления или в качестве аргумента функции;
no_addr — запрещает применение операции получения адреса к указателю; Используется для повышения возможностей оптимизатора.
auto_deref — упоминание идентификатора указателя равнозначно его разыменованию на месте "(*p)". Включает в себя no_addr. Для установки значения самого указателя используется специальный синтаксис (ключевое слово let, инициализация при объявлении в С++, аргумент функции);
fragile — "ломкий". Указатель на данные подлежащие скорому удалению. Семантика перемещения в С++;
not_null — гарантированно указывает на данные, проверка времени компиляции;
null_guard — проверка на неравенство нулевому указателю во время исполнения (в аргументах функций, при присвоении указателей без атрибута null_guard или not_null).

Теперь составим известные нам типы указателей из Ады, Паскаля, Оберона и С++ (pointer — просто указатель):

1) Указатель, к которому нельзя применить операцию взятия адреса:
Код: (cpp) [Выделить]
typedef no_addr pointer ptr;
int x;
int ptr px = &x; // px = @x
&px // error
*px = 7; // можно оптимизировать до x = 7, px выбросить вообще

2) Автоматически разыменовываемый указатель
Код: (cpp) [Выделить]
typedef auto_deref pointer ref;
int x;
int ref px; // px = @???
px = 1; // possible run-time crash
let px = &x; // px = @x
px = 1; // x = 1

3) Гарантированно указывающий на что-либо указатель
Код: (cpp) [Выделить]
typedef not_null pointer ptr;
int x, y;
int ptr p; // compile time error
int ptr p = &x; // p = @x
p = &y; // p = @y
*p = 1; // y = 1

4) Гарантированно ненулевой указатель, проверка времени исполнения
Код: (cpp) [Выделить]
typedef null_guard pointer ptr;

void Test (int ptr p) {}
iTest(nullptr); // run-time error

5) Семантика перемещения — функция принимает аргументом указатель на объект, который будет следом удалён
Код: (cpp) [Выделить]
typedef fragile pointer ptr;
void Test (TObject ptr obj) {}
int *p = new int();
Test(p);
delete p;

6) VAR-параметр Оберона, Паскаля, Ады
Код: (delphi) [Выделить]
typedef const auto_deref not_null pointer var;
procedure Test (var x: integer);
Test(1); // compile-time error
Test(x); // ok
Test(p^); // ok if p is pointer to integer

7) not null аргумент Ады, проверка времени исполнения
Код: (delphi) [Выделить]
typedef not_null pointer ptr;
procedure Test (x: ptr integer);
Test(nil); // compile-time error
Test(@x); // ok
Test(p); // ok

8) Классические ссылки в С++
Код: (cpp) [Выделить]
typedef const not_null auto_deref pointer &;
Примечание: возможность иметь ссылки на константы или возвращаемые по значению объекты есть синтаксический сахар, который можно с тем же успехом применить к любым пользовательским указателям в новой модели:

Код: (cpp) [Выделить]
const int* p = 1; // p = @c1, c1 is const int, c1 = 1
TObject Test () {}
TObject* obj = Test(); // obj = @local1, local1 is TObject, @local1 передаётся функции теневым аргументом

Что думаете, господа?

19
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 24, 2013, 08:51:36 pm »
Да, это расширения. Просто они одинаковые и ведут себя одинаково. Получается неформальный стандарт без применения условной компиляции.

20
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 24, 2013, 08:32:13 pm »
Соберётся, если писалось с использованием общей части языка (в большей степени равняются на Delphi). В VirtualPascal есть режим Делфи (не полный) и в FreePascal тоже. Я переносил свои программы между тремя. А суть в следующем: PACKED для структур во всех трёх обеспечивает alignas(1), STDCALL/CDECL/THISCALL и т.д. — правильное соглашение о вызове для функций. Паскаль не приветствует сложных кодирований расширений, вроде __xxxxx(yyy(__zzz)), поэтому есть определённое единообразие.

Это просто констатация факта, а не нападки на С++.

21
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 24, 2013, 08:03:29 pm »
Цитировать
Причем это действительно фактический стандарт, он используется. В отличае от стандарта паскаля (который по сути - фикция).
Не соглашусь с Вами, Алексей. Что лучше — несовместимые расширения без стандарта де-юре или де-факто совместимые расширения, аналог теневого стандарта? Если PACKED есть во всех популярных компиляторах, то он и есть стандарт. А вот с прагмами и declspec я натыкался на грабли, когда писал простейший SDK. Учитывая, что третьи лица используют стандарт древнее 11х невозможно не тащить за собой весь воз костылей. Так что паскалисты молодцы — там и соглашения о вызовах и выравнивания единообразно присутствуют, из-за чего код де-факто переносим. А что ещё нужно практикам?

22
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 24, 2013, 07:26:16 pm »
Если перевести на русский: до 2011 года в С++ выравнивания не было (как и массы других вещей). А как следствие, в 99% существующего кода не используется. Хорошо, что добавили, но никого не волнует скорость выхода стандартов С++. Важно, сколько лет функциональности не было и когда она появилась.

23
Общий раздел / Re: Дракон на хабре
« : Май 23, 2013, 07:57:03 pm »
На мой взгляд, Дракон-разделы изрядно засоряют информационный поток oberoncore. Я с какого-то периода вообще перестал следить за форумом, хотя ранее читал его ежедневно. Хабровчан понять не сложно.

24
Нужно написать системный модуль с процедурой: PtrToInt. Для любой конечной платформы понадобится изменить только её.

25
Общий раздел / Re: 1С - One Ass
« : Май 21, 2013, 06:52:48 pm »
Для обучения отсутствие поддержки режима клиент-сервер не вариант. Проще обучаться на полнофункциональной версии.

26
Общий раздел / Re: Юмор
« : Май 21, 2013, 06:52:01 pm »
Очень повеселило, спасибо.

27
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 20, 2013, 04:29:53 pm »
Небольшое отклонение от темы.
FreePascal, VirtualPascal, Delphi — проблемы нет, PACKED справляется с записями и массивами. То же самое с соглашениями о вызове. Все их применяют, но лишь стандарт С++ не знает об их существовании. Если целевая платформа не поддерживает определённое соглашение (разрядность, операцию умножения или любой другой элемент ЯП) достаточно выдать ошибку компиляции. Но STDCALL — он и в Африке STDCALL.

Я сперва использовал __declspec(alegn(1)), потом перешёл на #pragma pack(push, 1) из-за разичий в GCC и Студии.

28
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 20, 2013, 02:49:22 pm »
valexey_u, десятилетия и тонны софта до версии С++11х, так что это не показатель. То же самое и с новыми типами вроде int32_least_t, они нигде не используются, а нужно, чтобы весь код был с их применением.

29
Общий раздел / Re: [BlackBox] Compiler trap.
« : Май 20, 2013, 01:17:53 pm »
В С++ та же проблема без привязки к конкретному компилятору, не так ли? __declspec(align(1))

30
Возможно специалисты прояснят мне мои смутные сомнения.
Тезис заключается в следующем: ANSI C++ ни разу не кроссплатформенен. Фактически, даже простейшие вещи, вроде соглашения о вызове или экспорта/импорта функций и переменных из динамических модулей нет. Без них нельзя, фактически, ничего. Сюда же отнесём пути в заголовочных файлах (include "путь, специфичный для ОС"), выравнивание данных (как описать универсально структуру с точностью до байта).

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

По поводу юниковых утилит для сборки. Разве не рудимент, что большинство из них не хочет понимать пути с пробелами/русскими символами? Или это только в окружении Windows такая проблема? У меня отваливаются самые разные программы на С++ при неудобном для них местоположении, даже Notepad++.

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

Можно возразить, что альтернативы нет: либо централизованный общий реестр, либо ручное редактирование переменных окружения. Но реестр понадёжнее будет, на мой взгляд. В реестре если ключу "git" соответствует конкретный путь, то повторная установка его попросту перепишет. С переменными окружения хуже. Дубликаты путей к папкам, пути с различным регистром.

Страницы: 1 [2] 3 4 ... 17