Ask for help about code

 

Hi I am a beginner to learn mql4 programming. I meet a very simple problem but I don't know how to solve it. 

I wrote these codes already:


void SetLable(string LableName,string LableDoc,int LableX,int LableY,int DocSize,string DocStyle,color DocColor)

{

ObjectCreate(LableName,OBJ_LABEL,0,0,0);

ObjectSetText(LableName,LableDoc,DocSize,DocStyle,DocColor);

ObjectSet(LableName,OBJPROP_XDISTANCE,LableX);

ObjectSet(LableName,OBJPROP_YDISTANCE,LableY);

}



extern int DocSize=50;



int OnInit()

  {

SetLable("123","ABC",500,10,DocSize,"Verdana",Red);



SetLable("456","XYZ",500,30,DocSize,"Verdana",Blue);



   return(INIT_SUCCEEDED);

  }


When I compile it said "declaration of 'DocSize' hides global variable"

Actually I know where is the problem but I don't know how to destine the extern Docsize while there are two DocSize parameters.

Now I want to make two extern Docsize fields to adjust two labels size separately, how do I write the codes correctly ??



 
Just call them differently. The local is hiding the global. You can't have 2 variables named the same valid in the same scope. Also, when posting code, please use the "Insert code" button in the toolbar, it makes the text smaller and color-coded.
 
Comments that do not relate to this topic, have been moved to "Off Topic Posts".
 
Carlos Moreno Gonzalez #:
Just call them differently. The local is hiding the global. You can't have 2 variables named the same valid in the same scope. Also, when posting code, please use the "Insert code" button in the toolbar, it makes the text smaller and color-coded.

Yes that what I want to ask, How to call them differently?  what is the grammar or function I need to invoke ? 

 
butters #:

Yes that what I want to ask, How to call them differently?  what is the grammar or function I need to invoke ? 

