Title
TR1/C++0x: fabs(complex<T>) redundant / wrongly specified
Status
cd1
Section
[complex.value.ops]
Submitter
Stefan Große Pawig

Created on 2006-09-24.00:00:00 last changed 171 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Change the synopsis in [complex.syn]:

template<class T> complex<T> fabs(const complex<T>&);

Remove [complex.value.ops], p7:

template<class T> complex<T> fabs(const complex<T>& x);

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

Date: 2010-10-21.18:28:33

[ Bellevue: ]

Bill believes that abs() is a suitable overload. We should remove fabs().

Date: 2006-09-24.00:00:00

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*().

Possible Resolutions

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().

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg3174
2010-10-21 18:28:33adminsetmessages: + msg3173
2006-09-24 00:00:00admincreate