Download MetaTrader 5

Mysterious Unbalanced Left Parenthesis error

To add comments, please log in or register
Write your articles using our editor. It is convenient!
TheLobos
70
TheLobos 2016.04.13 08:37 

Either I'm going blind or something mysterious is going on. Can someone see what I'm doing wrong here?

 

  1. int subMACrossDirection (double fastMaValue, double slowMaValue, int &prevDirection, int &currDirection)
  2. {
  3.     fastMaValue = ND(fastMaValue);
  4.     slowMaValue = ND(slowMaValue);
  5.    
  6.     if (fastMaValue < slowMaValue) {
  7.         currDirection = DIRECTION_DOWN;
  8.     } else if (fastMaValue > slowMaValue) {
  9.         currDirection = DIRECTION_UP;
  10.     } else {
  11.         currDirection = prevDirection;
  12.     }
  13.    
  14.     // COMPILER TELLS ME THAT ON THIS LINE THERE IS AN
  15.     // 1) UNBALANCED LEFT PARENTHESIS
  16.     // 2) UNEXPECTED TOKEN ')'
  17.     if (prevDirection == DIRECTION_NONE) {
  18.         prevDirection = currDirection;
  19.         return DIRECTION_NONE;
  20.     }
  21.    
  22.     if (prevDirection != currDirection) {
  23.         prevDirection = currDirection;
  24.         return currDirection;
  25.     }
  26.    
  27.     return DIRECTION_NONE;
  28. }

Thanks for any tips and insights.

 

Donald Gibson
498
Donald Gibson 2016.04.13 09:17  
TheLobos:

Either I'm going blind or something mysterious is going on. Can someone see what I'm doing wrong here?

 

  1. int subMACrossDirection (double fastMaValue, double slowMaValue, int &prevDirection, int &currDirection)
  2. {
  3.     fastMaValue = ND(fastMaValue);
  4.     slowMaValue = ND(slowMaValue);
  5.    
  6.     if (fastMaValue < slowMaValue) {
  7.         currDirection = DIRECTION_DOWN;
  8.     } else if (fastMaValue > slowMaValue) {
  9.         currDirection = DIRECTION_UP;
  10.     } else {
  11.         currDirection = prevDirection;
  12.     }
  13.    
  14.     // COMPILER TELLS ME THAT ON THIS LINE THERE IS AN
  15.     // 1) UNBALANCED LEFT PARENTHESIS
  16.     // 2) UNEXPECTED TOKEN ')'
  17.     if (prevDirection == DIRECTION_NONE) {
  18.         prevDirection = currDirection;
  19.         return DIRECTION_NONE;
  20.     }
  21.    
  22.     if (prevDirection != currDirection) {
  23.         prevDirection = currDirection;
  24.         return currDirection;
  25.     }
  26.    
  27.     return DIRECTION_NONE;
  28. }

Thanks for any tips and insights.

 

 

try return(DIRECTION_NONE);

 docs.mql4.com/basis/operators/return

Fernando Carreiro
2349
Fernando Carreiro 2016.04.13 09:23  

When there are unbalance parenthesis, the MetaEditor compiler will incorrectly identify its position most of the time. It will often say its at A when in reality it is somewhere else at B. This is most often the case when there is a mix of unbalance of different types of parenthesis; such as using "(}" or "{)".

In this case, the code you have provided is not the culprit and the error may actually be in the function before or after it.

What you can try, in order to narrow down the correct place of the error is to first make a backup copy of the file, and then delete entire sections of the code and recompile, so as to see when the error no longer shows up.

TheLobos
70
TheLobos 2016.04.13 09:28  

Thanks guys for the answers guys, it pointed me in the right direction. My mistake was that I had accidentally placed a ";" after a #define like this

 

  #define DIRECTION_NONE  0;

 

which then resulted in the above error. Once the extra ";" was removed, everything worked like a charm.  

Fernando Carreiro
2349
Fernando Carreiro 2016.04.13 09:32  
Thank you for letting us know!
Ex Ovo Omnia
3153
Ex Ovo Omnia 2016.04.13 10:14  
TheLobos:

Thanks guys for the answers guys, it pointed me in the right direction. My mistake was that I had accidentally placed a ";" after a #define like this

 

  #define DIRECTION_NONE  0;

 

which then resulted in the above error. Once the extra ";" was removed, everything worked like a charm.  

Just a short coding hint - if you need to declare integer constants, it is more compact to do so in (anonymous) enumeration instead of #define, like

enum {
 DIRECTION_DOWN = -1,
 DIRECTION_NONE,
 DIRECTION_UP
};
TheLobos
70
TheLobos 2016.04.13 10:43  
Thanks Ovo, good hint, will make use of this one.
Alain Verleyen
Moderator
30740
Alain Verleyen 2016.04.13 11:39  
Ovo:

