Topic: Defect Report: TR1/C++0x: fabs(complex<T>) redundant / wrongly specified


Author: pawig@hildesheim.sgh-net.de (Stefan =?iso-8859-1?Q?Gro=DFe?= Pawig)
Date: Sun, 24 Sep 2006 17:55:20 GMT
Raw View
  Hello all,

TR1 introduced, in the C compatibility chapter, the function
fabs(complex<T>):

----- SNIP -----
8.1.1 Synopsis                                [tr.c99.cmplx.syn]

  namespace std {
  namespace tr1 {
[...]
  template<class T> complex<T> fabs(const complex<T>& x);
  } // namespace tr1
  } // namespace std

[...]

8.1.8 Function fabs                          [tr.c99.cmplx.fabs]

1 Effects: Behaves the same as C99 function cabs, defined in
  subclause 7.3.8.1.
----- SNIP -----

The current C++0X draft document (n2009.pdf) adopted this
definition in chapter 26.3.1 (under the comment // 26.3.7 values)
and 26.3.7/7.

But in C99 (ISO/IEC 9899:1999 as well as the 9899:TC2 draft document
n1124), the referenced subclause reads

----- SNIP -----
7.3.8.1 The cabs functions

  Synopsis

1 #include <complex.h>
  double cabs(double complex z);
  float cabsf(float complex z);
  long double cabsl(long double z);

  Description

2 The cabs functions compute the complex absolute value (also called
  norm, modulus, or magnitude) of z.

  Returns

3 The cabs functions return the complex absolute value.
----- SNIP -----

Note that the return type of the cabs*() functions is not a complex
type.  Thus, they are equivalent to the already well established
  template<class T> T abs(const complex<T>& x);
(26.2.7/2 in ISO/IEC 14882:1998, 26.3.7/2 in the current draft
document n2009.pdf).

So either the return value of fabs() is specified wrongly, or fabs()
does not behave the same as C99's cabs*().

Proposed resolution:

This depends on the intention behind the introduction of fabs().

If the intention was to provide a /complex/ valued function that
calculates the magnitude of its argument, this should be
explicitly specified.  In TR1, the categorization under "C
compatibility" is definitely wrong, since C99 does not provide
such a complex valued function.

Also, it remains questionable if such a complex valued function
is really needed, since complex<T> supports construction and
assignment from real valued arguments.  There is no difference
in observable behaviour between

  complex<double> x, y;
  y = fabs(x);
  complex<double> z(fabs(x));

and

  complex<double> x, y;
  y = abs(x);
  complex<double> z(abs(x));

If on the other hand the intention was to provide the intended
functionality of C99, fabs() should be either declared deprecated
or (for C++0X) removed from the standard, since the functionality
is already provided by the corresponding overloads of abs().

  Regards,
    Stefan
--
Veni, vidi, VISA: I came, I saw, I did a little shopping

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: pawig@hildesheim.sgh-net.de (Stefan =?iso-8859-1?Q?Gro=DFe?= Pawig)
Date: Mon, 25 Sep 2006 20:42:17 GMT
Raw View
petebecker@acm.org (Pete Becker) wrote:
> Stefan Gro=DFe Pawig wrote:
>> fabs() should be either declared deprecated
>> or (for C++0X) removed from the standard, since the functionality
>> is already provided by the corresponding overloads of abs().
>>
>
> That's a bit too drastic, since it would mean that C code using fabs
> would have to be modified.

Oh, sorry for being unclear.  I did not mean to deprecate or remove
fabs() as a whole, but only the fabs(const complex<T>&) overload
introduced in TR1.  This should not effect any C code at all.
(Or am I missing something?)

But of course there may also be C++ code out there that uses
fabs(const complex<T>&), which would have to be modified.

Nevertheless, if the return type of fabs(const complex<T>&) is
changed from complex<T> to T, this leaves us with two functions
that do exactly the same:
  T abs(const complex<T>&)  and
  T fabs(const complex<T>&).

If deprecation or removal are still too drastic, I think at least
a clarifying note in the standard would be in order. ;-)

  Regards,
    Stefan
--=20
NOTICE: Due to budgetary constraints the light at the end of the
tunnel will be turned off until further notice

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]