Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ complex.h protability

82 views
Skip to first unread message

Marcel Mueller

unread,
Feb 21, 2016, 9:23:17 AM2/21/16
to
I have some compatibility issues regarding complex.h in an FFTW3
application.

In fact older C++ compilers required the include files with the .h
extension (and no namespace std::), i.e.
#include <math.h>
#include <complex.h>
This is deprecated but so far all relevant compilers supported the old
header files for compatibility. The code is quite old (~15 years) and
not namespace aware. I only upgraded to FFTW3 several years ago.

But now I try to switch to a newer compiler (gcc 4.8) and this raises a
conflict with the C99 compatibility header complex.h. Of course, this
does not support the resulting type definition in fftw3.h (compiled with -E)
typedef __complex__<long double> fftwl_complex;

The fftw3.h behaves differently when included from C++. This is an
application specific patch.

#ifdef __cplusplus
/* In C++ mode prefer class complex<> */
#include <complex.h>
# define FFTW_DEFINE_COMPLEX(R, C) typedef complex<R> C
extern "C"
{
#else /* __cplusplus */
/* If <complex.h> is included, use the C99 complex type. Otherwise
define a type bit-compatible with C99 complex */
#ifdef _Complex_I
# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
#else
# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
#endif
#endif /* __cplusplus */

This worked with older gcc 3.x, IBM icc and AFAIK Watcom.

Is there an option to bring the old C++ complex.h compatibility back?

I tried

#include <complex>
using std::complex;

It seems to compile, but I am in doubt whether it is a good idea to mix
old style and new style headers within a single compilation unit.

Any suggestions, other than reworking all the old code for newer
standard compliance?


Marcel

Alf P. Steinbach

unread,
Feb 21, 2016, 10:49:06 AM2/21/16
to
On 21.02.2016 15:22, Marcel Mueller wrote:
> I have some compatibility issues regarding complex.h in an FFTW3
> application.
>
> In fact older C++ compilers required the include files with the .h
> extension (and no namespace std::), i.e.
> #include <math.h>
> #include <complex.h>

I believe the requirement had to be imposed by the FFTW3 headers.

No compilers can have imposed this requirement.


> This is deprecated but so far all relevant compilers supported the old
> header files for compatibility. The code is quite old (~15 years) and
> not namespace aware. I only upgraded to FFTW3 several years ago.
>
> But now I try to switch to a newer compiler (gcc 4.8) and this raises a
> conflict with the C99 compatibility header complex.h. Of course, this
> does not support the resulting type definition in fftw3.h (compiled with
> -E)
> typedef __complex__<long double> fftwl_complex;
>
> The fftw3.h behaves differently when included from C++. This is an
> application specific patch.
>
> #ifdef __cplusplus
> /* In C++ mode prefer class complex<> */
> #include <complex.h>
> # define FFTW_DEFINE_COMPLEX(R, C) typedef complex<R> C

This is wrong in two ways:

• Include of `<complex.h>`
It doesn't define the name used. Should be just `<complex>`.

• Use of unqualified template `complex`.
Should be `std::complex`.


> extern "C"
> {
> #else /* __cplusplus */
> /* If <complex.h> is included, use the C99 complex type. Otherwise
> define a type bit-compatible with C99 complex */
> #ifdef _Complex_I
> # define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
> #else
> # define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
> #endif
> #endif /* __cplusplus */

This is a bit sloppy, and the comment is wrong, but should work.

Conclusion so far is that FFTW3 is coded by programmers who make trivial
errors all over the place – so that where it works, it probably works
by happenchance.


> This worked with older gcc 3.x, IBM icc and AFAIK Watcom.
>
> Is there an option to bring the old C++ complex.h compatibility back?
>
> I tried
>
> #include <complex>
> using std::complex;
>
> It seems to compile, but I am in doubt whether it is a good idea to mix
> old style and new style headers within a single compilation unit.

Above code is perfectly OK in an implementation file.

In the global namespace in a header the `using std::complex` can lead to
unintended name collisions.


> Any suggestions, other than reworking all the old code for newer
> standard compliance?

I suggest switching to another FFT-library, one that works. :)

Barring that, submit a patch the fixes the errors noted above, and just
hope that not too much more will go wrong.


Cheers & hth.,

- Alf

Marcel Mueller

unread,
Feb 21, 2016, 2:03:18 PM2/21/16
to
On 21.02.16 16.48, Alf P. Steinbach wrote:
>> In fact older C++ compilers required the include files with the .h
>> extension (and no namespace std::), i.e.
>> #include <math.h>
>> #include <complex.h>
>
> I believe the requirement had to be imposed by the FFTW3 headers.
>
> No compilers can have imposed this requirement.

15 to 20 years ago all you get by #include <math> was "File not found".
I don't remember exactly when the new headers came.


>> #ifdef __cplusplus
>> /* In C++ mode prefer class complex<> */
>> #include <complex.h>
>> # define FFTW_DEFINE_COMPLEX(R, C) typedef complex<R> C
>
> This is wrong in two ways:
>
> • Include of `<complex.h>`
> It doesn't define the name used. Should be just `<complex>`.
>
> • Use of unqualified template `complex`.
> Should be `std::complex`.

Earlier C++ compilers required exactly this syntax.

> Conclusion so far is that FFTW3 is coded by programmers who make trivial
> errors all over the place – so that where it works, it probably works
> by happenchance.

You should be careful and not blame the FFTW programmers for a patch
that is part of the application code.
The lines with the #ifdef __cplusplus are a hack specific to this
application to make the C++ application work reasonably with FFTW
without the need for dirty reinterpret casts all the way. Older C++
compilers did not support C99 _Complex, and the fallback to C[2] is
really ugly, since it makes trivial mathematical operations like
multiplication unreadable.

>> #include <complex>
>> using std::complex;
>>
>> It seems to compile, but I am in doubt whether it is a good idea to mix
>> old style and new style headers within a single compilation unit.
>
> Above code is perfectly OK in an implementation file.
>
> In the global namespace in a header the `using std::complex` can lead to
> unintended name collisions.

The entire application code is not aware of namespaces. Probably the
keyword "namespace" does not even exist once. As I already mentioned, it
is quite old code.

>> Any suggestions, other than reworking all the old code for newer
>> standard compliance?
>
> I suggest switching to another FFT-library, one that works. :)

