По поводу надежности ПО. Exception handling = must have - страница 4

 
kombat :

Снова возвращась к "проблеме" деления на 0.

(т.н.  zero divide )

 

Неужели это принципильное условие???

Вот сегодня, из-за частого появления случаев в параметрах 0 пришлось лопатить

и уж простите тулить лажу... иного слова не знаю... если на 0.00000001 можно, а на 0 нельзя.

Ну и пусть себе вместо истиного расчёта всё тот-же 0, чем галиматью в виде например бешеных процентов...

 

 

 

ИЕ. 

 

 

 

 


Я извиняюсь, форум глючит, не даёт добавить кусок кода...

 

Повторяюсь, если же нужно возвращать 0 в случае 'нехорошего' делителя, то можно использовать, например, такую функцию:

 

double div(double a, double b, double e = 1e-8)
{
  return MathAbs(b) < e ? 0 : a / b; /* Люблю условные выражения за их выразительность!!! */
}

А когда введут перегрузку операторов, то можно будет, реализовав свой класс для 'трюкового' double и перегрузив для него операцию "/" с реализацией, подобной реализации вышеприведённой функции div(), вернуться к обычному использованию "/" для операции деления, 'автоматически' имея тот же трюк для 'нехорошего' делителя. Правда, это зависит от того, как введут перегрузку операторов. Будем надеяться, не испортят ничего.

 

2 simpleton


Да, признаю, что векторный вызов нисколько не усложняет использование исключений.


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


Деструктор для объекта в конструкторе которого произошло исключение НЕ ВЫЗЫВАЕТСЯ!


ЗЫ Будте осторожнее в ваших C++ проектах.

 

Господа,


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


Мы сделали MQL5 достаточно простым и явным образом ограничили возможности, чтобы язык не стал опасным.


С задачей справились успешно.

 
mql5 :

2 simpleton


Да, признаю, что векторный вызов нисколько не усложняет использование исключений.


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


Деструктор для объекта в конструкторе которого произошло исключение НЕ ВЫЗЫВАЕТСЯ!


ЗЫ Будте осторожнее в ваших C++ проектах.



Точнее по смыслу - объект считается несконструированным, если конструктор не вернул управление естественным образом.

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


И конструктор поэтому должен писаться с расчётом на то, что, если в конце его работы что-то случилось, и надо выбрасывать исключение, конструктор сам должен отменить всё, что он успел наконструировать вначале своей работы (память, прежде выделенную, освободить, ещё, что-нибудь, - но только для своего подобъекта).


Язык C++ - большой и сложный, его долго и досконально надо изучать, на практике выясняя и уточняя многие вопросы, прежде чем получится грамотно его использовать. Поэтому и заимствовать из C++ для C++-подобного языка надо очень осторожно и аккуратно.


Renat :

Господа,


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


MQL5 не выглядит "заточенным" под разработку торговых стратегий. Под разработку торговых стратегий заточена библиотека функций.

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

"Эксепшены" сложны в реализации компилятора, а не в применении программистом. И опасности не представляют, если реализованы как следует.


Renat :

Мы сделали MQL5 достаточно простым и явным образом ограничили возможности, чтобы язык не стал опасным.


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


Renat :


С задачей справились успешно.


С частью задачи справились успешно. Но часть дизайна имеет изъян. А дизайн - это основа.

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


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

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

Причём, ещё более худший случай, чем конструкторы/деструкторы.


a = b + c + d;


Как сообщить о том, что при перегруженной операции "сложения", скажем, 'b' и 'c' произошла ошибка, невыразимая в виде результата операции?

А ведь потом надо ещё и "складывать" с 'd'. И выражения могут быть посложнее.

Попытки обойти проблему с помощью зарезервированных "специальных" значений не всегда могут быть применимы.

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


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

Иначе получим корявый недоделанный язык. Те способы, которыми пользователи будут изобретать для обхода корявостей, думаю, явно не обрадуют разработчиков.


Кстати, в языке C подобных автоматизмов нет, поэтому он и не нуждается в механизме обработки исключений.

 

А кто вообще сказал, что будет перегрузка операторов?


