Warning! - page 2

 
nicholish en:

You mentioned that C lang uses files as a namespace. C uses namespaces as namespaces, contrary to something like python that uses the files themselves are literal namespaces and you can access attribute such as file.variable. Nonetheless, the use of non-const global variables is a code smell that can be avoided with better design.

I said "like namespace". I mean the C language respect the scope of file. Sometimes you just want to write a simple code and you want to use a lot of global variables. It's up to the programmer. Global variables are good if you know how to use it and the subject is not about how to use global variables.

The way MQL language mixes everything is a big problem because the more the project gets bigger the more the possibility to encounter name conflicts.


If you don't agree try to compile the following code. It's a const global variable as you like.


#include <Trade/Trade.mqh>

const int fmt = 1;

void OnStart(){}


Now, am I a bad designer? 

The Trade.mqh is from MetaQuotes. Suppose I include 10 different libraries and each library includes 10 different libraries and ... .  See it's growing fast 10x10x10x... Now each library has 100 functions and each function declare 10 local variables. The way MQL works is wrong because with this assumption the compiler warns me not to use more than 1000000000 (one billion) names.


William Roeder:
MQLn is not C and it is not C++. Adjust to it.
Should I Adjust to it or try to report the problem?
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
//| Expert initialization function                                   | //| Expert deinitialization function                                 | //| Expert tick function                                             | //| test1                                                            |...
 
declaration of 'fmt' hides global variable      Trade.mqh       1665    11

You should be thankful that such WARNING exists.

I bet you never bother to have a look inside Trade.mqh.

When you declare global consts and/or variables, then as you know too, such globals are visible anywhere.

The compiler WARNS you, in that case, so that you can verify if the conflict might cause unintended side-effects due to name collisions.

The compiler is SMARTER that most developers in deciding which const/variable to use.

But since the compiler is not willing to act like a SMART*SS, not knowing what a sloppy developer's intention, it simply WARNS him/her.

Rename your global variable to avoid the conflict, or rewrite Trade.mqh or choose not to use it at all.

As simple as that.

>> Know your tool then your experiences count.
-sef 2020

 

The solution is to wrap the import in a namespace, however, there appears to be a bug in the MQL linter and while it says it shadows the variable it does not. 

namespace Global {
   int fmt = 0;
   int res = 123433;
}

namespace Trade {
   #include <trade/trade.mqh>
}


void OnStart(){
   Trade::CPositionInfo pos;
   pos.SelectByMagic("EURUSD", Global::res);
}
 
Soewono Effendi:

You should be thankful that such WARNING exists.

I bet you never bother to have a look inside Trade.mqh.

When you declare global consts and/or variables, then as you know too, such globals are visible anywhere.

The compiler WARNS you, in that case, so that you can verify if the conflict might cause unintended side-effects due to name collisions.

The compiler is SMARTER that most developers in deciding which const/variable to use.

But since the compiler is not willing to act like a SMART*SS, not knowing what a sloppy developer's intention, it simply WARNS him/her.

Rename your global variable to avoid the conflict, or rewrite Trade.mqh or choose not to use it at all.

As simple as that.

>> Know your tool then your experiences count.
-sef 2020

Why do you bet? I won the bet.

A global variable shouldn't be accessed by an included file and that warning is because the compiler does a nasty thing in the first place. How should I explain this so everyone stop telling me ...?

I explained why this kind of name managing is not good for big projects.

I bet you never bother to understand what I'm talking about.
I bet every experienced compiler designer will agree with me.   

>> Understand what I'm talking about then tell me "know your tool then your experiences count."

 
Ehsan Tarakemeh:

Why do you bet? I won the bet.

A global variable shouldn't be accessed by an included file and that warning is because the compiler does a nasty thing in the first place. How should I explain this so everyone stop telling me ...?

I explained why this kind of name managing is not good for big projects.

I bet you never bother to understand what I'm talking about.
I bet every experienced compiler designer will agree with me.   

>> Understand what I'm talking about then tell me "know your tool then your experiences count."

No need to be so salty about it. I'm not saying it's the best design, but as others have pointed out MQL is its own language and the #include simple copy/pastas the code exactly how it is so if you do include other libraries you NEED a mechanism to tell you when you're shadowing variables. To be honest, I don't think this is a major issue for most developers since most devs prefer to not use globals and instead pass constants as parameters or use a class. In the rare event that I ever need a global then I always follow the common naming convention of adding a "g_" prefix. You wouldn't declare a class member without the "m_" prefix so globals should be treated in the same regard. 


That being said, you have discovered an annoying bug in the linter that needs to be addressed by MQ.

 
Ehsan Tarakemeh: Should I Adjust to it or try to report the problem?
PICNIC
 
William Roeder:
PICNIC

It is not user error. It is a bug in the linter/compiler. Here is a minimal reproducible example. 

namespace one {
int res = 0;
}

namespace two {
bool res = false;
}

void OnStart() {
   Print(one::res);
   Print(two::res);
}
 
nicholish en:

It is not user error. It is a bug in the linter/compiler. Here is a minimal reproducible example. 

they must be in the same type i think..


//--- hide it somewhere else from the compiler
extern int res = 0;

namespace One 
{
int res;

int returnres()
{
   res = 10;
   return(res);
}
}
namespace Two
{
int res;
int returnres()
{
   res = 11;
   return(res);
}
}
namespace Three
{
int res;
int returnres()
{
   res = 12;
   return(res);
}
}

namespace Four
{
#include <TestOne.mqh>

}


int OnInit()
  {


   Print(res);
   Print(One::returnres());
   Print(Two::returnres());
   Print(Three::returnres());
   Print(Four::returnres());
   res = One::returnres() + 5;
   Print("res is ",IntegerToString(res));
   
   return(INIT_SUCCEEDED);
  }


//|                                                      TestOne.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

int res;
int returnres()
{
   res = 20;
   return(res);
}
 
roshjardine:

they must be in the same type i think..


No.
Actually this is another bug.
When we define a namespace the philosophy is to use the same names in any way we like, otherwise why would we even call it a namespace.

Compile the codes in a C++ compiler, you won't get any errors or warnings.

 
Ehsan Tarakemeh:
No.
Actually this is another bug.
When we define a namespace the philosophy is to use the same names in any way we like, otherwise why would we even call it a namespace.

Compile the codes in a C++ compiler, you won't get any errors or warnings.

we are not discussing c++,python,java,c# and so on here.. and i am not interested in programming language debate..this is MQL