FFTW works quite perfectly so far and it is really fast. For sure I will
not reinvent the wheel because of minor problems like this.


Marcel

Jerry Stuckle

unread,
Feb 21, 2016, 2:26:03 PM2/21/16
to
On 2/21/2016 2:02 PM, Marcel Mueller wrote:
> On 21.02.16 16.48, Alf P. Steinbach wrote:
>>> In fact older C++ compilers required the include files with the .h
>>> extension (and no namespace std::), i.e.
>>> #include <math.h>
>>> #include <complex.h>
>>
>> I believe the requirement had to be imposed by the FFTW3 headers.
>>
>> No compilers can have imposed this requirement.
>
> 15 to 20 years ago all you get by #include <math> was "File not found".
> I don't remember exactly when the new headers came.
>

That's because 15 to 20 years ago the file "math" did not exist.

>
>>> #ifdef __cplusplus
>>> /* In C++ mode prefer class complex<> */
>>> #include <complex.h>
>>> # define FFTW_DEFINE_COMPLEX(R, C) typedef complex<R> C
>>
>> This is wrong in two ways:
>>
>> • Include of `<complex.h>`
>> It doesn't define the name used. Should be just `<complex>`.
>>
>> • Use of unqualified template `complex`.
>> Should be `std::complex`.
>
> Earlier C++ compilers required exactly this syntax.
>

Wrong, wrong, wrong. All C compilers from the very beginning just
included whatever file was listed.

#include <abc.xyz>

would work if there was a file abc.xyz in the path. The *convention* at
the time was to have header files with an extension of .h. But it was
*never* a compiler requirement.

>> Conclusion so far is that FFTW3 is coded by programmers who make trivial
>> errors all over the place – so that where it works, it probably works
>> by happenchance.
>
> You should be careful and not blame the FFTW programmers for a patch
> that is part of the application code.
> The lines with the #ifdef __cplusplus are a hack specific to this
> application to make the C++ application work reasonably with FFTW
> without the need for dirty reinterpret casts all the way. Older C++
> compilers did not support C99 _Complex, and the fallback to C[2] is
> really ugly, since it makes trivial mathematical operations like
> multiplication unreadable.
>
>>> #include <complex>
>>> using std::complex;
>>>
>>> It seems to compile, but I am in doubt whether it is a good idea to mix
>>> old style and new style headers within a single compilation unit.
>>
>> Above code is perfectly OK in an implementation file.
>>
>> In the global namespace in a header the `using std::complex` can lead to
>> unintended name collisions.
>
> The entire application code is not aware of namespaces. Probably the
> keyword "namespace" does not even exist once. As I already mentioned, it
> is quite old code.
>

"namespace" has existed for at least 25 years. I'm not sure exactly
which standard had it first, but we were using it in the early 90's. If
your code is older than that, then it probably needs rewriting.

>>> Any suggestions, other than reworking all the old code for newer
>>> standard compliance?
>>
>> I suggest switching to another FFT-library, one that works. :)
>
> FFTW works quite perfectly so far and it is really fast. For sure I will
> not reinvent the wheel because of minor problems like this.
>
>
> Marcel

No problem - you're the only one it affects.

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Ian Collins

unread,
Feb 21, 2016, 3:00:38 PM2/21/16
to
Marcel Mueller wrote:
> I have some compatibility issues regarding complex.h in an FFTW3
> application.
>
> In fact older C++ compilers required the include files with the .h
> extension (and no namespace std::), i.e.
> #include <math.h>
> #include <complex.h>
> This is deprecated but so far all relevant compilers supported the old
> header files for compatibility. The code is quite old (~15 years) and
> not namespace aware. I only upgraded to FFTW3 several years ago.
>
> But now I try to switch to a newer compiler (gcc 4.8) and this raises a
> conflict with the C99 compatibility header complex.h. Of course, this
> does not support the resulting type definition in fftw3.h (compiled with -E)
> typedef __complex__<long double> fftwl_complex;
>
> The fftw3.h behaves differently when included from C++. This is an
> application specific patch.
>
> #ifdef __cplusplus
> /* In C++ mode prefer class complex<> */
> #include <complex.h>
> # define FFTW_DEFINE_COMPLEX(R, C) typedef complex<R> C

What happens if you change these two lines to:

#include <complex>
# define FFTW_DEFINE_COMPLEX(R, C) typedef std::complex<R> C

or

# define FFTW_DEFINE_COMPLEX(R, C) using C = std::complex<R>

if you are using C++ >= 11.

?

--
Ian Collins

Alf P. Steinbach

unread,
Feb 21, 2016, 4:06:11 PM2/21/16
to
On 21.02.2016 20:02, Marcel Mueller wrote:
> On 21.02.16 16.48, Alf P. Steinbach wrote:
>>> In fact older C++ compilers required the include files with the .h
>>> extension (and no namespace std::), i.e.
>>> #include <math.h>
>>> #include <complex.h>
>>
>> I believe the requirement had to be imposed by the FFTW3 headers.
>>
>> No compilers can have imposed this requirement.
>
> 15 to 20 years ago all you get by #include <math> was "File not found".

There is no standard library header <math> and never has been.

There is a C++ standard library header <complex>. It's different from
<ccomplex> and <complex.h>.

In the same vein, the C++ header <string> is different from <cstring>
and <string.h>.



> I don't remember exactly when the new headers came.

With the C++ standardization in 1998.


>>> #ifdef __cplusplus
>>> /* In C++ mode prefer class complex<> */
>>> #include <complex.h>
>>> # define FFTW_DEFINE_COMPLEX(R, C) typedef complex<R> C
>>
>> This is wrong in two ways:
>>
>> • Include of `<complex.h>`
>> It doesn't define the name used. Should be just `<complex>`.
>>
>> • Use of unqualified template `complex`.
>> Should be `std::complex`.
>
> Earlier C++ compilers required exactly this syntax.

