bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AC_DEFUN_ONCE and maintainability


From: Bruno Haible
Subject: AC_DEFUN_ONCE and maintainability
Date: Tue, 03 Jul 2012 03:08:32 +0200
User-agent: KMail/4.7.4 (Linux/3.1.10-1.9-desktop; KDE/4.7.4; x86_64; ; )

Hi Eric,

> The canonical
> fix in gnulib is to use AC_DEFUN_ONCE instead of AC_DEFUN for any
> function that we want to guarantee that it gets expanded without
> triggering the older autoconf bug.

You're right; I should revert the patch and use
AC_DEFUN_ONCE([gl_FUNC_LOG],...) instead.

But I have two issues with AC_DEFUN_ONCE. The first one is a maintainability
issue:

There are 4 classes of Autoconf macros in Gnulib:
  (A) Macros that are defined at m4 level and not subject to reordering
      via AC_REQUIRE. Defined through m4_defun.
  (B) Macros that takes arguments, meant to be invoked (possibly inside
      'if' branches).
  (C) Macros without arguments, that can be required - must be safe to reorder,
      must not call AC_LIBOBJ.
  (D) Macros without arguments, that can be required - must be safe to reorder,
      must not call AC_LIBOBJ - or invoked (but not inside 'if' branches).

So far,
  for (B) we use AC_DEFUN,
  for (C) we use AC_DEFUN,
  for (D) we use AC_DEFUN_ONCE.

Issue #1: When I add an AC_REQUIRE([FOO]) somewhere, I don't immediately
know whether I have to transform AC_DEFUN([FOO]) to AC_DEFUN_ONCE([FOO]) -
because to determine whether we're in case (B) or (C) requires grepping
across all of Gnulib.

Issue #2: When I add an invocation FOO somewhere, I don't immediately
know whether I have to transform AC_DEFUN([FOO]) to AC_DEFUN_ONCE([FOO]) -
because to determine whether we're in case (B) or (C) requires grepping
across all of Gnulib.

Issue #3: When I add some code inside macro FOO, I don't know whether I'm
allowed to rely on global variables (possible in case (B)) or whether I
have to provide position independent code (in case (C)) - because to
determine whether we're in case (B) or (C) requires grepping across all
of Gnulib.

So it would be better to be able to distinguish cases (B) and (C).

I suggest to introduce a new macro AC_ONCE, that expands to AC_DEFUN,
so that:
  for (B) we use AC_DEFUN,
  for (C) we use AC_ONCE,
  for (D) we use AC_DEFUN_ONCE.

About the naming: The macro FOO in case (C) cannot take arguments and
cannot be invoked; it is far from a "function" - and 'defun' in Lisp
is meant to define a function.

Considering just the macros named gl_FUNC_*, here would be the suggested
changes:

Candidates for changing AC_DEFUN -> AC_ONCE:
gl_FUNC_REALPATH_WORKS
gl_FUNC_EACCESS
gl_FUNC_FEGETROUND
gl_FUNC_GETCWD_NULL
gl_FUNC_GETCWD_SIGNATURE
gl_FUNC_MEMMEM_SIMPLE
gl_FUNC_STRERROR_0
gl_FUNC_STRERROR_R_WORKS
gl_FUNC_UTIMES

Candidates for changing AC_DEFUN_ONCE -> AC_ONCE:
gl_FUNC_CHOWN_FOLLOWS_SYMLINK
gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK

Candidates for changing AC_DEFUN -> AC_DEFUN_ONCE:
gl_FUNC_ACOS
gl_FUNC_ACOSL
gl_FUNC_ASIN
gl_FUNC_ASINL
gl_FUNC_ATAN
gl_FUNC_ATAN2
gl_FUNC_ATANL
gl_FUNC_CBRT
gl_FUNC_CBRTL
gl_FUNC_CEIL
gl_FUNC_CEILF
gl_FUNC_CEILL
gl_FUNC_CLOSE
gl_FUNC_COPYSIGN
gl_FUNC_COS
gl_FUNC_COSH
gl_FUNC_COSL
gl_FUNC_EUIDACCESS
gl_FUNC_EXP
gl_FUNC_EXP2
gl_FUNC_EXP2L
gl_FUNC_EXPL
gl_FUNC_EXPM1
gl_FUNC_EXPM1F
gl_FUNC_EXPM1L
gl_FUNC_FABS
gl_FUNC_FABSF
gl_FUNC_FABSL
gl_FUNC_FLOOR
gl_FUNC_FLOORF
gl_FUNC_FLOORL
gl_FUNC_FMA
gl_FUNC_FMOD
gl_FUNC_FMODF
gl_FUNC_FMODL
gl_FUNC_FNMATCH_POSIX
gl_FUNC_FREXP
gl_FUNC_FREXPF
gl_FUNC_FREXPL
gl_FUNC_FSEEKO
gl_FUNC_FTELLO
gl_FUNC_GETOPT_POSIX
gl_FUNC_HYPOT
gl_FUNC_HYPOTF
gl_FUNC_HYPOTL
gl_FUNC_ILOGB
gl_FUNC_INET_NTOP
gl_FUNC_ISNAND
gl_FUNC_ISNANF
gl_FUNC_ISNANL
gl_FUNC_LDEXP
gl_FUNC_LDEXPF
gl_FUNC_LDEXPL
gl_FUNC_LINK_FOLLOWS_SYMLINK
gl_FUNC_LOG        and modify modules/log
gl_FUNC_LOG10
gl_FUNC_LOG10F
gl_FUNC_LOG1P
gl_FUNC_LOG1PF
gl_FUNC_LOG1PL
gl_FUNC_LOG2
gl_FUNC_LOG2F
gl_FUNC_LOGB
gl_FUNC_LOGF
gl_FUNC_LOGL
gl_FUNC_MBRTOWC
gl_FUNC_MEMCHR
gl_FUNC_MKFIFO
gl_FUNC_MKTIME
gl_FUNC_MMAP_ANON
gl_FUNC_MODF
gl_FUNC_MODFF
gl_FUNC_MODFL
gl_FUNC_OPENAT
gl_FUNC_POW
gl_FUNC_REMAINDER
gl_FUNC_REMAINDERF
gl_FUNC_REMAINDERL
gl_FUNC_RENAME
gl_FUNC_RINT
gl_FUNC_RMDIR
gl_FUNC_ROUND
gl_FUNC_ROUNDF
gl_FUNC_ROUNDL
gl_FUNC_SELECT
gl_FUNC_SETENV_SEPARATE
gl_FUNC_SIN
gl_FUNC_SINH
gl_FUNC_SINL
gl_FUNC_SQRT
gl_FUNC_SQRTL
gl_FUNC_STRERROR_R
gl_FUNC_STRCASESTR_SIMPLE
gl_FUNC_STRSTR_SIMPLE
gl_FUNC_TAN
gl_FUNC_TANH
gl_FUNC_TANL
gl_FUNC_TRUNC
gl_FUNC_TRUNCF
gl_FUNC_TRUNCL
gl_FUNC_UNLINK
gl_FUNC_VFPRINTF_POSIX
gl_FUNC_WCWIDTH

More generally, this would lead to the coding convention that all macros
gl_FUNC_FOO for a single function foo() would be an AC_DEFUN_ONCE.

The macro AC_ONCE would be defined in 00gnulib.m4.

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]