Специально проверил - никто из наших сотрудников про это не писал и не говорил. Только Вы.


В специальном разделе описания MQL5: Перегрузка явно написано:


Перегрузка

В пределах одного класса можно определить два или более методов, которые совместно используют одно и тоже имя, но имеют разное количество параметров. Когда это имеет место, методы называются перегруженными, а о процессе говорят как о перегрузке метода. Перегрузка метода – один из способов, с помощью которых реализуется полиморфизм. Перегрузка методов в классах производится по тем же правилам, что и перегрузка функций.

Если для вызываемой функции нет точного соответствия, то компилятор производит поиск подходящей функции по трем уровням последовательно:

1.поиск среди методов класса;
2.поиск среди методов базовых классов, последовательно от ближайшего предка до самого первого;
3.поиск среди остальных функций.

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


В MQL5 нет перегрузки операторов.


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


Именно это было задумано и реализовано.

 
Renat :

А кто вообще сказал, что будет перегрузка операторов?


Специально проверил - никто из наших сотрудников про это не писал и не говорил. Только Вы.


В специальном разделе описания MQL5: Перегрузка явно написано:


Перегрузка

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

Если для вызываемой функции нет точного соответствия, то компилятор производит поиск подходящей функции по трем уровням последовательно:

1.поиск среди методов класса;
2.поиск среди методов базовых классов, последовательно от ближайшего предка до самого первого;
3.поиск среди остальных функций.

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


В MQL5 нет перегрузки операторов.


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


Именно это было задумано и реализовано.


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

Однако, что-то мне подсказывает, что этого сделано не будет. 

 

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

Базовая, кстати, вещь. Вы, когда в следующий раз говорить о 15-20 годах опыта будете, вспомните об этой досадной процитированной ошибке из документации.

 

Найден bug в инициализации/деинициализации классов:


/******************************************************************************/
string s = "'Start' ";

/******************************************************************************/
class A { public: A()  { s += "'A()' "; } ~A() { s += "'~A()' "; } };

/******************************************************************************/
class B { public: B()  { s += "'B()' "; } ~B() { s += "'~B()' "; } };

/******************************************************************************/
class C { public: C()  { s += "'C()' "; } ~C() { s += "'~C()' "; } };

/******************************************************************************/
class D: public C { private: A a; B b; public: D()  { s += "'D()' "; } ~D() { s += "'~D()' "; } };

/******************************************************************************/
int OnInit() {  { D d; } Print(s + "'end'."); return 0; }


На закладке Experts имеем: 'Start' 'C()' 'A()' 'B()' 'D()' '~D()' '~A()' '~B()' '~C()' 'end'.

Вместо правильного:           'Start' 'C()' 'A()' 'B()' 'D()' '~D()' '~B()' '~A()' '~C()' 'end'.

 

Кстати, для чего конструктор - без параметров?

Обычно информация о том, чем инициализировать создаваемый экземпляр объекта, имеется в момент создания этого экземпляра.

Но нет способа передать эту информацию в конструктор.

 

Верно ли моё предположение, что конструктор без параметров - для того, чтобы сохранить язык MQL5 безопасным?

Forward декларации не реализованы - с той же целью?

 
simpleton :


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

Уверен, что в Вашем собственном языке у Вас будет полное право исключать собственные "изъяны".


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

Базовая, кстати, вещь. Вы, когда в следующий раз говорить о 15-20 годах опыта будете, вспомните об этой досадной процитированной ошибке из документации.

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


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


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


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


 

Найден bug в инициализации/деинициализации классов:


Спасибо за сообщение - с багом будем разбираться днем.


Верно ли моё предположение, что конструктор без параметров - для того, чтобы сохранить язык MQL5 безопасным?

Forward декларации не реализованы - с той же целью?

Лично я не вижу проблем с параметрами в конструкторе. Чуть позже выясню, по какой причине отклонили параметры.


Форвардные декларации работали некоторое время назад, но в очередном билде мы начали использовать двупроходный алгоритм компиляции, что не будет требовать предварительных описаний. На текущий момент (если я не ошибаюсь) заглушка "форвардные описания не поддерживаются" уже стоит, а вот учет второго прохода еще не применяется. Это мы доделаем до нормального состояния.

 
simpleton :