No, they couldn't, because the C++ <complex> header, providing the
`std::complex` class template, is an entirely different beast than the
<ccomplex> and <complex.h> headers, which provide C style stuff.


>> Conclusion so far is that FFTW3 is coded by programmers who make trivial
>> errors all over the place – so that where it works, it probably works
>> by happenchance.
>
> You should be careful and not blame the FFTW programmers for a patch
> that is part of the application code.

Well, then it's the application code programmers. ;-)

That affects the conclusion about what to do, yes.


> The lines with the #ifdef __cplusplus are a hack specific to this
> application to make the C++ application work reasonably with FFTW
> without the need for dirty reinterpret casts all the way. Older C++
> compilers did not support C99 _Complex, and the fallback to C[2] is
> really ugly, since it makes trivial mathematical operations like
> multiplication unreadable.

Do you really need to support C89/C90 compilers?

Is it really the case that someone has not upgraded their compiler
version since 1999, can't be told to do that, and are IMPORTANT?

Maybe this problem is more of a people & politics problem than a
technical one?

Marcel Mueller

unread,
Feb 21, 2016, 5:43:59 PM2/21/16
to
On 21.02.16 20.25, Jerry Stuckle wrote:
>> Earlier C++ compilers required exactly this syntax.
>
> Wrong, wrong, wrong. All C compilers from the very beginning just
> included whatever file was listed.

s/compiler/runtime/;

>>> In the global namespace in a header the `using std::complex` can lead to
>>> unintended name collisions.
>>
>> The entire application code is not aware of namespaces. Probably the
>> keyword "namespace" does not even exist once. As I already mentioned, it
>> is quite old code.
>
> "namespace" has existed for at least 25 years. I'm not sure exactly
> which standard had it first, but we were using it in the early 90's.

All my complilers from the mid 90's can't deal with namespaces. Neither
Borland supported them nor IBM VAC++ and AFAIR gcc 2.9.5 did not support
it either.

And well, from the release of a standard to the point where you can
really use a feature are often years. I recently got complaints about
C++11 code because still some common Linux Distros do not support it
because they use gcc 4.7 which at least requires a compiler option and
even with this option sometimes it does not work.

> If
> your code is older than that, then it probably needs rewriting.

No, it is only about 15 years old. But some of the supported compilers
did not know about namespaces at this time.


Marcel

Marcel Mueller

unread,
Feb 21, 2016, 5:51:43 PM2/21/16
to
On 21.02.16 21.00, Ian Collins wrote:
> What happens if you change these two lines to:
>
> #include <complex>
> # define FFTW_DEFINE_COMPLEX(R, C) typedef std::complex<R> C

This might work. I have to test it. I have to check whether the code
references the type complex<> directly somewhere else.
If it works it is the best solution so far.

> or
>
> # define FFTW_DEFINE_COMPLEX(R, C) using C = std::complex<R>
>
> if you are using C++ >= 11.

No, I should not depend on C++11. Currently gcc from 3.3.5 and up is
supported. C++11 requires 4.8, which has only experimental support on
the target platform.

By the way, what is the difference between typedef and using in this
context?


Marcel

Öö Tiib

unread,
Feb 21, 2016, 6:41:39 PM2/21/16
to
No differences in that context. (7.1.3.2): ... It has the same semantics
as if it were introduced by the typedef specifier. ...

Lot of programmers prefer 'using' because alias declaration is superset
of 'typedef' specifier and it is considered easier to read.


typedef void meh_t();

using doh_t = void();

static_assert(std::is_same<meh_t,doh_t>(), "should be no difference");

Alf P. Steinbach

unread,
Feb 21, 2016, 6:50:28 PM2/21/16
to
On 21.02.2016 23:51, Marcel Mueller wrote:
> On 21.02.16 21.00, Ian Collins wrote:
>> What happens if you change these two lines to:
>>
>> #include <complex>
>> # define FFTW_DEFINE_COMPLEX(R, C) typedef std::complex<R> C
>
> This might work. I have to test it. I have to check whether the code
> references the type complex<> directly somewhere else.
> If it works it is the best solution so far.

Such a direct technical fix can appear to be best, but when I offered
this purely technical solution in the first follow up to your posting
(Ian's presentation of what to write nicely complemented my earlier
explanation of what to fix and how – I forgot to make that concrete!),


> • Include of `<complex.h>`
> It doesn't define the name used. Should be just `<complex>`.
>
> • Use of unqualified template `complex`.
> Should be `std::complex`.


… I went on to mention some higher level solutions.

These solutions include ditching the current approach, and at an even
higher level, they include considering whether the driving constraints
for the problem, e.g. support for early 1990's compilers, stem from e.g.
a sociopolitical issue, or really a purely technical issue.


> [snip]
> By the way, what is the difference between typedef and using in this
> context?

Only clarity of notation.

Which I think is important. ;-)

Jerry Stuckle

unread,
Feb 21, 2016, 8:44:15 PM2/21/16
to
On 2/21/2016 5:43 PM, Marcel Mueller wrote:
> On 21.02.16 20.25, Jerry Stuckle wrote:
>>> Earlier C++ compilers required exactly this syntax.
>>
>> Wrong, wrong, wrong. All C compilers from the very beginning just
>> included whatever file was listed.
>
> s/compiler/runtime/;
>

Wrong. Compilers. Header files have nothing to do with runtime.

>>>> In the global namespace in a header the `using std::complex` can
>>>> lead to
>>>> unintended name collisions.
>>>
>>> The entire application code is not aware of namespaces. Probably the
>>> keyword "namespace" does not even exist once. As I already mentioned, it
>>> is quite old code.
>>
>> "namespace" has existed for at least 25 years. I'm not sure exactly
>> which standard had it first, but we were using it in the early 90's.
>
> All my complilers from the mid 90's can't deal with namespaces. Neither
> Borland supported them nor IBM VAC++ and AFAIR gcc 2.9.5 did not support
> it either.
>

