One reason that BSD's m4 is not yet a drop-in for GNU's m4 in all situations is that the two disagree on the correct output for this command line: $ echo 'changequote([,])define(a,1)define(b,2)defn([a],[b])' | m4 GNU m4 outputs 12, but BSD m4 outputs 21. POSIX says https://pubs.opengroup.org/onlinepubs/9799919799/utilities/m4.html "The defining text of the defn macro shall be the quoted definition (using the current quoting strings) of its arguments.". Since it does not mention reordering those arguments, I argue that BSD's stack-like behavior of multi-argument defn is wrong. Especially when compared to it's multi-argument dumpdef which does follow argument order.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=25a8168f86a1222388475ce858da405e4d06c1c3 commit 25a8168f86a1222388475ce858da405e4d06c1c3 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-02-07 18:16:21 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-02-07 18:16:21 +0000 m4: Change defn processing order Currently, defn pushes its arguments on the stack in order, which means they are then processed in reverse order. POSIX does not specify what order they are processed in, which arguably suggests that they should be processed in the order they are listed. Push them in reverse order so they will be processed in their original order. This matches GNU m4. PR: 292937 MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: obiwac, imp Differential Revision: https://reviews.freebsd.org/D55116 usr.bin/m4/eval.c | 2 +- usr.bin/m4/tests/Makefile | 2 ++ usr.bin/m4/tests/defn.m4 (new) | 5 +++++ usr.bin/m4/tests/m4_test.sh | 9 +++++++++ usr.bin/m4/tests/regress.defn.out (new) | 1 + 5 files changed, 18 insertions(+), 1 deletion(-)
A commit in branch stable/15 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=78c53adf27d542c970eab2595b04d97b129ab2d0 commit 78c53adf27d542c970eab2595b04d97b129ab2d0 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-02-07 18:16:21 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-02-15 08:57:46 +0000 m4: Change defn processing order Currently, defn pushes its arguments on the stack in order, which means they are then processed in reverse order. POSIX does not specify what order they are processed in, which arguably suggests that they should be processed in the order they are listed. Push them in reverse order so they will be processed in their original order. This matches GNU m4. PR: 292937 MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: obiwac, imp Differential Revision: https://reviews.freebsd.org/D55116 (cherry picked from commit 25a8168f86a1222388475ce858da405e4d06c1c3) usr.bin/m4/eval.c | 2 +- usr.bin/m4/tests/Makefile | 2 ++ usr.bin/m4/tests/defn.m4 (new) | 5 +++++ usr.bin/m4/tests/m4_test.sh | 9 +++++++++ usr.bin/m4/tests/regress.defn.out (new) | 1 + 5 files changed, 18 insertions(+), 1 deletion(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=e661c4c4a3a3aef6645dee66e3c34859766b39be commit e661c4c4a3a3aef6645dee66e3c34859766b39be Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-02-07 18:16:21 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-02-15 08:58:34 +0000 m4: Change defn processing order Currently, defn pushes its arguments on the stack in order, which means they are then processed in reverse order. POSIX does not specify what order they are processed in, which arguably suggests that they should be processed in the order they are listed. Push them in reverse order so they will be processed in their original order. This matches GNU m4. PR: 292937 MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: obiwac, imp Differential Revision: https://reviews.freebsd.org/D55116 (cherry picked from commit 25a8168f86a1222388475ce858da405e4d06c1c3) usr.bin/m4/eval.c | 2 +- usr.bin/m4/tests/Makefile | 2 ++ usr.bin/m4/tests/defn.m4 (new) | 5 +++++ usr.bin/m4/tests/m4_test.sh | 9 +++++++++ usr.bin/m4/tests/regress.defn.out (new) | 1 + 5 files changed, 18 insertions(+), 1 deletion(-)