Boost logo

Boost :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-01-10 18:00:24

----- Original Message -----
From: "Ralf W. Grosse-Kunstleve" <rwgk_at_[hidden]>

> - The real world problem is indeed compatibility with
> existing C or FORTRAN code.
> - For in-place FFT's it is only necessary to cast a pointer
> to the beginning of a vector (in the general sense) of
> std::complex to a pointer to the beginning of a
> vector of real numbers (e.g. float or double).
> I.e., essentially memory is reused for different types
> without actually caring about the conversions between
> the types. Using reinterpret_cast<> for this purpose
> seems perfectly OK.

Except that it's not portable. There's no guarantee that the compiler
doesn't insert padding in a complex. It doesn't even have to use the
cartesian representation internally, but that's fixable without a core
language change.

> Regarding compatibility with existing C code:
> C does not have a complex type.

C99 does, AFAIK.

> FFTW (e.g.) introduces
> its own type. I guess it is next to impossible to ensure
> portable conversions from std::complex to custom types
> like FFTW's.

As the language is currently defined, yes.

> Regarding compatibility with existing FORTRAN code:
> AFAIK FORTRAN COMPLEX are by definition stored as
> consecutive real values, real part first, imaginary
> part second. Here it would help if std::complex
> was derived from boost::array<T, 2>.

Doesn't FFTW use an equivalent representation?
struct { float re, im; }; is an example of one.

> My proposal was (message 22021 in this group):
> template <class T> class complex : public boost::array<T, 2> {
> //...
> };
> complex<double> c;
> double* a = c.elems;
> No cast required.
> Not even for reusing memory in an in-place FFT procedure.

Because complex has a base class, it is now a non-POD type.

  complex<double>* storage = new complex<double>[128];
  double* a = storage->elems;
  double crash = a[2]; // undefined behavior

The requirements for PODs, distilled from the standard, are:

A POD-struct is an aggregate class that has no non-static data members
of type pointer to member, non-POD-struct, non-POD-union (or array of
such types) or reference, and has no user-defined copy assign- ment
operator and no user-defined destructor. Similarly, a POD-union is an
aggregate union that has no non-static data members of type pointer to
member, non-POD-struct, non-POD-union (or array of such types) or
reference, and has no user-defined copy assignment operator and no
user-defined destructor. A POD class is a class that is either a
POD-struct or a POD-union.

An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions

> This would work portably with FORTRAN code, and, more
> importantly, code that is ported from FORTRAN to C++ (such
> as my fftbx posted here earlier).

I'm afraid not :(

> My proposal is compatible with all existing implementations
> of std::complex that I know about, but formalizes
> assumptions that are commonly made in practice (this should
> include the assumption that the complex value is internally
> represented as a real and an imaginary part, as opposed to,
> e.g. an amplitude and an angle).

And a few others.

> It does not, however (as I realize now), improve
> portability when using C code such as FFTW from C++. (But
> then again, it would be easy to modify the C header file to
> derive the custom type from std::complex if compiled with
> C++).

Hmm. I'm not sure that's so easy. Besides, many people don't have access to
the source code of the libraries they use, or are unwilling to rebuild them.


Boost list run by bdawes at, gregod at, cpdaniel at, john at