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

> Внимание!

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

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

> Немного о синтаксисе и безопасности, языков программирования
сообщение
Сообщение #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
Только не надо говорить, что примеры-искусственные, и специально подобраны так, что Ада показана выигрышно. Попробуйте привести примеры, как избежать в С/С++ тех неоднозначностей, о которых я написал, чтобы дать возможность компилятору не пропустить ошибку или недочет программиста.

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


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

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

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


> и, следовательно, разрешит менять селектор в рантайме

Во, тогда нормально.

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

Да, этого я и хотел (но опять же, как отключаемую опцию компилятора).

Я понял, почему Image для перечислимых типов для меня бесполезен. Типы я перечисляю в коде на английском, сообщения для пользователя пишу на русском (возможность писать идентификаторы на русском не предлагать, запарюсь переключаться). Да, будь я носителем языка с латинницей, оценил бы эту возможность по достоинству.

Система типов интересная (я про Unsigned_8 итд), намного логичнее, чем long long long int и прочие нелепые названия.


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


Гость






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



Эскизы прикрепленных изображений
Прикрепленное изображение
 К началу страницы 
+ Ответить 
сообщение
Сообщение #23


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

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

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


Я нашёл в википедии забавный пример, который показывает, зачем в Си такой switch.
http://ru.wikipedia.org/wiki/Устройство_Даффа


