"global initialization failed" - page 2

 
James Cater:

I'm using TimeLocal to measure the exact time from startup. I'm not interested in the Server time and it really doesn't need to be adjusted.

GetMicroSeconds() already gives you exact time from startup.

Anyway TimeLocal() is certainly not the problem, but the call the ChartXXX() function when the chart is not yet open.

 
Alain Verleyen:

GetMicroSeconds() already gives you exact time from startup.

Anyway TimeLocal() is certainly not the problem, but the call the ChartXXX() function when the chart is not yet open.

Doesn't the window /chart get opened before any of the indicators are loaded ?

I'll test this with some print statements


Is there documentation anywhere showing the order of initialisation ?

 
James Cater:

Doesn't the window /chart get opened before any of the indicators are loaded ?

I'll test this with some print statements


Is there documentation anywhere showing the order of initialisation ?

I don't think it's documented. From my experience, you can't rely on anything to be initialized/open at Global Initialization time. And I almost sure they changed such things without any warning.
 
Alain Verleyen:
I don't think it's documented. From my experience, you can't rely on anything to be initialized/open at Global Initialization time. And I almost sure they changed such things without any warning.

I will be changing all my global variables to be simple types or pointers to classes, and delay the initialisation of said objects until the first few lines of OnInit()

Who knows how the order changes when they prepare the product for the end user addling encryption and licensing checks as part of the market deployment.


For what it's worth the ChartGetInteger methods do appear to work before OnInit when running standard exes

#property strict
#property indicator_chart_window

int TestStartup()
{
   int desktopScreenDpi = TerminalInfoInteger(TERMINAL_SCREEN_DPI);
   int chartScale = (int)ChartGetInteger(0, CHART_SCALE);

   Print("TestStartup :  desktopScreenDpi=", desktopScreenDpi, " chartScale=", chartScale);
   
   return chartScale;
}

int  ExtDummy = TestStartup();


int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   return rates_total;
}
 
James Cater:

Is there documentation anywhere showing the order of initialisation ?

This is the closest I've seen: 

Right after a program is attached to a chart, it is uploaded to the client terminal memory, as well as global variable are initialized. If some global variable of the class type has a constructor, this constructor will be called during initialization of global variables.

After that the program is waiting for an event from the client terminal.

 
Alain Verleyen: I don't think it's documented. From my experience, you can't rely on anything to be initialized/open at Global Initialization time. And I almost sure they changed such things without any warning.
Global Variables - Variables - Language Basics - MQL4 Reference and Static Variables - Variables - Language Basics - MQL4 Reference
A global variable can be initialized only by a constant or constant expression that corresponds to its type.

The compiler should flag non-constant expressions, but doesn't, and some work sometimes.

If they are constant expressions the order doesn't matter. If one depends on another, you can't do it. Class constructors must be split, constant construction and then an initialization method called in OnInit, then anything else that depends on account or chart info done in OnTick.

Alternate is to new the class pointer in OnInit or OnTick, delete in OnDeinit, where you can control the ordering.

 
whroeder1:
Global Variables - Variables - Language Basics - MQL4 Reference
The compiler should flag non-constant expressions, but doesn't, and some work sometimes.

Yes, that certainly isn't enforced by the compiler, and in most cases system calls and calls to non market data have worked. They even work now with standard ex4 (ex4 unchanged by the deployment process)

Thanks for finding this quote, it certainly gives them a get-out clause when breaking compatibility. It's now clear that we need a two step initialisation for some global variables.

The support team have asked me to rebuild our code with the latest compiler. I will find out if that helps with the recent platform changes shortly.

Also, it would be good to get some feedback from MetaQuotes about this.
 
whroeder1:
 

Alternate is to new the class pointer in OnInit or OnTick, delete in OnDeinit, where you can control the ordering.

Indeed this does appear to be the only way. However it's a bit rich considering they use class constructors in the examples honest_knave gave two posts back.

 

UPDATE 1: Metaquotes asked us to compile our ex4 with an up to date MetaEditor (build 1559) and release a new version to market. We did this but it did not resolve the issue

UPDATE 2: Metaquotes have updated their demo server to 4.00 build 1065 and this release does appear to resolve the issue.


Once 1065 is out in the wild we intend to re-release our indicators with the changes discussed in this post. It will be interesting to see if using constant global variables fixes this issue for the older (1045) builds

 

UPDATE 3:

We changed all the global variables to constants and all the global classes to pointers and initialised them in OnInit(). We then released a new version to the market.

Sadly this did not resolve the issue. This suggests that this might be a MT4 platform regression and not the global variables.

The fact that build 1065 suddenly works with all the indicators again also hints at a platform regression rather than a coding issue.

I'm not sure we'll ever be able to say what really caused this.

Thanks for all your assistance everyone

Reason: