m4: Other Incompatibilities

 
 16.3 Other incompatibilities
 ============================
 
 There are a few other incompatibilities between this implementation of
 'm4', and the System V version.
 
    * GNU 'm4' implements sync lines differently from System V 'm4', when
      text is being diverted.  GNU 'm4' outputs the sync lines when the
      text is being diverted, and System V 'm4' when the diverted text is
      being brought back.
 
      The problem is which lines and file names should be attached to
      text that is being, or has been, diverted.  System V 'm4' regards
      all the diverted text as being generated by the source line
      containing the 'undivert' call, whereas GNU 'm4' regards the
      diverted text as being generated at the time it is diverted.
 
      The sync line option is used mostly when using 'm4' as a front end
      to a compiler.  If a diverted line causes a compiler error, the
      error messages should most probably refer to the place where the
      diversion was made, and not where it was inserted again.
 
           divert(2)2
           divert(1)1
           divert`'0
           =>#line 3 "stdin"
           =>0
           ^D
           =>#line 2 "stdin"
           =>1
           =>#line 1 "stdin"
           =>2
 
      The current 'm4' implementation has a limitation that the syncline
      output at the start of each diversion occurs no matter what, even
      if the previous diversion did not end with a newline.  This goes
      contrary to the claim that synclines appear on a line by
      themselves, so this limitation may be corrected in a future version
      of 'm4'.  In the meantime, when using '-s', it is wisest to make
      sure all diversions end with newline.
 
    * GNU 'm4' makes no attempt at prohibiting self-referential
      definitions like:
 
           define(`x', `x')
           =>
           define(`x', `x ')
           =>
 
      There is nothing inherently wrong with defining 'x' to return 'x'.
      The wrong thing is to expand 'x' unquoted, because that would cause
      an infinite rescan loop.  In 'm4', one might use macros to hold
      strings, as we do for variables in other programming languages,
      further checking them with:
 
           ifelse(defn(`HOLDER'), `VALUE', ...)
 
      In cases like this one, an interdiction for a macro to hold its own
      name would be a useless limitation.  Of course, this leaves more
      rope for the GNU 'm4' user to hang himself!  Rescanning hangs may
      be avoided through careful programming, a little like for endless
      loops in traditional programming languages.