This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [libstdc++] preliminary headers supporting decimal float in C++
- From: Benjamin Kosnik <bkoz at redhat dot com>
- To: janis187 at us dot ibm dot com
- Cc: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Sep 2009 13:49:54 -0700
- Subject: Re: [libstdc++] preliminary headers supporting decimal float in C++
- References: <1254181215.6320.14.camel@janis-laptop>
> Should <decimal> go in with the standard headers or in ext?
>
> So far my patch installs the new header files whether the target
> supports decimal floating-point arithmetic or not. Should I move the
> configuration checks from the gcc directory to the top level and use
> those to determine whether to install these files?
Good question. I would put current libstdc++ behavior into one of two
buckets, given constraints given in N2849 section 2.4:
1) put in std location, requires a flag to work. Ie, c++0x headers like
std/unordered_map and -std=gnu++0x (__GXX_EXPERIMENTAL_CXX0X__). For
you, this might mean something like -fdec-fp
(__STDC_WANT_DEC_FP__)
2) put in a non-std location, don't require a flag to work. Ie, TR1
headers like tr1/unordered_map.
From the GCC manual:
http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html
It doesn't look like there is a flag, and __STDC_DEC_FP__ is not
defined. So I would say you are trending towards style #2. This makes
sense for other reasons as it looks like there might be facet additions
which would mean you'd not want this support user-switchable.
So, I would suggest parking this stuff in
include/tr24732
> The TR defines, within each of the classes decimal32, decimal64, and
> decimal128, the following conversion:
>
> // 3.2.[234].4 conversion to integral type:
> operator long long() const;
>
> Apparently there's a way to implement this if one knows enough about
> C++, but providing this implicit conversion from a decimal float type
> to long long allows further implicit conversions from long long to
> other types, including float, double, and long double, which are not
> supposed to be allowed. Furthermore, a conversion from a decimal
> float type to a generic float type that goes through long long
> truncates the fractional part of the value which is rather
> surprising. This version of the patch leaves out that conversion and
> provides a set of functions to convert to long long, which made
> testing the rest of the functionality much easier. Any suggestions
> for how to do with using the current (not C++0x) standard? Or is it
> OK to require the use of C++0x functionality with this extension?
I think it is not ok to require the use of C++0x with the
decimal floating point extension. It is clearly designed with C++2003 in
mind, and makes no use of C++0x features.
When you post testsuite files demonstrating this issue in detail I'll
take a look at this overload issue.
> Section 4.2 of the TR says that implementations can support decimal
> floating-point literals as a conforming extension. My patch does that
> by adding a constructor that takes as argument a scalar DFP type.
>
> I've got lots of tests (not included here) but no documentation. I'll
> follow the recommendations in
> http://gcc.gnu.org/onlinedocs/libstdc++/manual/documentation_style.html.
Here's what I suggest to get the documentation parts rolling.
Add doc/xml/manual/status_cxxtr24733.xml, (base on c++0x
status) indicating status and implementation notes and things like
decimal floating-point literals as a conforming extension. For the
record, to review this patch I used C N1241 and C++ N2849.
Edit doc/xml/manual/using.xml
Add headers <decimal>, and perhaps <decimal.h> . You'll need
to indicate macro usage as well.
Edit doc/xml/support.xml and add bits for numeric_limits and builtin
types.
Would recommend you look at some of the testsuite techniques used for
atomic builtins, ie
testsuite/29_atomics/atomic_integral/operators/integral_conversion.cc.
These can be confusing but may reduce duplication and boost coverage
when you are testing some of these things.
> * std/decimal: New file.
> * bits/decimal.h: New file.
Some notes on these.
I would arrange this as
* include/tr24732/decimal: New file.
> Index: libstdc++-v3/include/std/decimal
> ===================================================================
> --- libstdc++-v3/include/std/decimal (revision 0)
> +++ libstdc++-v3/include/std/decimal (revision 0)
> @@ -0,0 +1,461 @@
> +// Classes and inlines for the C++ decimal classes.
> +
> +// Copyright (C) 2009 Free Software Foundation, Inc.
> +// This file is part of the GNU ISO C++ Library. This library is
> free +// software; you can redistribute it and/or modify it under the
> +// terms of the GNU General Public License as published by the
> +// Free Software Foundation; either version 3, or (at your option)
> +// any later version.
> +
> +// This library is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +// GNU General Public License for more details.
> +
> +// Under Section 7 of GPL version 3, you are granted additional
> +// permissions described in the GCC Runtime Library Exception,
> version +// 3.1, as published by the Free Software Foundation.
> +
> +// You should have received a copy of the GNU General Public License
> and +// a copy of the GCC Runtime Library Exception along with this
> program; +// see the files COPYING3 and COPYING.RUNTIME
> respectively. If not, see +// <http://www.gnu.org/licenses/>.
> +
> +/** @file decimal
> + * This is a Standard C++ Library header.
> + */
> +
> +// ISO/IEC TR 24733
> +// Written by Janis Johnson <janis187@us.ibm.com>
> +
> +#ifndef _GLIBCXX_DECIMAL
> +#define _GLIBCXX_DECIMAL 1
> +
> +#pragma GCC system_header
> +
> +#include <bits/c++config.h>
> +
> +_GLIBCXX_BEGIN_NAMESPACE(std)
> +_GLIBCXX_BEGIN_NAMESPACE(decimal)
don't need to use these macros, just use namespace std, namespace
decimal.
Please add doxygen comments for namespace decimal so that it will show
up here:
http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html
> +
> + class decimal32;
> + class decimal64;
> + class decimal128;
> +
> + // ISO/IEC TR 24733 3.2.5 Initialization from coefficient and
> exponent.
> + static decimal32 make_decimal32 (long long coeff, int exponent);
> + static decimal32 make_decimal32 (unsigned long long coeff, int
> exponent);
> + static decimal64 make_decimal64 (long long coeff, int exponent);
> + static decimal64 make_decimal64 (unsigned long long coeff, int
> exponent);
> + static decimal128 make_decimal128 (long long coeff, int exponent);
> + static decimal128 make_decimal128 (unsigned long long coeff, int
> exponent); +
> + // Extension: Conversion to integral type.
> + long long decimal32_to_long_long (decimal32 d);
> + long long decimal64_to_long_long (decimal64 d);
> + long long decimal128_to_long_long (decimal128 d);
> + long long decimal_to_long_long (decimal32 d);
> + long long decimal_to_long_long (decimal64 d);
> + long long decimal_to_long_long (decimal128 d);
> +
> + // ISO/IEC TR 24733 3.2.6 Conversion to generic floating-point
> type.
> + float decimal32_to_float (decimal32 d);
> + float decimal64_to_float (decimal64 d);
> + float decimal128_to_float (decimal128 d);
> + float decimal_to_float (decimal32 d);
> + float decimal_to_float (decimal64 d);
> + float decimal_to_float (decimal128 d);
> +
> + double decimal32_to_double (decimal32 d);
> + double decimal64_to_double (decimal64 d);
> + double decimal128_to_double (decimal128 d);
> + double decimal_to_double (decimal32 d);
> + double decimal_to_double (decimal64 d);
> + double decimal_to_double (decimal128 d);
> +
> + long double decimal32_to_long_double (decimal32 d);
> + long double decimal64_to_long_double (decimal64 d);
> + long double decimal128_to_long_double (decimal128 d);
> + long double decimal_to_long_double (decimal32 d);
> + long double decimal_to_long_double (decimal64 d);
> + long double decimal_to_long_double (decimal128 d);
> +
I have real questions about this C compatibility.
From C++ N2849, usability intent remains obscured at least to me.
First, all these functions are declared with C++ linkage. Are C
programmers to call the mangled name? After including the C++ header
<decimal>? Why would any C programmer do this instead of
casting?
Second, overloaded functions like decimal_to_float, decimal_to_double,
decimal_to_long_double are not actionable within C. Only the explicitly
named functions like decimal32_to_float will be usable. Maybe this is
just a typo in the standard.
Third, mapping from C++ arg types decimal64 to _Decimal64 unclear.
Anyway.
?
Would probably arrange this differently.
include/tr24733/decimal
include/tr24733/decimal.h -- just C stuff if needed, ie conversions to
generic floating
include/tr24733/decimal_operators.h -- all the overloads.
best,
-benjamin