Example
This X++ code compiles well, but have Two potential errors:
static void test(Args _args)
{
int axcoder, axcoder1;
axcoder=1;
axcoder1=2;
}
This code is fragile. Try now to add the new type called 'axcoder'. Introduce a new class with the name 'axcoder', for example.
You will get a syntax error.
The problem is that designers of X++ decide to:
- allow variables and type with similar name (so it is not possible treate a type as a variable of the special type, lead to tableNum, classNum and other ...Num literals in X++, blocks to declare variables in any place of code and so on)
- do not lookahead deep enough to resolve this collision - so you and me we both able to decide that axcoder is not a class name here, but X++ parser does not (i am not sure its an easy task, but i think it is possible)
There is a common workaround for this situation: add an extra semicolon after the end of declarations like this:
static void test(Args _args)
{
int axcoder, axcoder1;
;
axcoder=1;
axcoder1=2;
}
Now the code compiles well. But this is not the end.
Try to introduce a new class with the name 'axcoder1'.
Oops! One more syntax error.
The cause is the same.
Now let's split multivariable declaration to two;
static void test(Args _args)
{
int axcoder;
int axcoder1;
;
axcoder=1;
axcoder1=2;
}
This compiles well.
Conclusion
X++ developers didn't copy java accurate enough. The decide to reinvent the wheel so X++ is sometimes ugly. It allows you to compile code which become brocen if anybody introduce the class with a special name. I have seen examples of such fragile code even in sys layer code (see \Classes\SysLookup\lookupTableFieldRelation for example).
There are simple rules to avoid such errors:
- don't use multivariable declarations
- insert extra semicolon after declarations end (but you can ommit it if the first non-declaration is a keyword for example return)
- dont use simple name for classes ('i', for example) which can be name of the variable in existing code
Note on style
I prefer to keep extra semicolon as the first character of line so it help to delimit internal fuction from the main function body:
void test()
{
void subFunction1()
{
// body of subFunction1
}
void subFunction2()
{
// body of subFunction1
}
;
// body of the main function
}