Особенности языка mql5, тонкости и приёмы работы - страница 151

 
fxsaber:

Инициализация static-переменной идет на первом вызове.

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

я обычно так проверяю что и когда инициализируется

//+------------------------------------------------------------------+
void OnStart()
{
   f(333);
   f(2);
}
//+------------------------------------------------------------------+
int init_static()
{
   Print(__FUNCTION__);
   return(1);
}

void f( const int i )
{
  static const int j = init_static();
  
  Print(__FUNCTION__," , j =",j);
}

2019.11.30 11:09:32.456 tst (EURUSD,H1) init_static

2019.11.30 11:09:32.457 tst (EURUSD,H1) f , j =1

2019.11.30 11:09:32.457 tst (EURUSD,H1) f , j =1


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

 
Vladimir Simakov:

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

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

 
Alexey Navoykov:

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

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

 
Alexey Navoykov:

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

Реализация MVS C++17:

Static local variables

Variables declared at block scope with the specifier staticor thread_local (since C++11) have static or thread (since C++11) storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.

If the initialization throws an exception, the variable is not considered to be initialized, and initialization will be attempted again the next time control passes through the declaration.

If the initialization recursively enters the block in which the variable is being initialized, the behavior is undefined.

If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once (similar behavior can be obtained for arbitrary functions with std::call_once).

Note: usual implementations of this feature use variants of the double-checked locking pattern, which reduces runtime overhead for already-initialized local statics to a single non-atomic boolean comparison.

(since C++11)

The destructor for a block-scope static variable is called at program exit, but only if the initialization took place successfully.

Function-local static objects in all definitions of the same inline function (which may be implicitly inline) all refer to the same object defined in one translation unit.

Лично я только за, если подобная реализация законна в mql, только в доках надо прописать.

 
Vladimir Simakov:

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

Значит надо инициализировать нулевым (дефолтным) значением.  А зачем инициализировать первым попавшимся значением?  Тогда выходит, что поведение функции определяется порядком вызовов этой функции, создавая побочный эффект. А это неправильно.   Если требуется инициализировать внутренности извне, то надо использовать класс, а не функцию.

Однако я действительно ошибся, утверждая, что это не может компилироваться.  В С++ это работает, как ни странно, хотя мне никогда и в голову не приходило такое делать.

 
Alexey Navoykov:В С++ это работает, как ни странно, хотя мне никогда и в голову не приходило такое делать.

Там всегда так было, никаких концептуальных проблем, проблемы бы были, если бы было иначе

void fn() {
   static int i = fn_from_other_cpp();
}

А порядок разрушения строго обратный.

 
Vict:

Там всегда так было, никаких концептуальных проблем, проблемы бы были, если бы было иначе

Ваш пример немного из другой оперы.
 
Slava:

После выбора контекстного меню "Редактировать" навигатор не может найти исходный mq5 по тому же самому пути, что и ex5.

Потому что ex5 был перемещён в папку скриптов из Shared Projects, где живёт mq5

Исправим. Сделаем такой же интеллектуальный поиск, что и в настройках тестера

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

 
fxsaber:

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

2250 - отлично.

Поторопился. 2251 - не открывает mq5.

 
fxsaber:

2250 - отлично.

Поторопился. 2251 - не открывает mq5.

А он есть? Точно есть? По какому пути?

Как можно воспроизвести?

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