Sorry you had compilers which were not standards compliant. That does
not mean it wasn't part of the standard.

> And well, from the release of a standard to the point where you can
> really use a feature are often years. I recently got complaints about
> C++11 code because still some common Linux Distros do not support it
> because they use gcc 4.7 which at least requires a compiler option and
> even with this option sometimes it does not work.
>

Yes, it takes time for compiler developers to write code. Whether the
compiler is up to date with the standard or the distro includes a
standards-compliant compiler is immaterial to whether the item is part
of the standard or not.

>> If
>> your code is older than that, then it probably needs rewriting.
>
> No, it is only about 15 years old. But some of the supported compilers
> did not know about namespaces at this time.
>
>
> Marcel

It's not anyone else's fault that you were using non-standards compliant
compilers. Namespaces were in the standard, and there were compilers
supporting it.

Christian Gollwitzer

unread,
Feb 22, 2016, 2:16:37 AM2/22/16
to
Am 21.02.16 um 16:48 schrieb Alf P. Steinbach:
I'm not sure how serious you are with this suggestion. For one thing,
FFTW is /the/ FFT library, because it uses a superoptimization approach
to achieve very high performance. Especially if you need lengths which
are not powers of 2, FFTW is hard to beat.

Second, I haven't seen a library which does not define its own complex
numbers, because a long time in the C/C++ world complex numbers were not
supported overly well, as opposed to Fortran. Just a few weeks ago, we
found that neither gcc nor clang can vectorize loops with complex
numbers. All 3rd party libraries I know of use a

struct mycomplex { double real; double imag; }

It is nonsense to make these members private in <complex> with trivial
getters and setters. I have never seen an implementation which uses
polar coordinates or the like.

Christian

Robert Wessel

unread,
Feb 22, 2016, 3:54:56 AM2/22/16
to
On Sun, 21 Feb 2016 14:25:50 -0500, Jerry Stuckle
<jstu...@attglobal.net> wrote:

>Wrong, wrong, wrong. All C compilers from the very beginning just
>included whatever file was listed.
>
>#include <abc.xyz>
>
>would work if there was a file abc.xyz in the path. The *convention* at
>the time was to have header files with an extension of .h. But it was
>*never* a compiler requirement.

That's at least partially incorrect. Early (pre-Unix System Services)
C compilers for MVS would not, mainly because there was no way to
specify an extension (including a ".H") on the actual source member
being included. The ".H" would be dropped, and the file would be
searched for from a list of (usually) PDS's defined in the search list
(and usually two separate lists for system and user includes).

Öö Tiib

unread,
Feb 22, 2016, 5:06:51 AM2/22/16
to
On Monday, 22 February 2016 09:16:37 UTC+2, Christian Gollwitzer wrote:
> Am 21.02.16 um 16:48 schrieb Alf P. Steinbach:
> > On 21.02.2016 15:22, Marcel Mueller wrote:
> >> Any suggestions, other than reworking all the old code for newer
> >> standard compliance?
> >
> > I suggest switching to another FFT-library, one that works. :)
> >
>
> I'm not sure how serious you are with this suggestion.

Smiley indicates that it was not serious suggestion. Serious suggestion
(that you snipped) seemed to be to fix FFTW and to submit a patch to it.

Marcel Mueller

unread,
Feb 22, 2016, 1:38:40 PM2/22/16
to
On 22.02.16 02.44, Jerry Stuckle wrote:
> It's not anyone else's fault that you were using non-standards compliant
> compilers.

I enumerated *all existing* compilers for the platform at this time in
the past.

> Namespaces were in the standard, and there were compilers
> supporting it.

In theory.


Marcel

Jerry Stuckle

unread,
Feb 22, 2016, 2:15:07 PM2/22/16
to
In practice. I used them. Both on Windows and Linux/Unix.

Cholo Lennon

unread,
Feb 22, 2016, 2:36:58 PM2/22/16
to
On 02/21/2016 10:44 PM, Jerry Stuckle wrote:
> On 2/21/2016 5:43 PM, Marcel Mueller wrote:
>> On 21.02.16 20.25, Jerry Stuckle wrote:
>>>> Earlier C++ compilers required exactly this syntax.
>>>
>>> Wrong, wrong, wrong. All C compilers from the very beginning just
>>> included whatever file was listed.
>>
>> s/compiler/runtime/;
>>
>
> Wrong. Compilers. Header files have nothing to do with runtime.
>
>>>>> In the global namespace in a header the `using std::complex` can
>>>>> lead to
>>>>> unintended name collisions.
>>>>
>>>> The entire application code is not aware of namespaces. Probably the
>>>> keyword "namespace" does not even exist once. As I already mentioned, it
>>>> is quite old code.
>>>
>>> "namespace" has existed for at least 25 years. I'm not sure exactly
>>> which standard had it first, but we were using it in the early 90's.
>>
>> All my complilers from the mid 90's can't deal with namespaces. Neither
>> Borland supported them nor IBM VAC++ and AFAIR gcc 2.9.5 did not support
>> it either.
>>
>
> Sorry you had compilers which were not standards compliant. That does
> not mean it wasn't part of the standard.
>

It's depends on what you define as C++ standard. Normally we tend to use
the ISO C++ as a reference (1998 or later). The ARM document (where
namespaces are described) is not considered "the" C++ standard.

BTW, what was your compiler that implemented namespaces in the early
90's? As Marcel Mueller said, my compilers in those years didn't have
support for namepaces (Borland/Microsoft)


>> And well, from the release of a standard to the point where you can
>> really use a feature are often years. I recently got complaints about
>> C++11 code because still some common Linux Distros do not support it
>> because they use gcc 4.7 which at least requires a compiler option and
>> even with this option sometimes it does not work.
>>
>
> Yes, it takes time for compiler developers to write code. Whether the
> compiler is up to date with the standard or the distro includes a
> standards-compliant compiler is immaterial to whether the item is part
> of the standard or not.
>
>>> If
>>> your code is older than that, then it probably needs rewriting.
>>
>> No, it is only about 15 years old. But some of the supported compilers
>> did not know about namespaces at this time.
>>
>>
>> Marcel
>
> It's not anyone else's fault that you were using non-standards compliant
> compilers. Namespaces were in the standard, and there were compilers
> supporting it.
>


--
Cholo Lennon
Bs.As.
ARG

Ian Collins

unread,
Feb 22, 2016, 2:54:01 PM2/22/16
to
Cholo Lennon wrote:
> On 02/21/2016 10:44 PM, Jerry Stuckle wrote:
>> On 2/21/2016 5:43 PM, Marcel Mueller wrote:
>>> On 21.02.16 20.25, Jerry Stuckle wrote:
>>>>
>>>> "namespace" has existed for at least 25 years. I'm not sure exactly
>>>> which standard had it first, but we were using it in the early 90's.
>>>
>>> All my complilers from the mid 90's can't deal with namespaces. Neither
>>> Borland supported them nor IBM VAC++ and AFAIR gcc 2.9.5 did not support
>>> it either.
>>>
>>
>> Sorry you had compilers which were not standards compliant. That does
>> not mean it wasn't part of the standard.
>>
>
> It's depends on what you define as C++ standard. Normally we tend to use
> the ISO C++ as a reference (1998 or later). The ARM document (where
> namespaces are described) is not considered "the" C++ standard.

There weren't any standards compliant compilers in the early 90s because
there wasn't a standard!

--
Ian Collins

Cholo Lennon

unread,
Feb 22, 2016, 3:03:13 PM2/22/16
to
Well, that was I was trying to say (in a complex manner btw) ;-)

Regards

Jerry Stuckle

unread,
Feb 22, 2016, 3:16:28 PM2/22/16
to
Just because there wasn't an ISO standard at the time doesn't mean there
wasn't a standard. It started with Stroustrup's book. Modifications
followed from that.

People think that ISO is the only organization which can issue
standards. Nothing is further from the truth. If they come out with a
standard, it is generally recognized world-wide. But when they haven't,
there can still be standards.

Alf P. Steinbach

unread,
Feb 22, 2016, 3:38:20 PM2/22/16
to
On 22.02.2016 21:16, Jerry Stuckle wrote:
> On 2/22/2016 2:53 PM, Ian Collins wrote:
>>>
>>> It's depends on what you define as C++ standard. Normally we tend to use
>>> the ISO C++ as a reference (1998 or later). The ARM document (where
>>> namespaces are described) is not considered "the" C++ standard.
>>
>> There weren't any standards compliant compilers in the early 90s because
>> there wasn't a standard!
>>
>
> Just because there wasn't an ISO standard at the time doesn't mean there
> wasn't a standard. It started with Stroustrup's book. Modifications
> followed from that.

I agree that Bjarne's TCPPL and later Bjarne and Margaret's ARM (the
Annotated Reference Manual) constituted the effective C++ standards at
the time, before 1998, just as Brian and Dennis' TCPL constituted the
effective C standard before C89/C90.

Re existence of pre 1998 namespaces, my copy of the ARM is deep down in
some unmarked box in an attic some miles from here, and likewise my copy
of Visual C++ 1.5. Yes AFAIK I still have that. But given the relatively
low accessibility of those items, and my generally vague memory, I can't
say for sure.

Oh, wait! Talk about bad memory, I forgot GOOGLE! Yay, Mr. Google found
the following 1994 Dr Dobbs article in zero point 38 seconds:

<url: http://www.drdobbs.com/cpp/c-namespaces/184409289>

So, this should now be regarded as solved.

C++ had namespaces at least as early as 1994.

In that article Tom Penelli refers to them as “so new [a feature]”, so
presumably they were a post ARM feature. As I recall the ARM was
published in 1989. But that can of course also be checked with Mr.
Google, who knows all. :)


> People think that ISO is the only organization which can issue
> standards. Nothing is further from the truth. If they come out with a
> standard, it is generally recognized world-wide. But when they haven't,
> there can still be standards.

Yeah, right again.

I remember having countless discussions about this with the late Erik
Naggum (RIP., there is a Wikipedia page about him for those unfamiliar
with the name), who insisted on very formal distinctions between formal
standard, de facto standard and so on, more shades that I don't remember
because it's never been an issue except with him. “Standard in Windows”,
he cried, and would ask me to point him to the formal ISO standard that
I referred to, which of course I didn't, although now, much later, I
could point him to the 1995 ECMA standardization of the 16-bit Windows
API, I guess. Anyway. The important thing about generally useful
communication is to be understood, not to pedantically try to
misconstrue every statement. Erik was right that precision matters wrt.
technical stuff, and generally he was just right about most everything
technical. But IMHO he went too far, too rigid.

Öö Tiib

unread,
Feb 22, 2016, 3:48:17 PM2/22/16
to
Can you name the mysterious compiler? There was lot of talk of it but
nothing supported it. First C++ that gave *warning* about usage of
'namespace' as variable name was CFront 3.0.3 released May 1994. It also
did not yet have 'namespace' implemented, instead the README told that:

The identifier names "mutable", "namespace", and "using" will
now trigger a warning when they are used as identifiers.
For example:

int namespace = 37;

This is because they are future keywords for the ANSI C++ language
namespace feature.

Cholo Lennon

unread,
Feb 22, 2016, 3:50:57 PM2/22/16
to
Check this, namespaces are in the 1990 ARM document (is not the best
source because the ARM is not there, but the chronology could be helpful)

http://en.cppreference.com/w/cpp/language/history