What I meant is that you have to name the two variables differently. The issue is that you already have a variable called "DocSize" which is global, then in your function (which is also the scope of "DocSize" since it's a global variable) you declare another "DocSize" variable, local to the function, and that's why you're getting the error. All you have to do is change the name of either the global variable or the local one. For example this should suffice:

void SetLable(string LableName,string LableDoc,int LableX,int LableY,int size,string DocStyle,color DocColor) { // "DocSize" renamed to "size"
        ObjectCreate(LableName,OBJ_LABEL,0,0,0);
        ObjectSetText(LableName,LableDoc,size,DocStyle,DocColor); // "DocSize" renamed to "size"
        ObjectSet(LableName,OBJPROP_XDISTANCE,LableX);
        ObjectSet(LableName,OBJPROP_YDISTANCE,LableY);
}

Since you said you're a beginner, let me give you a couple of general tips:

  • Use some standard naming for your variables. There are some rules, but usually variables start with lowercase and functions start with uppercase. The compiler isn't going to throw any error, as far as I know, but it's just a convention most developpers follow. I'm saying this because you've named your function parameters i.e., "DocStyle" - that at first glance might suggest a function whereas "docStyle" might be more widely accepted as a variable name. Again, the compiler is gonna accept either name.
  • Use indentation and watch for unnecessary empty lines. It adds clarity to your code, and makes it nicer to the eye. For example:

void SetLable(string LableName,string LableDoc,int LableX,int LableY,int size,string DocStyle,color DocColor) {
        ObjectCreate(LableName,OBJ_LABEL,0,0,0);
        ObjectSetText(LableName,LableDoc,size,DocStyle,DocColor); // "DocSize" renamed to "size"
        ObjectSet(LableName,OBJPROP_XDISTANCE,LableX);
        ObjectSet(LableName,OBJPROP_YDISTANCE,LableY);
}

...versus...

void SetLable(string LableName,string LableDoc,int LableX,int LableY,int DocSize,string DocStyle,color DocColor)

{

ObjectCreate(LableName,OBJ_LABEL,0,0,0);

ObjectSetText(LableName,LableDoc,DocSize,DocStyle,DocColor);

ObjectSet(LableName,OBJPROP_XDISTANCE,LableX);

ObjectSet(LableName,OBJPROP_YDISTANCE,LableY);

}
 
Carlos Moreno Gonzalez #:

What I meant is that you have to name the two variables differently. The issue is that you already have a variable called "DocSize" which is global, then in your function (which is also the scope of "DocSize" since it's a global variable) you declare another "DocSize" variable, local to the function, and that's why you're getting the error. All you have to do is change the name of either the global variable or the local one. For example this should suffice:

Since you said you're a beginner, let me give you a couple of general tips:

  • Use some standard naming for your variables. There are some rules, but usually variables start with lowercase and functions start with uppercase. The compiler isn't going to throw any error, as far as I know, but it's just a convention most developpers follow. I'm saying this because you've named your function parameters i.e., "DocStyle" - that at first glance might suggest a function whereas "docStyle" might be more widely accepted as a variable name. Again, the compiler is gonna accept either name.
  • Use indentation and watch for unnecessary empty lines. It adds clarity to your code, and makes it nicer to the eye. For example:

...versus...

Thank you Carlos, I just figured it out before I saw your reply , but still very much informative. Let me show my code how I solve it

void SetLable(string LableName,string LableDoc,int LableX,int LableY,int DocSize,string DocStyle,color DocColor)
{
ObjectCreate(LableName,OBJ_LABEL,0,0,0);
ObjectSetText(LableName,LableDoc,DocSize,DocStyle,DocColor);
ObjectSet(LableName,OBJPROP_XDISTANCE,LableX);
ObjectSet(LableName,OBJPROP_YDISTANCE,LableY);
}




extern int DocSize1=50;
extern int DocSize2=50;


int OnInit()
  {
SetLable("123","ABC",500,10,DocSize1,"Verdana",Red);
SetLable("456","XYZ",500,50,DocSize2,"Verdana",Blue);

Because I copied these codes from other's for learning, so there are many things that I am not familiar with.

The reason why I made the mistake is that I thought the "DocSize" must be same in void SetLable and Setlable below , but actually it dones't need to be. The "int DocSize" simply means I give it a name called DocSize, it can be named anything such as WordSize or LetterSize ,it doesn't matter. And the DocSize1 or DocSize2 have their meaning while I invoke "extern" function, if I don't do that ,DocSize1 and DocSize must be an integer such as 30, 45, 84 or anyother digit.


So I have much understanding now, thanks.

 
butters #:

Thank you Carlos, I just figured it out before I saw your reply , but still very much informative. Let me show my code how I solve it

Because I copied these codes from other's for learning, so there are many things that I am not familiar with.

The reason why I made the mistake is that I thought the "DocSize" must be same in void SetLable and Setlable below , but actually it dones't need to be. The "int DocSize" simply means I give it a name called DocSize, it can be named anything such as WordSize or LetterSize ,it doesn't matter. And the DocSize1 or DocSize2 have their meaning while I invoke "extern" function, if I don't do that ,DocSize1 and DocSize must be an integer such as 30, 45, 84 or anyother digit.


So I have much understanding now, thanks.

Exactly. In other words, when you're calling a function with parameters in the call you're passing to the function a copy of those variables. If there are no scope issues the variables can be called the same, but that can lead to confusion. Usually you use something different, i.e.:

int OnInit() {
        short firstOperand  = 3;
        short secondOperand = 7;

        Print(CalculateProduct(firstOperand, secondOperand));
        return(INIT_SUCCEEDED);
}

short CalculateProduct(short a, short b) {
        return(a * b);
}

You could have used "firstOperand" and "secondOperand" instead of "a" and "b" in the function since the former variables are local, not global. However it can lead to doubt. Usually you'd see something like the above.

Reason: