This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v3] Provide a C++ version of iseqsig
- From: Florian Weimer <fweimer at redhat dot com>
- To: "Gabriel F. T. Gomes" <gabriel at inconstante dot eti dot br>, libc-alpha at sourceware dot org
- Date: Tue, 14 Nov 2017 14:35:27 +0100
- Subject: Re: [PATCH v3] Provide a C++ version of iseqsig
- Authentication-results: sourceware.org; auth=none
- References: <20171114132152.22775-1-gabriel@inconstante.eti.br>
On 11/14/2017 02:21 PM, Gabriel F. T. Gomes wrote:
diff --git a/math/math.h b/math/math.h
index 326fd8ebe1..acc909d37f 100644
--- a/math/math.h
+++ b/math/math.h
@@ -1152,8 +1152,76 @@ iszero (__T __val)
/* Return X == Y but raising "invalid" and setting errno if X or Y is
a NaN. */
-# define iseqsig(x, y) \
- __MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
+# if !defined __cplusplus || (__cplusplus < 201103L && !defined __GNUC__)
+# define iseqsig(x, y) \
+ __MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
+# else
+/* In C++ mode, __MATH_TG cannot be used, because it relies on
+ __builtin_types_compatible_p, which is a C-only builtin. Moreover,
+ the comparison macros from ISO C take two floating-point arguments,
+ which need not have the same type. Choosing what underlying function
+ to call requires evaluating the formats of the arguments, then
+ selecting which is wider. The macro __MATH_EVAL_FMT2 provides this
+ information, however, only the type of the macro expansion is
+ relevant (actually evaluating the expression would be incorrect).
+ Thus, the type is used as a template parameter for __iseqsig_type,
+ which calls the appropriate underlying function. */
+template<typename _T1, typename _T2>
+inline int
+iseqsig(_T1 __x, _T2 __y) throw()
+{
+# if __cplusplus >= 201103L
+ typedef __decltype (__MATH_EVAL_FMT2 (__x, __y)) _T3;
+# else
+ typedef __typeof (__MATH_EVAL_FMT2 (__x, __y)) _T3;
+# endif
+ return __iseqsig_type<_T3>::__call(__x, __y);
+}
+
+} /* extern "C++" */
+# endif /* __cplusplus */
Would these two expressions have the same types, assuming _T1 and _T2
are the template parameters from the iseqsig definition?
__MATH_EVAL_FMT2 (__x, __y)
__MATH_EVAL_FMT2 (_T1 (), _T2 ())
I believe the second expression would be safe to evaluate, so it could
be used to select a suitable inline function. This would then work with
any C++ version.
But the current approach is okay as well.
diff --git a/math/test-math-iseqsig.cc b/math/test-math-iseqsig.cc
new file mode 100644
index 0000000000..0316340638
--- /dev/null
+++ b/math/test-math-iseqsig.cc
+static bool errors;
Maybe use support_record_failure from <support/check.h> instead?
+static void
+check (int actual, int expected, const char *actual_expr, int line)
+{
+ if (actual != expected)
+ {
+ errors = true;
+ printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr);
+ printf ("%s:%d: expected: %d\n", __FILE__, line, expected);
+ printf ("%s:%d: actual: %d\n", __FILE__, line, actual);
+ }
+}
+
+#define CHECK(actual, expected) \
+ check ((actual), (expected), #actual, __LINE__)
I think my memory protection key patches contain a more general
implementation of this called TEST_COMPARE. Adhemerval requested just a
minor documentation change, so I could commit that separately if you
want to use it.
Thanks,
Florian