Features of the mql5 language, subtleties and tricks - page 151

 
fxsaber:

The static variable is initialized on the first call.

It's hard to guess why the developers did it, I think it's a bug - the initialization of a constant variable with an unknown value at compile time

That's how I usually check what and when to initialize it

//+------------------------------------------------------------------+
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


In my example, all initialized correctly and the compiler does not allow to assign further value to constant j - there will be a compilation error

 
Vladimir Simakov:

The problem is that it is not worth to use it in any case, because it is a conceptual error.

Well, it is not worth using it anyway, because it is a conceptual error.

 
Alexey Navoykov:

Well, you shouldn't use it anyway, as it's a conceptual error.

But why conceptual? On the contrary, sometimes you do not know what value to initialize static variable at compile time, initialization at first call helps.

 
Alexey Navoykov:

Well, don't use it anyway, as it's a conceptual error.

Implementation of MVS C++17:

Static local variables

Variables declared at block scope with the specifier staticorthread_local (since C++11) have staticor 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.

Personally I'm all for it, if such an implementation is legal in mql, just need to specify it in the docs.

 
Vladimir Simakov:

So why is it conceptual? On the contrary, sometimes you don't know what value to initialize a static variable with at compile time, it's the first-call initialization that helps.

So we need to initialize with a zero (default) value. And why initialize with the first encountered value? Then the function behavior is determined by the order of calls of this function, creating a side effect. And it's incorrect. If you want to initialize internals from outside, you'd better use a class, not a function.

However, I was actually wrong in saying that it can't compile. In C++ it works, oddly enough, although it never occurred to me to do such a thing.

 
Alexey Navoykov: In C++ it works, oddly enough, although it never occurred to me to do so.

It's always been like that there, no conceptual problems, the problems would be if it were otherwise

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

And the order of destruction is strictly the opposite.

 
Vict:

This has always been the case there, no conceptual problems, there would be problems if it were otherwise

Your example is a little different.
 
Slava:

After selecting the "Edit" context menu, the navigator cannot find the original mq5 in the same path as ex5.

Because ex5 has been moved to the scripts folder from Shared Projects, where mq5 lives

Will fix it. Let's make the same smart search as in tester settings

There is also an opposite situation. In Favorites Navigator, it's impossible to go to mq5-editing (mq5 is available) if ex5 is missing (there was a compilation error, for example). Please fix this too.

 
fxsaber:

There is also a reverse situation. In Favorites Navigator, it is impossible to switch to mq5-editing (mq5 is available) if ex5 is missing (there was a compilation error, for example). Please fix this too.

2250 is fine.

It has been hurried. 2251 - does not open mq5.

 
fxsaber:

2250 is fine.

Hurriedly. 2251 - does not open mq5.

Is it there? Do you have it? Which path is it on?

How can it be reproduced?

Reason: