Preprocessor changes
Several bugs have been fixed in the preprocessor, that can now result in a compilation error.
String token expansion
&define T(x) DISPLAY "head_"#x"_tail"
-- macro usage:
T(body)"head_""body""_tail"It was accepted by the compiler, because it was interpreted as a single string literal.
"head_" "body" "_tail"However, this will now result in a compiler error, because this is not a valid string literal.
To solve an issue such as this and get the same result string as before version 3.00, use the
|| concatenation operator in the preprocessor macro and add
(escaped) double quotes before and after the
#ident placeholder:
&define T(x) DISPLAY "head_""" || #x || """_tail"
&define T(x) DISPLAY 'head_"' || #x || '"_tail'Identifier concatenation
&define FOO() foo
-- macro usage:
FOO()barfoobarfoo barAnd this will result in a compilation error.
Backslash in macro parameters
Before version 3.00.00 it was possible to use the backslash to escape a comma in preprocessor macro parameters. This syntax is no longer allowed by the preprocessor, it is not a valid usage. To solve this issue, replace parameters by real string literals in the macro:
-- bad coding
&define FOO(p1) DISPLAY #p1
FOO(hello world) -- expands to: DISPLAY "hello world"
FOO(hello \, world) -- error
-- good coding
&define FOO(p1) DISPLAY p1
FOO("hello world") -- expands to: DISPLAY "hello world"
FOO("hello , world") -- expands to: DISPLAY "hello , world"
The ## paste operator
## paste operator was used to construct code with
two elements that did not result in a valid token, for
example:&define FOO(name) rec_ ## [ x ]
FOO(x)rec_[ x ]x.4gl:2:1:2:1:error:(-8042) The operator '##' formed 'rec_[',
an invalid preprocessing token.## paste operator must be used to join two identifiers, to
create a new identifier:&define REC_PREFIX(name) rec_ ## name
LET REC_PREFIX(customer) = NULLLET rec_customer = NULLFile inclusion search path
Before version 3.00, the compiler option -I was allowing you to specify a list
of paths separated by the OS path separator.
This behavior was unexpected and wrong: The -I option must define a single path
(or directory).
fglcomp -I path1:path2 ...must
be reviewed by specifying each directory in a separate -I
option:fglcomp -I path1 -I path2 ...