IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Немного о синтаксисе и безопасности, языков программирования
volvo
сообщение 4.01.2011 11:32
Сообщение #1


Гость






Итак, Новый Год, заняться особенно нечем, а давайте я вас чуть-чуть "подразню" что-ли? smile.gif Покажу вам на простых примерах некоторые возможности одного из языков программирования, который многие считают устаревшим. Не вопрос, считайте дальше, на данный момент мы пользуемся Стандартом 2005-го года, т.е., новее, чем у С++, к 2012 готовится очередная версия Стандарта.

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

Итак.

С чего начнем? Наверное, с Hello World? Нет, не интересно. Напишем хоть сколько-нибудь полезную программку. Пускай она получает от пользователя число, и определяет, положительное оно или отрицательное:

(Паскаль)
var i: integer;
begin
write('i = '); readln(i);

if i > 0 then writeln('positive')
else writeln('negative or zero');
end.


(Ада)
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
i: integer;
begin
Put("i = ");
Get(i);

if i > 0 then Put_Line ("positive");
else Put_Line("negative or zero");
end if;

end;

Что бросается в глаза? "Многословность". Похоже, это - единственный недостаток Ады smile.gif

Давайте теперь немного поговорим о преимуществах.

0. Описание переменных по мере необходимости. (Показать/Скрыть)

1. Циклы For. (Показать/Скрыть)

2. Проверка логических условий. (Показать/Скрыть)

3. Оператор Goto (Показать/Скрыть)

4. Дефолтные параметры процедур/функций. (Показать/Скрыть)

5. Инициализация массивов. (Показать/Скрыть)

6. Еще немного о массивах. (Показать/Скрыть)

7. Параметры подпрограмм. (Показать/Скрыть)

8. Дженерики. (Показать/Скрыть)



Немного о безопасности

Недавно мне задали вот такой (очень, казалось бы, простой) вопрос: "Везде, где написано про язык программирования Ада, есть утверждение, что он - более безопасный, чем тот же С/С++. А в чем это выражается?"

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

1. Пример программы на С
#include <stdio.h>
int main () {
int length = 8265;
int width = 0252;
int height = 8292;
printf ("length = %d\n", length);
printf ("width = %d\n", width);
printf ("height = %d\n", height);
}
Программа прекрасно компилируется и запускается на выполнение...
Но каким будет ее вывод?

Вот таким будет вывод: (Показать/Скрыть)


2. Корректен ли следующий код:
#include <limits.h>

/*
Если *y - ноль и x > 0, то *k приравнять максимальному положительному числу
Если *y - ноль и x <= 0, оставить *k без изменений
Если *y - не ноль, присвоить *k значение x деленного на *y, и увеличить *y на 1
*/
void check_divide (int *k, int x, int *y) {
if (*y = 0)
if (x > 0)
*k = INT_MAX;
else
*k = x / *y /* Здесь делить на *y безопасно, поскольку нулю оно не равно */;
*y++;
}
? Несмотря на то, что программа компилируется, здесь присутствуют как минимум 4 серьёзные проблемы. Какие?

... (Показать/Скрыть)


3. Что касается ассоциативности и приоритета операций:

Что означает условие
if (x & mask == 0) ...
?

Оно компилируется, но... (Показать/Скрыть)


А вот это:
if (x < y < z) ...
?

И это тоже компилируется, но... (Показать/Скрыть)


4. Еще о синтаксисе...

Корректен ли следующий код:
// -- Если впереди "зелёный" свет - увеличить скорость
void increase_speed_if_safe (int speed, int signal) {
if (signal == CLEAR);
increase_speed ();
}
?

Код компилируется без предупреждений, но... (Показать/Скрыть)


5. Поговорим о перечислениях...

enum Alert_Type {LOW, MEDIUM, HIGH, VERY_HIGH};

void handle_alert (enum Alert_Type alert) {
switch (alert) {
case LOW:
activate_camera ();
case MEDIUM:
send_guard ();
case HIGH:
sound_alarm ();
}
}

