Previously the X++ language allowed the LEFT and RIGHT keywords on definitions of string variables. That is no longer valid X++. However, we still allow specifying an explicit string length. The X++ language runtime implicitly does string truncation on assignment, both directly and when passing parameters. Consider the following example:

{
    str 5 s;
    s = ‘124567890";
}

The resulting string will only contain the first 5 characters, i.e. ‘12345'. Normally the user would not explicitly provide the length of the string in this way, but the behavior is exactly the same when using an extended type that has a particular length. One example is the SysGroup type, that is defined as having length 10 in the properties for the extended data type. If you run

{
    SysGroup g = ‘1234567890ABCDEFGHIJ";
    print g;
}

You will only get the first 10 characters printed. The remaining ones are lost to truncation.

The compiler is currently very weak in its support for these extended datatypes (EDTs). There is no validation that you are not assigning apples to oranges (so to speak). It would be natural for the compiler to respect the hierarchy that is expressed in the extended data types as is the case for class hierarchies, but that semantic check is not currently done: The compiler will base its checking on the base types of the EDTs. Introducing extra checks for the EDT hierarchies would be pleasing from a correctness perspective, but it would be an unreasonably daunting task for the eco-system to clean up the errors that would be the result of adding this check. On the other hand, using the EDTs does allow for a degree of documentation and customization.

It is quite easy for the X++ interpreter to provide these truncation semantics; it is not as easy to do in managed code. If we did, it would both compromise performance, and introduce considerable complexity into both the generation of the IL code and its execution.

Consider the following example, in which the interpreter and IL will provide different results:

{
str 5 s = ‘1234’;        // Interpreter: ‘1234’; IL: ‘1234’
s += ‘ABCDE’;         // Interpreter: ‘1234A’; IL: ‘12345ABCDE’
s = strrem(s, ‘1’);      // Interpreter: ‘234A’; IL: ‘2345ABCDE’
}

No truncation would take place when assignments are made to bound strings, neither for direct assignments or by passing parameters. Only when the string is persisted into the database will the truncation take effect.

The question for you to answer is: Do you rely on these semantics in your code? Would your code run well if all string types were equal and unbound? Do we need to muddy the waters for IL by introducing the same behavior in IL?