In the examples of the last section, ``Adding Builtin C Types to the Repertoire of G2++ Types'', we showed how to extend the size of string and array fields beyond their defined limits:
#include "usr.h" USR u; ... u.login="hello world"; OK even though the defined size is 6! u.proj.reserve(99); OK even though the defined size is 4!
We also learned that, for compatibility with G2, fields that exceed their defined length will be truncated by the typed inserters and extractors. For example:
cout << u; truncation of login and proj fields occurs here
Fixed size strings and arrays are in some ways like hardware addresses: just as you may occasionally need to hard-code an address into a program in order to communicate with a special piece of hardware, you may also need to use a fixed size string in order to communicate with an external system that expects one. Consider a software package that asks for input by giving you a pointer to a private buffer together with the buffer's length; you have no choice but to place the string into the buffer, being careful to observe the buffer length limitation. When the programmer has complete control, fixed sizes make less sense; their presence may be a symptom of inflexible design. Not only would such programs avoid the use of fixed size strings and arrays internally, by using types like String(C++) and Block(C++), but they would also communicate among themselves by sending and receiving records containing arbitrary size strings and arrays. For this reason, G2++ supports records with arbitrary size strings and arrays.
We have already seen how to declare fixed size strings and arrays: simply use numbers for string and array sizes:
usr.g usr login 6 # max 6 chars id usr LONG grp SHORT name 20 # max 20 chars proj 4 LONG # max 4 elements
To declare an arbitrary size string or array, use an asterisk (*) instead of a number:
usr.g usr login * # any number of chars id usr LONG grp SHORT name * # any number of chars proj * LONG # any number # of elements
Arbitrary size fields are never truncated, on either input or output:
#include "usr.h" USR u; ... cin >> u; no truncation u.login="hello world"; u.proj.reserve(99); u.proj=1; cout << u; no truncation
Fixed and arbitrary size fields may be mixed in the same record definition.