void process_alerts () {
handle_alert (2);
...
Программа компилируется, но выполняться будет совсем не так, как кажется. В чем дело?

А дело в том, что... (Показать/Скрыть)


6. Неопределенности

Что здесь происходит:
{
int k = 0;
int v [10];
k = v [k++];
}
?
А происходит здесь... (Показать/Скрыть)


7. Проблемы с системой типов языка.

Программа компилируется, но все равно в ней что-то не так:
typedef int Time;
typedef int Distance;
typedef int Speed;

// ...
const Speed SAFETY SPEED = 120;

void increase_speed (Speed s);

// …
void check_speed (Time t, Distance d) {
Speed s = d/t;
if (s < SAFETY_SPEED)
increase_speed (t);
}

void perform_safety_checks () {
Time t = get_time ();
Distance d = get_distance ();
// …
check_speed (d, t);
}

Что именно?
Уууу... Да здесь целый букет... (Показать/Скрыть)


8. Проблема переполнения.

Что произойдет в следующем фрагменте программы на С (или на С++):

#include <limits.h>
void compute () {
int k = INT_MAX;
k = k + 1;
}

?
... (Показать/Скрыть)


Disclaimer
Только не надо говорить, что примеры-искусственные, и специально подобраны так, что Ада показана выигрышно. Попробуйте привести примеры, как избежать в С/С++ тех неоднозначностей, о которых я написал, чтобы дать возможность компилятору не пропустить ошибку или недочет программиста.

По большей части смысл данной темы - в том, чтобы показать, что большинство проблем связано с излишней "гибкостью" языка, в котором "разрешено все то, что не запрещено" (а запрещено явно очень немного вещей), что то же самое и даже гораздо большее можно сделать и без этих правил, разрешающих "всё и вся", с таким строгим синтаксисом, как у Ады.
 К началу страницы 
+ Ответить 
Unconnected
сообщение 4.01.2011 15:05
Сообщение #2


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Фухх, осилил) С многим сам сталкивался, вот например кажется такой код в С++

int k;
if (k=5) {...}



, и это компилировалось, насколько помню.. только непонятно, в чем заключалось условие, в успешном присваивании?

С условиями жизненно, помню, ловил такое долго) Правда, можно сделать if U1 then if U2 then ... , тогда точно будут по отдельности выполняться.

А вот такую штуку

var a:integer;
m:array [1..a] of byte;


было бы неплохо в паскале завести, давно хочу)

Ну, я так понял, что во многом Ада даёт "защиту от дурака", и если не выделываться (ну типа if (a<b<c) - тут на ходу дотумкать можно, что компилятор может не понять правильно), то скорее всего всё будет хорошо. Ну и где надо она гибше, да.. с всеуничтожающим break хорошо придумали.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 4.01.2011 19:47
Сообщение #3


Гость






Цитата
и если не выделываться (ну типа if (a<b<c) - тут на ходу дотумкать можно, что компилятор может не понять правильно), то скорее всего всё будет хорошо
Ну вот и приведи мне решение (хочешь - на Паскале, хочешь - на Сях, хочешь - на С++), которое позволит мне на этапе компиляции забраковать неправильные варианты вызова процедур/функций (я про пункт "7. Проблемы с системой типов языка") smile.gif

Цитата
я так понял, что во многом Ада даёт "защиту от дурака"
Это не совсем "защита от дурака". Это надежность программ прежде всего.

Кстати, очень многие вещи остались "за кадром": встроенная в язык работа с подзадачами/потоками (с 1983 года !!! Причем средствами языка, нет никакой зависимости ни от ОС, ни от используемого компилятора) и межпоточное взаимодействие (аналогично, средствами языка), и защищенные типы (попробуй написать потокобезопасный контейнер на Паскале, например, чтоб с ним можно было безопасно работать из десятка потоков)... И так пост большой получился... Если кому интересно - расскажу.
 К началу страницы 
+ Ответить 
-TarasBer-
сообщение 4.01.2011 20:09
Сообщение #4


Гость






> Что бросается в глаза? "Многословность".

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

> Описание переменных по мере необходимости.

Это прикольно, но процедуры на более чем 100 строк считаются дурным тоном. А для коротких процедур завести переменную в начале не обломно.

> Циклы For.

+

> Проверка логических условий.

Все уже сто лет привыкли, что полной проверки нет и пользуются этим.
На крайняк можно написать if a then if b...

> Оператор Goto

+

> Дефолтные параметры процедур/функций.

+

> Инициализация массивов.

+

> Еще немного о массивах.

> (чем не "сборка мусора"?)

Надеюсь, там не сборка, а детерминированное удаление при выходе из зоны видимости? Другой автоматизации работы с памятью я не признаю.

> Параметры подпрограмм.

Не вкурил. Есть же директива const.

> Дженерики.

То есть можно делать приколы из С++, в котором шаблоны - функциональный язык, выполняющийся во время компиляции? Это интересно.

> Системы счисления

+

> Смешивание "=" и "==".

За это надо построить машину времени, вернуться в прошлое и убить Ритчи. И эта зараза во всех новых языках!!!

> Поговорим о перечислениях...

А что, перечисления Си даже в отладчике видны как числа? Я так не смогу, я привык, что в отладчике вижу нормальные имена.

> гибкие селекторы - можно сделать и так:

Да, тут у Си полный облом.

> Ошибка компиляции: несоответствие типов параметров

Это правильно, но принудительной ретипизацией это можно обойти?

> В Аде каждый раз, когда происходит переполнение выбрасывается исключение (на всех поддерживаемых платформах). То же смое касается и попытки деления на 0, и выхода за пределы массива, ну, и так далее...

Не понял, в код вставляются проверки выхода за диапазон? Это отрубаемо, надеюсь?

> только непонятно, в чем заключалось условие, в успешном присваивании?

Нет. В том, что результат присваивания не ноль.

> var a:integer;
> m:array [1..a] of byte;

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




 К началу страницы 
+ Ответить 
-TarasBer-
сообщение 4.01.2011 20:17
Сообщение #5


Гость






А вот что меня напрягает в синтаксисе Паскаля (и у Ады тоже, кажется, есть этот минус), так это то, что функции, не принимающие параметров, можно записывать без пустых скобочек.
Где-то была тема, в которой три человека очень долго думали, что в данном контексте значила pointer(a) - вызов метода или указатель на метод? Нужен был указатель, но почему он не вызовется, сказать наверняка было невозможно.
Да и вообще, это нарушает логичность.
 К началу страницы 
+ Ответить 
volvo
сообщение 4.01.2011 20:43
Сообщение #6


Гость






Цитата
Насколько я знаю, для закрытия блока надо тоже его назвать.
Это настраиваемо. Мой компилятор с этим справляется сам, посему у меня отключено. А вообще - да, окончательную проверку на Styling программа не пройдет, пока все отступы не будут выровнены, все блоки не будут названы, и все подпрограммы не будут размещены в алфавитном порядке с предварительным описанием в файле спецификаций (некий аналог Interface-части юнитов Паскаля. Кстати, по той же причине - облегчение поиска в случае необходимости).

Цитата
А для коротких процедур завести переменную в начале не обломно.
Ниже я написал один из способов применения. Это удобно...

Цитата
Все уже сто лет привыкли, что полной проверки нет и пользуются этим.
А если мне НАДО полную проверку? Ада-решение: вместо "and then" пишется просто "and", вместо "or else" - просто "or"... Паскаль заставляет меня опять заморачиваться с директивами компиляции, остальные языки - тоже...

Цитата
Надеюсь, там не сборка, а детерминированное удаление при выходе из зоны видимости? Другой автоматизации работы с памятью я не признаю.
Я тоже не терплю языков, которые навязывают мне свой GC. По этой причине я не стал изучать ничего из .NET-а, по этой же причине не ушел на Оберон... Там именно удаление при выходе из области видимости... Сборшик мусора Стандартом Ады не запрещен, но и не навязывается. Есть - используй, нет - не используй...

Цитата
А что, перечисления Си даже в отладчике видны как числа?
Отладчик добавляет к числу еще и идентификатор. Но все равно, неявное приведение к типу int делает свое черное дело при работе программы...

Цитата
Не понял, в код вставляются проверки выхода за диапазон? Это отрубаемо, надеюсь?
Да, для этого надо пересобрать программу с другими ключами.

Добавлено через 9 мин.
Цитата
Нужен был указатель, но почему он не вызовется, сказать наверняка было невозможно.
У Ады совершенно нет этой проблемы (по крайней мере, попадать в такое положение, при котором возникала бы неоднозначность мне не приходилось). Если нужен указатель на метод - P'Access, нужен вызов метода - просто P... В Паскале - помню, было... А пустые скобки меня в Дельфи/FPC напрягают, например.
 К началу страницы 
+ Ответить 
TarasBer
сообщение 4.01.2011 22:22
Сообщение #7


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Ниже я написал один из способов применения. Это удобно...

С одной стороны, удобно, с другой, не бьёт по рукам любителей простыней.

> А если мне НАДО полную проверку?

Зачем? Ради побочных эффектов вычисления операндов?
Тогда заранее в отдельные переменные записываешь результаты вычислений операндов.
По-моему это не так часто происходит, чтобы заводить отдельно оператор "и-с-полной-проверкой" и оператор "и-с-неполной-проверкой".
По крайней мере я ни разу не ощутил потребность в таком операторе.

> Там именно удаление при выходе из области видимости...

И можно создавать свои объекты, которые в автовызываемом деструкторе делают освобождения ресурсов, закрытия файлов итд?
А ГЦ недетерминирован, ставит крест на приложениях реального времени, всё равно в кривых руках память течёт (да), а в прямых, если в языке есть автовызов деструктора, нафиг он нужен? Стандартный счётчик ссылок не работает только в хитрых структурах, двусвязных списках, например, ну так для них объектную оболочку можно сделать, чтобы все опасные операции внутри реализации класса были зашиты, а оболочка это сама всё вычистит при выходе из зоны видимости.

> Да, для этого надо пересобрать программу с другими ключами.

Тогда нормально. Хошь - компилируй в программу с полным контролем и безопасностью, хошь - на скорость дави.

> У Ады совершенно нет этой проблемы

Ну надеюсь. Просто пустые скобки - это как сигнал, что типа это может иметь побочные эффеты, если что, надо кешировать.

А в Дельфи я нашёл эту тему с неоднозначностью:
http://www.gamedev.ru/code/forum/?id=141396


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 4.01.2011 23:29
Сообщение #8


Гость






Цитата
И можно создавать свои объекты, которые в автовызываемом деструкторе делают освобождения ресурсов, закрытия файлов итд?
Угу.

-- В отдельном пакете описываем объект:
type MyObject is new Controlled with
record
... -- Тут все, что мне нужно
end record;

procedure Initialize (Obj : in out MyObject);
procedure Finalize (Obj : in out MyObject);


Для Controlled-типов процедуры Initialize и Finalize (конструктор/деструктор, можно и так) вызываются автоматически. Все, что мне останется сделать:

declare
Obj : MyObject; -- Тут вызовется Initialize
begin
-- Работаем с объектом
end; -- Тут же, при выходе из области видимости, вызовется Finalize


Если же мне захочется самому вызывать конструктор/деструктор - не надо наследоваться от Controlled...
 К началу страницы 
+ Ответить 
TarasBer
сообщение 5.01.2011 0:03
Сообщение #9


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Для Controlled-типов процедуры Initialize и Finalize (конструктор/деструктор, можно и так) вызываются автоматически.

Всё, хочу перейти на Аду.
Есть какие-нибудь бесплатные среды под Вин32? Мне достаточно редактора кода и заголовков от ВинАПИ, формошлёпалку не надо.

Добавлено через 9 мин.
А, я что ещё вспомнил.
Могут ли out-параметры быть по умолчанию?
Мне не удалось в Дельфи написать var s: string = nil^, пришлось вспомнить, что передача по ссылке - это неявная передача указателя и написать s: PString = nil.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 5.01.2011 0:16
Сообщение #10


Гость






Цитата
Есть какие-нибудь бесплатные среды под Вин32?
Есть. Без формошлепалки, IDE для Win/Lin со всеми необходимыми пакетами можно взять здесь (просто выбираешь Free sortware or Academic Development, можешь даже не указывать мыло, и собираешь для себя пакет скачки. Обязательно качать Gnat GPL и Win32Ada, это как раз то, что ты описал - заголовки WinAPI и компилятор со всеми прибамбасами. Я для себя еще брал QtAda, но это - для любителя особых извращений...)

Добавлено через 8 мин.
Цитата
Могут ли out-параметры быть по умолчанию?
Нет, только In-параметры. Даже In Out не могут. А оно надо?
 К началу страницы 
+ Ответить 
TarasBer
сообщение 5.01.2011 0:28
Сообщение #11


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Нет, только In-параметры. Даже In Out не могут. А оно надо?

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


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 5.01.2011 1:20
Сообщение #12


Гость






Цитата
а заводить спец переменную ради возвращения того, что мне не надо, некрасиво.

lol.gif Я посмотрю, что ты скажешь, когда Ада заставит тебя вместо
ReleaseDC (hwnd, My_DC);
написать
i_Result : Win32.INT;
-- ...
i_Result := ReleaseDC (hwnd, My_DC);
, ибо функция должна в любом случае значение вернуть (а еще интереснее - если подряд вызываются три функции, одна возвращает Win32.BOOL, вторая - Win32.INT, а третья - Win32.LONG. Вот и опишешь три переменных: i_Result, b_Result и L_Result, хотя они тебе тоже не особо и сдались...). Это тебе не С, где на такие вещи можно просто не обращать внимание. Это - Ада. Не сделал - не откомпилировал...

Все Сиш-ные и Дельфийские замашки, основанные на хаках и бесконтрольном приведении типов придется забыть. Ибо Ада тебе даже не гарантирует, что матрица хранится по строкам. Она может храниться и по столбцам, как в Фортране...
 К началу страницы 
+ Ответить 
Lapp
сообщение 5.01.2011 13:20
Сообщение #13


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


volvo, спасибо за это эссе, +1 good.gif

Я встряну мимоходом.
Цитата(volvo @ 4.01.2011 20:43) *
А если мне НАДО полную проверку? Ада-решение: вместо "and then" пишется просто "and", вместо "or else" - просто "or"... Паскаль заставляет меня опять заморачиваться с директивами компиляции, остальные языки - тоже...
Я уже как-то говорил об этом.. За всю свою практику я не встретил ни одного случая, где это было "НАДО". Все примеры на эту тему как правило сродни чесанию правой пяткой за левым ухом. Так что я для себя сейчас считаю, что если мне это вдруг "НАДО" - значит, что-то не так )). Логика - штука хитрая. Красота выражения говорит о его правильности обычно. Так что лично я не буду возражать, если мне однажды все-таки придется "заморочиться с директивами".. smile.gif

Цитата(Unconnected @ 4.01.2011 15:05) *
Фухх, осилил) С многим сам сталкивался, вот например кажется такой код в С++
int k;
if (k=5) {...}

, и это компилировалось, насколько помню..
А вот это как раз очень жизненно. С одной стороны, этой ошибке подвержены практически все, кто переходит с Паскаля на Си. А с другой,
Цитата
только непонятно, в чем заключалось условие, в успешном присваивании?
- такая конструкция очень удобна и часто применяется. Значит она следующее: присваиваем k некоторое значение (конечно, там стоит обычно выражение из переменных или функций), и если оно ненулевое, то..
Забавно, что паскалисту (я говорю про начинающих, а не зрелых, которые осознают потребность такого даже в Паскале) такая конструкция совершенно чужда, он просто не мыслит в таких категориях )).

Offtop:
Это сообщение не увидело бы свет, если бы FF после крэша машины (блин, это меня уже напрягает, надо что-то делать) не восстановил практически полный его текст. За что ему спасибо! smile.gif


подправил, была опечатка..

Сообщение отредактировано: Lapp - 5.01.2011 15:28


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 5.01.2011 15:29
Сообщение #14


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Все Сиш-ные и Дельфийские замашки, основанные на хаках и бесконтрольном приведении типов придется забыть.

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

> Забавно, что паскалисту (я говорю про начинающих, а не зрелых, которые осознают потребность такого даже в Паскале) такая конструкция совершенно чужда, он просто не мыслит в таких категориях )).

А такая?


if (i := 5) <> 0 then begin
end;



--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 5.01.2011 15:59
Сообщение #15


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> for i in 1 .. 10 loop -- i вообще не описывается

А если написать так?
for i in 1 .. L.Count - 1 loop
то, надеюсь, будет использован знаковый тип? Вспомнился прикол, как некоторые брали word и материли "глючную дельфу", которая почему-то для пустого списка пыталась перебирать индексы от 0 до 65535.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 5.01.2011 17:08
Сообщение #16


Гость






Цитата
Вся отрисовка держится на бесконтрольной ретипизации.
Для крайних случаев (когда без этого уже совсем никак не обойтись) есть модуль Ada.Unchecked_Conversion, который позволяет привести любой тип к любому другому. Но слишком часто прибегать к его услугам (в смысле строить программу так, чтобы были сплошные преобразования типов, потому что "я сам знаю, как мне делать, почему меня компилятор ограничивает?") - это моветон.

Цитата
А если написать так?
for i in 1 .. L.Count - 1 loop
то, надеюсь, будет использован знаковый тип?

Прикрепленное изображение
Еще сомневаешься?
 К началу страницы 
+ Ответить 
TarasBer
сообщение 5.01.2011 20:24
Сообщение #17


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Я посмотрю, что ты скажешь, когда Ада заставит тебя вместо

Мда, я представил для SendMessage... Ну для самый частых функций ещё обёртку можно сделать, проглатывающую возвращаемое значение. Кстати, инлайн-функции там есть?

> Но слишком часто прибегать к его услугам (в смысле строить программу так, чтобы были сплошные преобразования типов, потому что "я сам знаю, как мне делать, почему меня компилятор ограничивает?") - это моветон.

А мне, кроме графического модуля, нигде и не надо.
В Д7 я ещё делал наглые преобразования к типу, с которым работает некоторая структура, но это от отсутствия генериков.

> Еще сомневаешься?

Тогда нормально.
А вместо диапазона писать название перечислимого типа можно?
for i in TMyType do...
А то так запарило в одном месте для 3 разных типов писать

var
imt: TMyType;
...
for imt := Low(TMyType) to High(TMyType) do...



Что ещё не хватало в Дельфи.
А, контроль вариантных полей во время выполнения (во время компиляции, увы, никак).


type
TMyRec = record
case Selector: byte of
0: b: array [0 .. 9] of byte;
1: w: array [0 .. 4] of word;
end;
end;
...
r.Selector := 0;
r.w[0] := 1; // чтобы тут выдавало ошибку выполнения (потому что поле относится к другому значению селектора),
// разумеется, при включённых флагах компиляции



--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 5.01.2011 21:29
Сообщение #18


Гость






Цитата
А вместо диапазона писать название перечислимого типа можно?
Легко...
Прикрепленное изображение
Будет перебираться весь тип, от самого первого до самого последнего значения, и всего делов. Обрати внимание, для того чтобы напечатать идентификатор элемента, достаточно сделать MyType'Image. Это тоже встроено в язык, не нужны никакие Дельфийские шаманства с RTTI.

Цитата
А, контроль вариантных полей во время выполнения (во время компиляции, увы, никак).

Увы - это ты про Дельфи? smile.gif Вот это что-ли?
Прикрепленное изображение

(правда тут у тебя небольшой облом - селектор должен задаваться один раз, при инициализации переменной. Менять его ты не имеешь права. Задавать переменную без селектора - тоже). Но как доп. средство для контроля - пойдет.
 К началу страницы 
+ Ответить 
TarasBer
сообщение 5.01.2011 21:51
Сообщение #19


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Обрати внимание, для того чтобы напечатать идентификатор элемента, достаточно сделать MyType'Image.

Да, такую фичу я тоже хотел (типа чтобы Str(mt, S) писало в S имя mt), но так, в качестве баловства, серьёзного применения ей пока не вижу.
Image - это функция, возвращающая строку?

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

Это я на стадии компиляции должен указывать значение селектора?
Тогда что вообще дают такие вариантные записи?
Или всё это не обязательно?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 5.01.2011 22:47
Сообщение #20


Гость






Ну, максимум что можно предложить - это описать запись как "нелимитированную", то есть дать селектору значение по умолчанию, что позволит описывать экземпляр структуры без начального значения селектора, и, следовательно, разрешит менять селектор в рантайме. Только менять его можно будет только вот таким образом:
Прикрепленное изображение
(то есть, в агрегате должны присутствовать все поля, связанные с данным селектором. Как видишь, это очень просто делается. А потом - уже меняй любое нужное тебе значение. Если то, что ты меняешь недоступно при установленном в настоящий момент селекторе, вылетит CONSTRAINT_ERROR).
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 5.10.2024 0:12
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"