Скачать MetaTrader 5

Баг со статическими переменными

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Alexey Navoykov
3996
Alexey Navoykov 2016.11.22 06:46 

Просьба разработчиков прокомментировать ситуацию с заявкой в СД #1533350, поданную ещё в августе (а фактически я писал о ней на форуме ещё раньше).  В СД я получил от вас лишь какую-то отписку, свидетельствующую о том, что в проблему даже не вникали. А все дальнейшие мои посты остались без ответа.

На всякий случай, продублирую эту ситуацию тут.  Речь идёт о некорректном поведении статических переменных - объектов класса.

class A  { public:
            int m;
            A() { Print("Constructor A");  m=1; }
         };

class B  { public:
            B() { Print("Constructor B");  static A a;  Print("a.m==",a.m); }
         };
B b;

void OnStart()
{
};

 В логе получаем:

Сonstructor B
a.m==0

Constructor A 

Создание статического объекта А происходит после того, как к нему было обращение, хотя объект объявлен раньше по коду.  Такое поведение помимо того что нарушает логику алгоритма, так ещё и приводит непредсказуемым последствиям, которые невозможно предугадать ни на стадии компиляции, ни в процессе выполнения.  Фактически в A::m мог содержаться любой мусор, если объект ещё не создан.

Вот что мне ответили в СД:

Спасибо за сообщение. Принципиально, работу со статическими переменными изменять не планируем. Различие в их инициализации с С++, сохранится, в MQL, все статические переменные будут по прежнему инициализироваться на загрузке программы, а не при первом использовании внутри функции.

Но это явно противоречит тому, что мы видим по факту. Ведь при загрузке программы статическая переменная A a не инициализировалась, конструктор для неё не запускался.
Ситуация не меняется также если объявить конструктор в таком виде:

A() : m(1) { Alert("Constructor A"); }


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

A100
3939
A100 2016.11.22 14:47  
Alexey Navoykov:

Вот что мне ответили в СД:

Спасибо за сообщение. Принципиально, работу со статическими переменными изменять не планируем. Различие в их инициализации с С++, сохранится, в MQL, все статические переменные будут по прежнему инициализироваться на загрузке программы, а не при первом использовании внутри функции.

Странно при том, что если вместо A -> int, то все нормально

class B { public:
        B();
        int i;
};
B::B()
{
static int ii = 5;
        i = ii;
}
static B b;
void OnStart()
{
        Print( b.i ); //результат: 5 (а не 0 как выше)
}
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий