Flatten(), before calling the flatten opcode, copies the value into __D0main which type is long, while FlattenVar() uses the variable directly. So with FlattenVar(), you pass it a two byte value, while with Flatten() you pass it a 4 byte value, because there is a temporary variable involved which you aren't aware of. The length of the string is therefore different in the two cases.
So StrCat does work, however the text you are looking for is a few characters later in the string than you expect and therefore not showing on the screen.
Oh, nice explanation. It makes some sense, as Flatten() is a general function, it's normal that it returns a 4-byte string, regardless of the kind of the variable.
I would suggest that this note could be on the description in the API html help.
Flatten is implemented in the compiler as a function that can take a boolean expression as its input. It needs to use temporaries as a result of this capability. The temporaries used for all NXC expressions are either signed longs, unsigned longs, or floats.
FlattenVar is defined as a macro in NXCDefs.h so it cannot accept any kind of NXC expression (since it emits an NBC asm block directly into the resulting code). FlattenVar can work with any type, not just simple numbers. It will flatten to a string whose length is determined by the size of the input variable.
There is a new SizeOf API function in NXC which will be included in the next test/official release that uses FlattenVar to calculate at runtime the size of any type. For simple types it does the calculation at compile time. The Read/ReadLn functions have been modified to use this new function so that it can calculate the right number of bytes to read from a file based on the size of the container provided to store the data in.
If the null terminator is the value 0, why doesn't strcat() ignore the 0-value bytes of the Flatten() result of the variables with less then 4 bytes? And from what I just tried, if I call strlen(Flatten(1)) it gives me 4.
Is that because of the structure behind the "string" type, that contains length information?
A string is just an array of bytes and strlen = array length - 1. The firmware keeps track of the number of elements in each array so it would think that the string was 4 bytes long even though 2 of those bytes were additional nulls (with the actual array length being 5).
All that strcat does is the same thing as arraybuild except that it drops off the last element in each of the source arrays both when counting how many elements the destination array needs to have room for and when using memmove to copy the data from each source array into the memory allocated for the destination array.
So your concatenation worked fine but you have two nulls embedded in the middle of your string - and the first two characters in it are not representable on the NXC LCD screen using the font defined in the firmware.