>
>> People think that ISO is the only organization which can issue
>> standards. Nothing is further from the truth. If they come out with a
>> standard, it is generally recognized world-wide. But when they haven't,
>> there can still be standards.
>
> Yeah, right again.
>
> I remember having countless discussions about this with the late Erik
> Naggum (RIP., there is a Wikipedia page about him for those unfamiliar
> with the name), who insisted on very formal distinctions between formal
> standard, de facto standard and so on, more shades that I don't remember
> because it's never been an issue except with him. “Standard in Windows”,
> he cried, and would ask me to point him to the formal ISO standard that
> I referred to, which of course I didn't, although now, much later, I
> could point him to the 1995 ECMA standardization of the 16-bit Windows
> API, I guess. Anyway. The important thing about generally useful
> communication is to be understood, not to pedantically try to
> misconstrue every statement. Erik was right that precision matters wrt.
> technical stuff, and generally he was just right about most everything
> technical. But IMHO he went too far, too rigid.
>
>
> Cheers & hth.,
>
> - Alf
>


Cholo Lennon

unread,
Feb 22, 2016, 4:09:57 PM2/22/16
to
Reading again "The Design & Evolution of C++", chapter 17 "Namespaces",
Stroustroup says the following:

"Namespaces were voted into C++ at the Munich meeting in July 1993"

Jerry Stuckle

unread,
Feb 22, 2016, 4:19:07 PM2/22/16
to
IBM's Visual C++ compiler for OS/2 and Windows did, for one. I don't
remember off hand what Linux compilers we used way back then.

And IIRC, even Microsoft Visual C++ 6.something supported them. But I
haven't used it for 15 years or more.

Richard

unread,
Feb 22, 2016, 4:20:24 PM2/22/16
to
[Please do not mail me a copy of your followup]

"Alf P. Steinbach" <alf.p.stein...@gmail.com> spake the secret code
<nafrds$ph8$1...@dont-email.me> thusly:

>C++ had namespaces at least as early as 1994.

SGI's MIPSpro 7.2 compiler had them in 1995
<http://techpubs.sgi.com/library/manuals/0000/007-0704-120/pdf/007-0704-120.pdf>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Öö Tiib

unread,
Feb 22, 2016, 4:51:46 PM2/22/16
to
IBM VisualAge C++ added namespace support 2003 AFAIK, at 2000 it did
have templates but no namespaces.

>
> And IIRC, even Microsoft Visual C++ 6.something supported them. But I
> haven't used it for 15 years or more.

Yes, I remember it, it had first nice IDE from MS and come shortly after
first working OS from MS (NT 4.0). It was released in 1998.

So how you could use those early nineties?

Jerry Stuckle

unread,
Feb 22, 2016, 4:58:17 PM2/22/16
to
VisualAge C++ for OS/2 and Windows didn't even exist in 2003. It had
been dropped several years before that. I don't remember exactly when,
though.

>>
>> And IIRC, even Microsoft Visual C++ 6.something supported them. But I
>> haven't used it for 15 years or more.
>
> Yes, I remember it, it had first nice IDE from MS and come shortly after
> first working OS from MS (NT 4.0). It was released in 1998.
>
> So how you could use those early nineties?
>

Visual C++ came out long before 1998.

Richard

unread,
Feb 22, 2016, 5:16:31 PM2/22/16
to
[Please do not mail me a copy of your followup]

Jerry Stuckle <jstu...@attglobal.net> spake the secret code
<nag03g$b68$1...@jstuckle.eternal-september.org> thusly:

>Visual C++ came out long before 1998.

<https://en.wikipedia.org/wiki/Visual_C%2B%2B>

Visual C++ 1.0 was released in 1993. The first C++ compiler was 1992.
The C compiler was introduced in 1983.

Öö Tiib

unread,
Feb 22, 2016, 6:09:33 PM2/22/16
to
OS/2 was long dead indeed but that VisualAge crap did still smoulder
here and there. At 2000 its C++ certainly did not have namespaces. I trust
it was 2011 when VisualAge was finally dropped and replaced with
XL C/C++ by IBM.

>
> >>
> >> And IIRC, even Microsoft Visual C++ 6.something supported them. But I
> >> haven't used it for 15 years or more.
> >
> > Yes, I remember it, it had first nice IDE from MS and come shortly after
> > first working OS from MS (NT 4.0). It was released in 1998.
> >
> > So how you could use those early nineties?
> >
>
> Visual C++ came out long before 1998.

Yes, looked it up https://support.microsoft.com/en-us/kb/145669 it
seems that Visual C++ 4.00 were first that had namespaces (released at
end of 1995). Borland C++ 5.0 released 1996 had also namespaces. So
those were impossible to use in the early 90's without time machine.

Jerry Stuckle

unread,
Feb 22, 2016, 7:53:35 PM2/22/16
to
Yea, right. Just the response I would expect from an ignorant troll.

<plonk!>

Öö Tiib

unread,
Feb 23, 2016, 2:23:44 AM2/23/16
to
How silly of you to spit poison there. Everybody do mistakes but
those who insult others instead of admitting their error look desperate
and pathetic.

bartekltg

unread,
Feb 23, 2016, 4:55:37 AM2/23/16
to
On 21.02.2016 22:05, Alf P. Steinbach wrote:
> On 21.02.2016 20:02, Marcel Mueller wrote:
>> On 21.02.16 16.48, Alf P. Steinbach wrote:
>>>> In fact older C++ compilers required the include files with the .h
>>>> extension (and no namespace std::), i.e.
>>>> #include <math.h>
>>>> #include <complex.h>
>>>
>>> I believe the requirement had to be imposed by the FFTW3 headers.
>>>
>>> No compilers can have imposed this requirement.
>>
>> 15 to 20 years ago all you get by #include <math> was "File not found".
>
> There is no standard library header <math> and never has been.
>
> There is a C++ standard library header <complex>. It's different from
> <ccomplex> and <complex.h>.

It has changed ;-)

"26.4.11 Header <ccomplex> [ccmplx]
1 The header behaves as if it simply includes the header <complex>."


BTW, since, I think, c++11 there is a binary compatibility with C
complex. I think this is because of :

