Mysterious Unbalanced Left Parenthesis error

 

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.

 

 
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

 

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.

 

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.  

 
Thank you for letting us know!
 
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
};
 
Thanks Ovo, good hint, will make use of this one.
 
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.

 
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)
 
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);
}
 
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.
Reason: