Constants in C/AL

December 1st, 2011

Let’s start this post with a little example:

In the MSXML library, the XMLDocument class has a method called CreateNode, which accepts an integer representing the desired node type as its first parameter. One of the possible symbolic values for node type defined in MSXML is NODE_ELEMENT, which has a numerical value of 1. A call to CreateNode might look like this:

MyNewElement := MyXMLDocument.CreateNode(1, MyNodeName, MyNamespace);

However, the use of magic numbers is considered a bad idea by most professional programmers. We should probably use something like this instead:

MyNewElement := MyXMLDocument.CreateNode(NODE_ELEMENT, MyNodeName, MyNamespace);

But how are we going to implement this NODE_ELEMENT constant?

As you will probably be aware, constants are conspicuously absent in C/AL (remarkable, I guess, for a language that is supposed to be Pascal-based, or at least Pascal-inspired…). Boolean and numerical constants, and non-localizable string constants are usually implemented by setting a global variable to the desired value, and hoping that future maintainers of the code will be kind enough to leave the value alone.

My suggestion is to use a function instead. By its very nature, the return value of function is constant, i.e. cannot be assigned a new value from outside of the function. That also means that it is not affected by a carelessly added call to, say, CLEARALL, which would cause a constant implemented as a global variable to loose its value. Lastly, functions have global scope within the containing object, without introducing unnecessary global variables – a personal allergy of mine…

9 Responses to “Constants in C/AL”

  1. Luc van Vugt Says:

    Makes perfect sense, Jan.

    But shouldn’t we ask MS for a CONSTANT concept in C/SIDE? They’re investing a lot in C/SIDE lately.

  2. Langbak Says:

    Hi jhoek,

    I couldn’t agree more!!

    Your solution is also much easier to maintain if the constant should change in a future API release.

    /Langbak

  3. Dynamics NAV Enthusiast Says:

    That (using functions to define constants) sounds like a brilliant idea :)

  4. Natalie Says:

    You are totally right - this principle (using a function) is even followed by the NAV standard:
    Codeunit 1, functions ApplicationVersion, ApplicationBuild, ApplicationLanguage.

  5. jhoek Says:

    @Natalie: That’s right, although the situation for that is slightly different, I think. In my example, the NODE_ELEMENT function could have been Local=Yes, limiting its scope to the containing object, whereas the functions in codeunit 1 are called by the platform, e.g. for displaying the values in the about box. Theoretically, this would make these functions Local=No (i.e. visible to calling objects), although I’m sure the platform could also call local functions…

  6. Constants in C/AL | Pardaan.com Says:

    […] Bron : Zen & the Art of C/SIDE Development Lees meer… […]

  7. Thad Says:

    Actually in a situation like that I prefer to firstly create a codeunit to encapsulate all the xml document and node manipulation. Assuming this is the case I would then create a global variable of type option called XMLDomNodeType with the value:
    NODE_ELEMENT,NODE_ATTRIBUTE,NODE_TEXT,NODE_CDATA_SECTION,NODE_ENTITY_REFERENCE,NODE_ENTITY,NODE_PROCESSING_INSTRUCTION,NODE_COMMENT,NODE_DOCUMENT,NODE_DOCUMENT_TYPE,NODE_DOCUMENT_FRAGMENT,NODE_NOTATION

    Then you don’t have to have a separate function for every value of the enumeration, and since the enumeration starts with 1, this mirrors an option type very nicely. This will also still lead to very readable code, such as:

    MyNewElement := MyXMLDocument.CreateNode(XMLDomNodeType::NODE_ELEMENT, MyNodeName, MyNamespace);

  8. jhoek Says:

    Yep, I agree. However, that works best for smaller, adjacent constant values (which is the case for the MSXML node types).

    For flags, which typically have numerical values of 0, 1, 2, 4, 8, 16 etc., options quickly lose their advantages, I think.

  9. Thad Says:

    Yes I agree, in the instance of flags I wouldn’t recommend using options. Quite frankly I would probably try to avoid ever doing anything with an API that involved flags inside of Navision if I could help it.

Leave a Reply

*
To prove you're a person (not a spam script), type the security text shown in the picture. Click here to regenerate some new text.
Click to hear an audio file of the anti-spam word