"
26.4:
...
If z is an lvalue expression of type cv std::complex<T> then:
(4.1) — the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,
(4.2) — reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part
of z, and
(4.3) — reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary
part of z.
Moreover, if a is an expression of type cv std::complex<T>* and the
expression a[i] is well-defined for an
integer expression i, then:
(4.4) — reinterpret_cast<cv T*>(a)[2*i] shall designate the real part of
a[i], and
(4.5) — reinterpret_cast<cv T*>(a)[2*i + 1] shall designate the
imaginary part of a[i].
"


>
>> The lines with the #ifdef __cplusplus are a hack specific to this
>> application to make the C++ application work reasonably with FFTW
>> without the need for dirty reinterpret casts all the way. Older C++
>> compilers did not support C99 _Complex, and the fallback to C[2] is
>> really ugly, since it makes trivial mathematical operations like
>> multiplication unreadable.
>
> Do you really need to support C89/C90 compilers?
>
> Is it really the case that someone has not upgraded their compiler
> version since 1999, can't be told to do that, and are IMPORTANT?
>
> Maybe this problem is more of a people & politics problem than a
> technical one?


I think the problem is with libraries based on fortran (with C
interface). Then reinterpreted cast is needed, but at least
should work.

bast
Bartekltg


Alf P. Steinbach

unread,
Feb 23, 2016, 1:45:25 PM2/23/16
to
On 23.02.2016 10:55, bartekltg wrote:
> On 21.02.2016 22:05, Alf P. Steinbach wrote:
>> On 21.02.2016 20:02, Marcel Mueller wrote:
>>> On 21.02.16 16.48, Alf P. Steinbach wrote:
>>>>> In fact older C++ compilers required the include files with the .h
>>>>> extension (and no namespace std::), i.e.
>>>>> #include <math.h>
>>>>> #include <complex.h>
>>>>
>>>> I believe the requirement had to be imposed by the FFTW3 headers.
>>>>
>>>> No compilers can have imposed this requirement.
>>>
>>> 15 to 20 years ago all you get by #include <math> was "File not found".
>>
>> There is no standard library header <math> and never has been.
>>
>> There is a C++ standard library header <complex>. It's different from
>> <ccomplex> and <complex.h>.
>
> It has changed ;-)

No. Not as far as I know. :)


> "26.4.11 Header <ccomplex> [ccmplx]
> 1 The header behaves as if it simply includes the header <complex>."

Points to understand the above quote, which is of C++11 §26.4.10/1:

• The header <ccomplex> is not the header <complex>.

• The header <ccomplex> is the basic C++ variant of the /C header/
<complex.h>. It places the C declarations in namespace std. It may also
place them in the global namespace.

• The /C++ header/ <complex.h>, distinct from the C header <complex.h>
(same name, yes), is defined in terms of <ccomplex> instead of directly
in terms of the C header. The C++ header <complex.h> provides the same
contents as <ccomplex> except that it provides this content in the
global namespace. It may also provide the contents in the std namespace.

And yes, I agree, the complexity of this is really ridiculous. The
original C++98 idea was evidently to not-so-subtly-at-all encourage a
move from “foo.h” headers to header names without filename extensions
“cfoo”. At that time C++ <ccomplex> was not allowed to pollute the
global namespace. But that did not sit well with compiler vendors, who
saw no reason to jump through hoops with additional extreme complexity,
with no evident advantage other than maybe supporting some idealistic
notions about filenames, so with C++11 the rules were changed to make
the <ccomplex> and <complex.h> requirements symmetric (and ditto for all
other such header pairs), incidentally making the whole thing
/meaningless/. So, just include <complex.h>, and forget about the
<ccomplex> complexity, so to speak – but remember that this is the
/C++ version/ of <complex.h>, and so it can, at the implementation's
discretion, make code that uses std:: qualifications compile, even
though that will not compile with some other compiler. :(

Relevant:

C++11 §17.6.1.2:

<quote>
Except as noted in Clauses 18 through 30 and Annex D, the contents of
each header cname shall be the same as that of the corresponding header
name.h, as specified in the C standard library (1.2) or the C Unicode
TR, as appropriate, as if by inclusion. In the C ++ standard library,
however, the declarations (except for names which are defined as macros
in C) are within namespace scope (3.3.6) of the namespace std. It is
unspecified whether these names are first declared within the global
namespace scope and are then injected into namespace std by explicit
using-declarations (7.3.3).
</quote>


> BTW, since, I think, c++11 there is a binary compatibility with C
> complex. I think this is because of :
>
> "
> 26.4:
> ...
> If z is an lvalue expression of type cv std::complex<T> then:
> (4.1) — the expression reinterpret_cast<cv T(&)[2]>(z) shall be
> well-formed,
> (4.2) — reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part
> of z, and
> (4.3) — reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary
> part of z.
> Moreover, if a is an expression of type cv std::complex<T>* and the
> expression a[i] is well-defined for an
> integer expression i, then:
> (4.4) — reinterpret_cast<cv T*>(a)[2*i] shall designate the real part of
> a[i], and
> (4.5) — reinterpret_cast<cv T*>(a)[2*i + 1] shall designate the
> imaginary part of a[i].
> "

Yes. That compatibility is the whole point of the above wording.


> [snip]
> I think the problem is with libraries based on fortran (with C
> interface). Then reinterpreted cast is needed, but at least
> should work.

Oh. I didn't think of that.


Cheers!,

- Alf

Alf P. Steinbach

unread,
Feb 23, 2016, 1:55:40 PM2/23/16
to
Oh, please disregard that posting, I was not thinking clearly.

There is no way there can be a C++ version of C99 <complex.h>, due to
the C99 keyword _Complex.

:(


Cheers,

- Alf

bartekltg

unread,
Feb 23, 2016, 2:42:10 PM2/23/16
to
On 23.02.2016 19:45, Alf P. Steinbach wrote:
> On 23.02.2016 10:55, bartekltg wrote:
>> On 21.02.2016 22:05, Alf P. Steinbach wrote:
>>> On 21.02.2016 20:02, Marcel Mueller wrote:
>>>> On 21.02.16 16.48, Alf P. Steinbach wrote:
>>>>>> In fact older C++ compilers required the include files with the .h
>>>>>> extension (and no namespace std::), i.e.
>>>>>> #include <math.h>
>>>>>> #include <complex.h>
>>>>>
>>>>> I believe the requirement had to be imposed by the FFTW3 headers.
>>>>>
>>>>> No compilers can have imposed this requirement.
>>>>
>>>> 15 to 20 years ago all you get by #include <math> was "File not found".
>>>
>>> There is no standard library header <math> and never has been.
>>>
>>> There is a C++ standard library header <complex>. It's different from
>>> <ccomplex> and <complex.h>.
>>
>> It has changed ;-)
>
> No. Not as far as I know. :)

