The lone semicolon

Something that confuses and annoys people when they’re learning X++, is the semicolon after variable declarations.

As you know all local variables have to be declared at the start of the function and statements are placed after that. Then comes the important part: don’t forget to always put a semicolon on a single line before the first statement.

If you don’t, your code might not compile. Sometimes it will, sometimes it won’t. And code that works now can be broken later, without touching it. A semicolon is not always required, but instead of worrying if it’s required, it’s easier to make a habit of just writing it. Even if you don’t have any local variables. Unfortunately even standard X++ code doesn’t always have this.

The reason you need that extra semicolon is because the compiler can’t always see where the variable declarations end. If you don’t help a little, it will make a guess. And it’s not very good at guessing.

While the compiler is analyzing the code it checks if the first word on a line matches the name of a type (AOT object). If it’s a type name the compiler treats the line as a variable declaration. In this case a variable name should be next.

If the first word is not a variable the compiler considers the line to be the start of a statement. In some cases it treats statements as class declarations and that causes compiler errors.

Let me explain this with some examples from the standard application (4.0 SP1). This is a method from the BOMSearch class.

server static BOMSearch newProdTable(ProdTable prodTable)
{
    BOMSearch BOMSearch = new BOMSearch(
                            prodTable.BOMId,
                            prodTable.BOMDate,
                            prodTable.ItemId,
                            prodTable.inventDim().ConfigId,
                            false);
    ;
    BOMSearch.init();
 
    return BOMSearch;
}

If you remove the semicolon from line 9 you will get an error on the next line. The first line is never a problem for the compiler: a variable BOMSearch of type BOMSearch is created.

Next the compiler sees the word BOMSearch and figures, ‘I know that, it’s a class name. So this must be a variable declaration. But what’s with the .init()? That’s not allowed here.’

And there’s the compilation error.

This method from CustTable is an example of bad standard code.

void initFromCustGroup(CustGroup _custGroup)
{
    this.PaymTermId = _custGroup.PaymTermId;
    this.PaymSched  = PaymTerm::find(this.PaymTermId).PaymSched;
}

‘What do you mean, bad code? This is standard Axapta. It works just fine!’.
Yes it does… for now. Create an EDT named this and compile again. It’s broken for the same reason as the previous example.

To avoid headaches, repeat after me: always put a semicolon on a single line before the first statement.

Too bad the compiler isn’t smarter. A Best Practice check would be nice too.

5 thoughts on “The lone semicolon”

  1. Yes, Axapta is littered with such bugs and newbies are left wondering how this product made it out of Redmond. Anyway, we get used to it and hope and pray that the next release has better code and overall standards’ conformation.

  2. You’re right. Things like this are annoying and reflect poorly on the product. It creates an impression of low quality. Technical folks tend to be very critical of legacy/3rd party code, so we wonder how on Earth they could release that pile of … 🙂

    But to be honest, I think MBS is doing genuine efforts to improve the quality of the code and adhere to their own rules. I remember Axapta 2.5 that came with compilation errors out of the box and had thousands of Best Practice errors. At least standard 4.0 compiles cleanly by now. There’s still a long way to go though.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.