( Incompatibilities

Info Catalog ( Extensions ( Compatibility ( 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
      non-numeric argument).
    * 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.
           =>define(`_m4wrap_level', `0')dnl
           =>       `define(`m4wrap'_m4wrap_level,
           =>               defn(`m4wrap'_m4wrap_level)`$1')',
           =>       `builtin(`m4wrap', `define(`_m4wrap_level',
           =>                                  incr(_m4wrap_level))dnl
           =>define(`m4wrap'_m4wrap_level, `$1')')')dnl
           ', `d')')m4wrap(`b')
    * 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'.
Info Catalog ( Extensions ( Compatibility ( Other Incompatibilities
automatically generated byinfo2html