In gcc 5.2.1, ccomplex:

#pragma GCC system_header

#ifndef _GLIBCXX_CCOMPLEX
#define _GLIBCXX_CCOMPLEX 1

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#endif

#include <complex>

#endif


It looks like, as stated in 26.4.11, including
<ccomplex> has the same effect as including <complex>.

Hmm. complex.h is... strange ;-)

...
#if __cplusplus >= 201103L
# include <ccomplex>
#endif

#if _GLIBCXX_HAVE_COMPLEX_H
# include_next <complex.h>
# ifdef _GLIBCXX_COMPLEX
// See PR56111, keep the macro in C++03 if possible.
# undef complex
# endif
#endif

So it may be replaced by c++ <complex>. IMHO strange decision


>> "26.4.11 Header <ccomplex> [ccmplx]
>> 1 The header behaves as if it simply includes the header <complex>."
>
> Points to understand the above quote, which is of C++11 §26.4.10/1:

Yes, I have looked at c++14 draft, in versions
n3242.pdf
n3376.pdf
it is 26.4.10


> • The header <ccomplex> is not the header <complex>.

Of course. This is a different file. The effect are the sama.

> • The header <ccomplex> is the basic C++ variant of the /C header/
> <complex.h>. It places the C declarations in namespace std. It may also
> place them in the global namespace.

I'm lost. You just corrected me in which paragraph the standard
say "The header behaves as if it simply includes the header <complex>.".


> • The /C++ header/ <complex.h>, distinct from the C header <complex.h>
> (same name, yes), is defined in terms of <ccomplex> instead of directly
> in terms of the C header. The C++ header <complex.h> provides the same
> contents as <ccomplex> except that it provides this content in the
> global namespace. It may also provide the contents in the std namespace.
>
> And yes, I agree, the complexity of this is really ridiculous. The
> original C++98 idea was evidently to not-so-subtly-at-all encourage a
> move from “foo.h” headers to header names without filename extensions
> “cfoo”. At that time C++ <ccomplex> was not allowed to pollute the
> global namespace. But that did not sit well with compiler vendors, who
> saw no reason to jump through hoops with additional extreme complexity,
> with no evident advantage other than maybe supporting some idealistic
> notions about filenames, so with C++11 the rules were changed to make
> the <ccomplex> and <complex.h> requirements symmetric (and ditto for all
> other such header pairs), incidentally making the whole thing
> /meaningless/. So, just include <complex.h>, and forget about the
> <ccomplex> complexity, so to speak – but remember that this is the
> /C++ version/ of <complex.h>, and so it can, at the implementation's
> discretion, make code that uses std:: qualifications compile, even
> though that will not compile with some other compiler. :(

Wow;-)




> Relevant:
>
> C++11 §17.6.1.2:
>
> <quote>
> Except as noted in Clauses 18 through 30 and Annex D, the contents of
> each header cname shall be the same as that of the corresponding header
> name.h, as specified in the C standard library (1.2) or the C Unicode
> TR, as appropriate, as if by inclusion. In the C ++ standard library,
> however, the declarations (except for names which are defined as macros
> in C) are within namespace scope (3.3.6) of the namespace std. It is
> unspecified whether these names are first declared within the global
> namespace scope and are then injected into namespace std by explicit
> using-declarations (7.3.3).
> </quote>


Does that mean complex.h and ccomplex (I have pasted fragments)
from new gcc are broken according to the standard?

best
bartekltg

Alf P. Steinbach

unread,
Feb 23, 2016, 4:26:41 PM2/23/16
to
On 23.02.2016 20:41, bartekltg wrote:
>
> Does that mean complex.h and ccomplex (I have pasted fragments)
> from new gcc are broken according to the standard?

No, it means I posted some rubbish, sorry. Once I realized it, after a
second or two, I posted a follow-up to clarify that, but Usenet is a bit
asynchronous.

It would have been a good posting about C++03, and about the change of
the general rules in C++11, except that C++03 didn't have any <ccomplex>
or <complex.h> headers, only the C++ <complex> header.

C++03 provided the following C compatibility headers, based on C89:

<assert.h> <iso646.h> <setjmp.h> <stdio.h> <wchar.h>
<ctype.h> <limits.h> <signal.h> <stdlib.h> <wctype.h>
<errno.h> <locale.h> <stdarg.h> <string.h>
<float.h> <math.h> <stddef.h> <time.h>

*But*, with C++11 the C library compatibility was upgraded to track the
C evolution, so it was now specified in terms of C99 instead of C89/90.

And in C99 a new keyword was introduced, `_Complex`, used to form type
specifications that are just syntactically invalid when interpreted as
C++. Also a new header <complex.h> was introduced in C99, using those
C99 complex number types. With declarations like

double complex cacos(double complex);

where C99 `complex` is a macro required to be defined as `_Complex`, and
where this macro would wreak havoc with use of C++03's `complex`.

So, C++11 instead offers binary level compatibility for its `complex`
class template, in its new §26.4/4 which you quoted.

Anyway, coffee helps a little, and thanks for pointing out the new C++11
headers <ccomplex> and <complex.h>!

Since I learned something today I can pride myself on still not being
entirely senile, yay! :)


Cheers, & thanks,

- Alf

0 new messages