(m4.info.gz) Other Incompatibilities
15.2 Facilities in System V `m4' not in GNU `m4'
The version of `m4' from System V contains a few facilities that have
not been implemented in GNU `m4' yet. Additionally, POSIX requires
some behaviors that GNU `m4' has not implemented yet. Relying on these
behaviors is non-portable, as a future release of GNU `m4' may change.
* System V `m4' supports multiple arguments to `defn', and POSIX
requires it. This is not yet implemented in GNU `m4'.
Unfortunately, this means it is not possible to mix builtins and
other text into a single macro; a helper macro is required.
* POSIX requires an application to exit with non-zero status if it
wrote an error message to stderr. This has not yet been
consistently implemented for the various builtins that are
required to issue an error (such as `include' ( Include)
when a file is unreadable, `eval' ( Eval) when an argument
cannot be parsed, or using `m4exit' ( M4exit) with a
* Some traditional implementations only allow reading standard input
once, but GNU `m4' correctly handles multiple instances of `-' on
the command line.
* POSIX requires `m4wrap' ( M4wrap) to act in FIFO (first-in,
first-out) order, but GNU `m4' currently uses LIFO order.
Furthermore, POSIX states that only the first argument to `m4wrap'
is saved for later evaluation, bug GNU `m4' saves and processes
all arguments, with output separated by spaces.
However, it is possible to emulate POSIX behavior by including the
file `examples/wrapfifo.m4' from the distribution:
=>dnl Redefine m4wrap to have FIFO semantics.
=> `builtin(`m4wrap', `define(`_m4wrap_level',
* POSIX requires that all builtins that require arguments, but are
called without arguments, behave as though empty strings had been
passed. For example, `a`'define`'b' would expand to `ab'. But
GNU `m4' ignores certain builtins if they have missing arguments,
giving `adefineb' for the above example.
* Traditional implementations handle `define(`f',`1')' (
Define) by undefining the entire stack of previous definitions,
and if doing `undefine(`f')' first. GNU `m4' replaces just the top
definition on the stack, as if doing `popdef(`f')' followed by
* POSIX requires `syscmd' ( Syscmd) to evaluate command
output for macro expansion, but this appears to be a mistake in
POSIX since traditional implementations did not do this. GNU `m4'
follows traditional behavior in `syscmd', and provides the
extension `esyscmd' that provides the POSIX semantics.
* POSIX requires `maketemp' ( Maketemp) to replace the
trailing `X' characters with the `m4' process id, giving the same
result on identical input, without creating any files, which
leaves the door open for a data race in which other processes can
create a file by the same name. GNU `m4' actually creates a
temporary file for each invocation of `maketemp', which means that
the output of the macro is different even if the input is
* POSIX requires `changequote(ARG)' ( Changequote) to use
newline as the close quote, but GNU `m4' uses `'' as the close
quote. Meanwhile, some traditional implementations use ARG as the
close quote, making it impossible to nest quotes. For predictable
results, never call changequote with just one argument.
* Some implementations of `m4' give macros a higher precedence than
comments when parsing, meaning that if the start delimiter given to
`changecom' ( Changecom) starts with a macro name, comments
are effectively disabled. POSIX does not specify what the
precedence is, so the GNU `m4' parser recognizes comments, then
macros, then quoted strings.
* Traditional implementations allow argument collection, but not
string and comment processing, to span file boundaries. Thus, if
`a.m4' contains `len(', and `b.m4' contains `abc)', `m4 a.m4 b.m4'
outputs `3' with traditional `m4', but gives an error message that
the end of file was encountered inside a macro with GNU `m4'. On
the other hand, traditional implementations do end of file
processing for files included with `include' or `sinclude' (
Include), while GNU `m4' seamlessly integrates the content of
those files. Thus `include(`a.m4')include(`b.m4')' will output
`3' instead of giving an error.
* Traditional `m4' treats `traceon' ( Trace) without
arguments as a global variable, independent of named macro tracing.
Also, once a macro is undefined, named tracing of that macro is
lost. On the other hand, when GNU `m4' encounters `traceon'
without arguments, it turns tracing on for all existing
definitions at the time, but does not trace future definitions;
`traceoff' without arguments turns tracing off for all definitions
regardless of whether they were also traced by name; and tracing
by name, such as with `-tfoo' at the command line or
`traceon(`foo')' in the input, is an attribute that is preserved
even if the macro is currently undefined.
* POSIX requires `eval' ( Eval) to treat all operators with
the same precedence as C. However, GNU `m4' currently follows the
traditional precedence of other `m4' implementations, where
bitwise and logical negation (`~' and `!') have lower precedence
than equality operators, rather than equal precedence with other
unary operators. Use explicit parentheses to ensure proper
precedence. As extensions to POSIX, GNU `m4' treats the shift
operators `<<' and `>>' as well-defined on signed integers (even
though they are not in C), and adds the exponentiation operator
* POSIX requires `translit' ( Translit) to treat each
character of the second and third arguments literally, but GNU
`m4' treats `-' as a range operator.
* POSIX requires `m4' to honor the locale environment variables of
`LANG', `LC_ALL', `LC_CTYPE', `LC_MESSAGES', and `NLSPATH', but
this has not yet been implemented in GNU `m4'.
(m4.info.gz) Other Incompatibilities
automatically generated byinfo2html