Найден bug в инициализации/деинициализации классов:

Спасибо за сообщение, ошибку исправили. Ждите обновлений.
 
Renat :


Уверен, что в Вашем собственном языке у Вас будет полное право исключать собственные "изъяны".


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


Renat :


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


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


Если вырвать из контекста фомулировку и иметь ввиду сигнатурный полиморфизм, который "можно устроить", то, вроде бы, действительно правда.


Однако по ссылке находится описание и примеры отнюдь не сигнатурного полиморфизма, а того, который в англоязычной литературе именуется как "inheritance polymorphism" (другие названия - "subtype polymorphism").

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


Не проще ли не запутывать неискушённого в тонкостях ООП пользователя, коими являются большинство пользователей MT4/MT5, а исправить документацию, назвав полиморфизмом тот, который inheritance, а перегрузкой функций - тот, который signature-based, и не ссылаться нигде в документации со странички, где речь идёт о перегрузке функций, на страничку о полиморфизме, при этом имея ввиду всё-таки перегрузку функций?


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


Renat :


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


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


Тут дело не совсем в чистоте формулировок.

В данном случае "лирическое отступление" о сигнатурном полиморфизме в документации оформлено так, что вводит в заблужение.


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


Сильно сомневаюсь, что одной ошибки достаточно, чтобы вылететь с рынка - слишком большой запас накоплен.

Даже если стараться вылететь, так просто это не получится хотя бы за счёт инерции.

Люди уже привыкли к платформе, и распространена она очень широко.


Renat :

Форвардные декларации работали некоторое время назад, но в очередном билде мы начали использовать двупроходный алгоритм компиляции, что не будет требовать предварительных описаний. На текущий момент (если я не ошибаюсь) заглушка "форвардные описания не поддерживаются" уже стоит, а вот учет второго прохода еще не применяется. Это мы доделаем до нормального состояния.


Это - хорошо. А то дошло до того, что люди уже изобретают способы, как обойти отсутствие forward деклараций.


Renat :

Спасибо за сообщение - с багом будем разбираться днем.


Ещё один, как раз связанный с полиморфизмом типа inheritance (пока что bug'и удаётся относительно легко находить):


/******************************************************************************/
string s = "'Start' ";

/******************************************************************************/
class A { public: A() { s += "'A(), expected call to A::f():' "; f(); }
                 ~A() { s += "'~A(), expected call to A::f():' "; f(); }
                 virtual void f(void) { s += "'A::f()' "; } };

/******************************************************************************/
class B: public A { public: B() { s += "'B(), expected call to B::f():' "; f(); }
                           ~B() { s += "'~B(), expected call to B::f():' "; f(); }
                           void f(void) { s += "'B::f()' "; } };

/******************************************************************************/
int OnInit() {  A *a = new B; delete a; Print(s + "'end'."); return 0; }


На закладке Experts имеем:


'Start' 'A(), expected call to A::f():' 'A::f()' 'B(), expected call to B::f():' 'B::f()' '~B(), expected call to B::f():' 'B::f()' '~A(), expected call to A::f():' 'B::f()' 'end'.


В деструкторе ~A() "надобъекта" 'B' уже "нет", однако из деструктора ~A() вызывается B::f().

Polymorphism (computer science) - Wikipedia, the free encyclopedia
  • en.wikipedia.org
In programming languages and type theory, polymorphism (from Greek πολύς, polys, "many, much" and μορφή, morphē, "form, shape") is the provision of a single interface to entities of different types.1 A polymorphic type is a type whose operations can also be applied to values of some other type, or types.2 There are several fundamentally...
 

Как я вижу, Вам нравятся игры в теоретические формулировки.


У нас написано все верно и достаточно полно. Если не хватает одной книги, то нужно идти и читать еще еще 10 книг, чтобы получить обзорное представление, а не пытаться требовать от одной книги раскрытия всех точек зрения. Для раскрытия темы к услугам сотни книг по С/C++ языкам в каждом книжном магазине.


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


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

Причина обращения: