On 1/4/19 3:48 AM, Richard W.M. Jones wrote:
The preferred implementation uses __auto_type, a GCC extension also
now supported by Clang.
Unfortunately OpenBSD ships with GCC 4.2.1 (from 2007!) which predates
this extension by quite a few years, so we have to be able to fall
back to a plain macro.
Not quite. A quick google search found that at least gcc 3.3.6 supported
typeof, and therefore 4.2.1 does as well (I'm not sure how far back that
extension goes - it's surprisingly hard to google for which gcc version
introduced a specific extension, and I merely got lucky that my google
search hit a copy of the 3.3.6 docs. I suppose a crawl through gcc.git
history is going to be the most accurate way to find when which
extensions were added). At any rate, typeof is better than the naive
plain macro.
But you ARE right that __auto_type is nicer than typeof (smaller macro
expansion, and deals with variably modified types correctly - although
we don't use those to worry about that latter point).
+++ b/configure.ac
@@ -156,9 +156,27 @@ you may be using a C compiler which does not support this
attribute,
or the configure test may be wrong.
This code requires the attribute to work for proper locking between threads.])])
-dnl restore CFLAGS
CFLAGS="${acx_nbdkit_save_CFLAGS}"
+dnl Check for __auto_type (GCC extension).
+AC_MSG_CHECKING([if __auto_type is available in this compiler])
+AC_COMPILE_IFELSE([
+AC_LANG_SOURCE([[
+static int
+test (int a)
+{
+ __auto_type at = a;
+ return at;
+}
+]])
+ ],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_AUTO_TYPE],[1],[__auto_type is available])
+ ],[
+ AC_MSG_RESULT([no])
If desired, we could also make the negative branch test that typeof is
supported, rather than blindly using it - then again; we rely on enough
other gcc extensions (and mandate at least automatic cleanup support)
that we are probably safe assuming that typeof works if __auto_type is
not present.
+#ifdef HAVE_AUTO_TYPE
+
+/* __auto_type is a GCC extension, added in GCC 4.9 in 2014, and to
+ * Clang in 2015.
+ */
+
+#define MIN(x, y) ({ \
+ __auto_type _x = (x); \
+ __auto_type _y = (y); \
+ _x < _y ? _x : _y; \
+ })
+#define MAX(x, y) ({ \
+ __auto_type _x = (x); \
+ __auto_type _y = (y); \
+ _x > _y ? _x : _y; \
+ })
+
+#else
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
So I'd replace these with:
#define MIN(x, y) ({ \
typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a < _b ? _a : _b; \
})
and similar for MAX.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org