Microsoft Dynamics Ax developer's blog

Thursday, March 16, 2006

The magic semicolon

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
}

4 comments:

Helmut Wimmer said...

Hi Max!
I found your post today and finally I understand why I have to put semicolons in the top of the methods. It's so good I made a post on my own blog with a link to your post.

Max Belugin said...

Thank you, Helmut.

Kamalakannan said...

hey thats really great,

till date i just thought it's a best practice and i use to blink when Xpp compiler shows up errors.

Thanks mak for your clarrification

Moutasem al-awa said...

Thanks it hepled me to understand its use, even i am reading Inside Microsoft Dynamics AX from MS Press they didn't mention it.