Just a short coding hint - if you need to declare integer constants, it is more compact to do so in (anonymous) enumeration instead of #define, like

 

An other "hidden" feature, as the documentation states otherwise :

Unlike C++, an anonymous enumeration can't be declared in MQL4. That is, a unique name must be always specified after the enum keyword.

whroeder1
14514
whroeder1 2016.04.13 11:51  
4x_Gypsy: try return(DIRECTION_NONE);
The parentheses are unnecessary since Build 600. (Ticket #1011145 2014.05.11)
TheLobos:   #define DIRECTION_NONE  0;
Never add semicolon to #defines. Adding it breaks 
(DIRECTION_NONE);
and results in two with
return DIRECTION_NONE;
Thus breaking
if(condition) return DIRECTION_NONE;
else          return other; // This else is NOT connected to the if.
 Don't define related constants, use an enumeration.
enum Direction{
 DIRECTION_DOWN = -1,
 DIRECTION_NONE,
 DIRECTION_UP
};
Direction function(void){
   :
   return DIRECTION_NONE;
}
Direction d = function();
if(d == DIRECTION_NONE) ...
Using enumerations instead of constants allows the compiler to check types.
/// Converts a day of week to a string.
static string  as_string(ENUM_DAY_OF_WEEK dow,  ///<[in] Day of the week.
                         COUNT         nChar=9) /**<[in] Number of characters to
                                              * return, e.g.\ 3 outputs SUN. */{
   return StringSubstr(EnumToString(dow), nChar);
}

Print(as_string(DIRECTION_NONE)); // Does not compile without a intentional cast.
Where as
#define DIRECTION_NONE 0
Print(as_string(DIRECTION_NONE)); // Compiles and prints SUNDAY
And adding a unrelated function
string   as_string(ENUM_TIMEFRAMES tf){
   if(tf == WRONG_VALUE)  return "\xBF\xBF"; // ¿
   string period_xxx = EnumToString(tf);                       // PERIOD_XXX
   return StringSubstr(period_xxx, 7);                         // XXX
}

Print(as_string(DIRECTION_NONE)); // No longer Compiles (ambiguous)
Alain Verleyen
Moderator
30740
Alain Verleyen 2016.04.13 12:12  
WHRoeder:
4x_Gypsy: try return(DIRECTION_NONE);
The parentheses are unnecessary since Build 600. (Ticket #1011145 2014.05.11)
TheLobos:   #define DIRECTION_NONE  0;
Never add semicolon to #defines. Adding it breaks  and results in two with Thus breaking
 Don't define related constants, use an enumeration.
Using enumerations instead of constants allows the compiler to check types.Where as

Can I ask why you defined this function as static ?

static string  as_string(ENUM_DAY_OF_WEEK dow,  ///<[in] Day of the week.
                         COUNT         nChar=9) /**<[in] Number of characters to
                                              * return, e.g.\ 3 outputs SUN. */{
   return StringSubstr(EnumToString(dow), nChar);
}
whroeder1
14514
whroeder1 2016.04.13 12:23  
angevoyageur: Can I ask why you defined this function as static ?
Cut and paste error. I currently have:
/** This structure just contains static functions for name space control.     */
struct Date_Time{
   #define HR2400 86400 // PERIOD_D1 * 60 = 24 * 3600
static SECONDS    time(datetime when=0){
   return SECONDS((when == 0) ? TimeCurrent() : when) % HR2400;                }
static datetime   date(datetime when=0){
   return ((when == 0) ? TimeCurrent() : when) - time(when);                   }
static datetime   tomorrow( datetime when=0){   // Weekends not accounted for.
   return date((when == 0) ? TimeCurrent() : when) + HR2400;                   }
/// Returns previous trading day.
static datetime   yesterday(datetime when=0) /**< Previous relative to when.*/{
   if(when==0) when = TimeCurrent();
   // Make sure I have daily history.
   download_history(_Symbol, PERIOD_D1, __FUNCTION__);
   INDEX    iD1   = iBarShift(NULL, PERIOD_D1,  when);   // Find today.
   return iTime(NULL, PERIOD_D1, iD1 + 1);               // Return yesterday.
}
/// Converts a day of week to a string.
static string  as_string(ENUM_DAY_OF_WEEK dow,  ///<[in] Day of the week.
                         COUNT         nChar=9) /**<[in] Number of characters to
                                              * return, e.g.\ 3 outputs SUN. */{
   return StringSubstr(EnumToString(dow), nChar);
}
 private:   /// Data. Prevent "struct has no members, size assigned to 1 byte."
   char  onebyte; 
};
//////////
SECONDS elapsed = Date_Time::time(...);
These functions don't need to be inside a structure but if I ever add other functions (like time zones) then the struct becomes a class but nothing else needs to be changed elsewhere.
12
To add comments, please log in or register