strcpy(to, from, count)
register char *to, *from;
register count;
{
register n = (count + 7) / 8;
switch (count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
}



Правда, остаётся вопрос, зачем нужен этот пример.


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


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

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

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


Цитата(TarasBer @ 9.01.2011 13:53) *
зачем в Си такой switch.
Аму-дарьеть.. Я б сам ни в жизь не допер..


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


Гость






Цитата
остаётся вопрос, зачем нужен этот пример.
Чтоб огрести проблем с выходом новой редакции Стандарта (и новой версии компилятора, придерживающейся этой редакции).

Тема разделена: Настройка GPS (IDE для Ады)

Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #26


Гость






Из недавнего - просто вспомнилось (к вопросу о безопасности и контроле программиста над происходящим в программе)...

Все помнят такую особенности Дельфи / Object Pascal, как передачу объекта класса по ссылке, и к чему это приводит, да? Иллюстрация:

// есть вот такой класс
type
T = class
value : Integer;
constructor Create(AValue : Integer);
procedure Print;
end;

constructor T.Create (AValue : Integer);
begin
Inherited Create;
Value := AValue;
end;

procedure T.Print;
begin
writeln(value);
end;


// и вот такая процедура (полиморфная)
procedure DoSomething (Const Obj : T);
begin
Obj.Print;
Obj.value := 10; // <--- Изменение объекта
end;

// Используется вот так
var
Obj : T;
begin
Obj := T.Create(5);
Obj.Print;

DoSomething(Obj);

Obj.Print;
Obj.Free;
end.


Как вы думаете, что в данном случае означает Const? Неужели - то, что объкет класса нельзя изменить, и Дельфи мне выдаст ошибку компиляции или хотя бы аварийно завершит программу при попытке изменения объекта Obj? Да ничего подобного. Легко изменяется любое поле объекта, хоть напрямую, хоть через методы/свойства.

Это по меньшей мере нелогично. Если я передаю объект в процедуру с таким прототипом:
procedure DoSomething (Const Obj : T);
, я ожидаю, что объект не будет изменен. Дельфи мне этого обеспечить не может. В отличие от С++. Что делается в Аде? Тут как раз все в порядке:

(описание класса)
--  Specification file (ADS)
package MyObj is

type Root is tagged record
A : Integer;
end record;

procedure Print (Obj : Root);
procedure Set_Value (Obj : in out Root; Value : Integer);

end MyObj;

-- Body file (ADB)
with ada.Text_IO; use ada.Text_IO;

package body MyObj is

procedure Print (Obj : Root) is
begin
Put_Line (Integer'Image (Obj.A));
end Print;

procedure Set_Value (Obj : in out Root; Value : Integer) is
begin
Obj.A := Value;
end Set_Value;

end MyObj;


(основная программа)
   procedure Polymorphic (Obj : in MyObj.Root) is
begin
Obj.Print; -- Да пожалуйста, объект не будет изменяться
Obj.Set_Value (3); -- А вот тут - стоп !!! Это изменит объект
end Polymorphic;

, компиляция прекратится при попытке вызвать метод, модифицирующий Obj. Так что вот вам еще одна ступень защиты. Если же параметр Obj описать как in out, то есть, изменяемый - то и Set_Value прекрасно отработает.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #27


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

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

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


Эээ, а кто может обеспечить безопасность данных, передаваемых по указателю, даже если он передан с модификатором const?
Что касается классов, то в Дельфи класс - это указатель.
А в С++ просто классы сделаны как положено (да, мне С++ная концепция ООП нравится куда больше), а не в виде указателей, которые ещё и надо РУКАМИ удалять.
В Дельфи, чтобы передать содержимое, а не указатель, надо пользоваться не class, а object.
Короче, ООП от Борланда мне (из-за этого в том числе) стало казаться настолько неестественным, что я стал жёстко структурить, выдавая иногда перлы типа http://govnokod.ru/4249 или http://govnokod.ru/5261 (да, именно тут мне захотелось контроля обращения к вариантному полю в зависимости от знаения селектора).
Зато, я считаю, только после таких вещей начинаешь по-настоящему понимать смысл ООП, а не так, что дяди сказали, что ООП типо крута, а сам сидишь и лепишь его везде.


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


Гость






Цитата
Эээ, а кто может обеспечить безопасность данных, передаваемых по указателю, даже если он передан с модификатором const?
Хм. Значит, надо было отменять модификатор const, или доделывать его, чтоб он работал со всеми сущностями, а не отсылать программиста разбираться, является ли классом строка, и почему на нее спецификатор действует, а на другие классы - нет.

Тем более, что это возможно, как оказалось. В Аде объекты тоже не передаются по значению, однако если я заказал доступ только по чтению - то он таким и будет, и мне не надо волноваться, что мой объект будет изменен в результате.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #29


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

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

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


Забавно, но самый страшный баг был написан именно на Аде:

http://ru.wikipedia.org/wiki/Авария_ракеты...5_(4_июня_1996)


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


Гость






Блин... Это не проблема Ады. Есть посекундный анализ этой катастрофы, который показал, в чем на самом деле была проблема. Показать? Кому-то просто выгодно муссировать слухи, о том, что именно язык МО США дал такой сбой...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #31


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

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

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


> Есть посекундный анализ этой катастрофы, который показал, в чем на самом деле была проблема. Показать?

Да.

> Кому-то просто выгодно муссировать слухи, о том, что именно язык МО США дал такой сбой...

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


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


Гость






Цитата
Во всех официальных источниках обвиняется именно программное обеспечение.
Уточняю: во воех русскоязычных официальных источниках... Вот перевод отчета Комиссии по Расследованию: http://forums.airbase.ru/2007/03/t54337--a...shibk.2155.html

( на всякий случай - вот ссылка на англоязычный оригинал: http://homepages.inf.ed.ac.uk/perdita/Book/ariane5rep.html )

Что видим? А вот что:
Цитата
Было обосновано, что в случае события отмены старта период в 50 сек. после H0-9 будет достаточным для того, чтобы наземное оборудование смогло восстановить полный контроль за Инерциальной Платформой без потери информации – за это время Платформа прекратит начавшееся было перемещение, а соответствующий программный модуль всю информацию о ее состоянии зафиксирует, что поможет оперативно возвратить ее в исходное положение (напомним, что все это в случае, когда ракета продолжает находиться на месте старта). И действительно, однажды, в 1989 г., при старте под номером 33 ракеты Ariane 4, эта особенность была с успехом задействована.

Однако, Ariane 5, в отличие от предыдущей модели, имел уже принципиально другую дисциплину выполнения предполетных действий – настолько другую, что работа рокового программного модуля после времени старта вообще не имела смысла. Однако, модуль повторно использовался без каких-либо модификаций – видимо из-за нежелания изменять программный код, который успешно работает.

<...>

Расследование показало, что в данном программном модуле присутствовало целых семь переменных, вовлеченных в операции преобразования типов. Оказалось, что разработчики проводили анализ всех операций, способных потенциально генерировать исключение, на уязвимость. И это было их вполне сознательным решением добавить надлежащую защиту к четырем переменным, а три – включая BH – оставить незащищенными. Основанием для такого решения была уверенность в том, что для этих трех переменных возникновение ситуации переполнения невозможно в принципе. Уверенность эта была подкреплена расчетами, показывающими, что ожидаемый диапазон физических полетных параметров, на основании которых определяются величины упомянутых переменных, таков, что к нежелательной ситуации привести не может. И это было верно – но для траектории, рассчитанной для модели Ariane 4. А ракета нового поколения Ariane 5 стартовала по совсем другой траектории, для которой никаких оценок не выполнялось. Между тем она (вкупе с высоким начальным ускорением) была такова, что "горизонтальная скорость" превзошла расчетную (для Ariane 4) более чем в пять раз.

Но почему же не была (пусть в порядке перестраховки) обеспечена защита для всех семи, включая BH, переменных? Оказывается, для компьютера IRS была продекларирована максимальная величина рабочей нагрузки в 80%, и поэтому разработчики должны были искать пути снижения излишних вычислительных издержек. Вот они и ослабили защиту там, где теоретически нежелательной ситуации возникнуть не могло. Когда же она возникла, то вступил в действие такой механизм обработки исключительной ситуации, который оказался совершенно неадекватным.

Этот механизм предусматривал следующие три основных действия. Прежде всего, информация о возникновении нештатной ситуации должна быть передана по шине на бортовой компьютер OBC; параллельно она – вместе со всем контекстом – записывалась в перепрограммируемую память EEPROM (которую во время расследования удалось восстановить и прочесть ее содержимое), и наконец, работа процессора IRS должна была аварийно завершиться. Последнее действие и оказалось фатальным – именно оно, случившееся в ситуации, которая на самом деле была нормальной (несмотря на сгенерированное из-за незащищенного переполнения программное исключение), и привело к катастрофе.


Итого: недостаток вычислительной мощности, из-за которого программисты осмысленно снимают защиту (что в результате приводит к сбою) - это проблема языка? Нет. То, что траектория Ариан-5 не оценивалась во всей серьезностью, а кто-то положился на то, что все будет так же, как и в Ариан-4 - это что, проблема Ады? Нет. В чем же тогда обвиняют язык? В том, что кто-то неизвестно почему не мог усилить процессоры? В том, что не было выделено средств на тестирование баллистических характеристик? В том, что кто-то вообще не дал программистам просмотреть код, чтоб не платить им, а заявил, что будет использоваться прекрасно показавшая себя в прошлом проекте часть? Почему Ада виновата?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #33


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

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

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


> Итого: недостаток вычислительной мощности, из-за которого программисты осмысленно снимают защиту (что в результате приводит к сбою) - это проблема языка?

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


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 





- Текстовая версия 11.05.2024 2:37
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name