I suspect that the problem is either than I simply don't know what I
am doing, or lcc-win32 is missing some basic elements of C99 complex
arithmetic because the first problem is simply this:
-------- 1.c ---------
int main(void)
{
double _Complex x = 1.0;
return 0;
}
--- lcc-win32 says ---
Error 1.c: 3 operands of = have illegal types 'struct long double
_Complex' and 'double'
----------------------
This is with or without the -ansic flag. Adding #include <complex.h>
and the problem is goes away, *unless* -ansic is specified:
-------- 2.c ---------
#include <complex.h>
int main(void)
{
double _Complex x = 1.0;
return 0;
}
--- lcc -ansic says ---
Error 2.c: 5 operands of = have illegal types 'struct long double
_Complex' and 'double'
-----------------------
These are so basic that I suspect I am missing something, but I can't
see what. No programs with complex numbers seem to work when I use
the -ansic flag, but that flag is needed or I can't compile:
-------- 7.c ---------
#include <stdio.h>
#include <complex.h>
int operator = (42);
int main(void)
{
double _Complex x = 1+2*I;
printf("%d\n", operator);
return 0;
}
--- lcc-win32 says ---
Error 7.c: 4 syntax error; found `42' expecting ')'
Error 7.c: 4 skipping `42'
Error 7.c: 4 incorrect number of arguments to operator asgn
Error 7.c: 9 undeclared identifier 'operator'
Warning 7.c: complex-7.c: 9 possible usage of operator before definition
----------------------
A couple of small points (and neither depends on the -ansic flag) are:
_Complex_I seems not to be defined in complex.h and the types of creal
and cimag seem to be wrong:
-------- 5.c ---------
#include <stdio.h>
#include <complex.h>
int main(void)
{
double _Complex x = _Complex_I;
printf("%g+%gI\n", creal(x), cimag(x));
return 0;
}
--- lcc-win32 says ---
Error 5.c: 6 undeclared identifier '_Complex_I'
Warning 5.c: 7 printf argument mismatch for format g. Expected double
got long double
Warning 5.c: 7 printf argument mismatch for format g. Expected double
got long double
Warning 5.c: 6 possible usage of _Complex_I before definition
----------------------
--
Ben.
Now this works with ansic. What was missing are the two lines
#pragma extensions(push,on)
at the beginning of complex.h
and
#pragma extensions(pop)
at the end. Please add the missing lines, and it will work.
> -------- 2.c ---------
> #include <complex.h>
>
> int main(void)
> {
> double _Complex x = 1.0;
> return 0;
> }
> --- lcc -ansic says ---
> Error 2.c: 5 operands of = have illegal types 'struct long double
> _Complex' and 'double'
> -----------------------
>
This is the same bug as above
> These are so basic that I suspect I am missing something, but I can't
> see what. No programs with complex numbers seem to work when I use
> the -ansic flag, but that flag is needed or I can't compile:
>
> -------- 7.c ---------
> #include <stdio.h>
> #include <complex.h>
>
> int operator = (42);
>
Here the compiler thinks you are starting to define an operator
assignment and finds the number 42. This has two solutions
1) Eliminate the unneeded parentheses enclosing (42)
2) Wait till tomorrow when I fix this.
> int main(void)
> {
> double _Complex x = 1+2*I;
> printf("%d\n", operator);
> return 0;
> }
> --- lcc-win32 says ---
> Error 7.c: 4 syntax error; found `42' expecting ')'
> Error 7.c: 4 skipping `42'
> Error 7.c: 4 incorrect number of arguments to operator asgn
> Error 7.c: 9 undeclared identifier 'operator'
> Warning 7.c: complex-7.c: 9 possible usage of operator before definition
> ----------------------
>
> A couple of small points (and neither depends on the -ansic flag) are:
> _Complex_I seems not to be defined in complex.h and the types of creal
> and cimag seem to be wrong:
>
All complex numbers are represented in long double
precision. The creal macro is missing a cast.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
> Ben Bacarisse wrote:
<snip>
>> -------- 1.c ---------
>> int main(void)
>> {
>> double _Complex x = 1.0;
>> return 0;
>> }
>> --- lcc-win32 says ---
>> Error 1.c: 3 operands of = have illegal types 'struct long double
>> _Complex' and 'double'
>> ----------------------
>>
>> This is with or without the -ansic flag. Adding #include <complex.h>
>> and the problem is goes away, *unless* -ansic is specified:
>>
>
> Now this works with ansic. What was missing are the two lines
> #pragma extensions(push,on)
> at the beginning of complex.h
> and
> #pragma extensions(pop)
> at the end. Please add the missing lines, and it will work.
Seems to have had no effect. The program does not include complex.h,
but I suppose that does not prevent lcc-win32 from reading it.
Anyway, I see no change in behaviour having edited the file as you ask.
>> -------- 2.c ---------
>> #include <complex.h>
>>
>> int main(void)
>> {
>> double _Complex x = 1.0;
>> return 0;
>> }
>> --- lcc -ansic says ---
>> Error 2.c: 5 operands of = have illegal types 'struct long double
>> _Complex' and 'double'
>> -----------------------
>>
>
> This is the same bug as above
Now, this files does use complex.h but, again, I see no change. Have I
missed the point of your changes? I put the two lines right at the
top and at the very end of complex.h -- cutting and pasting from your
message.
>> These are so basic that I suspect I am missing something, but I can't
>> see what. No programs with complex numbers seem to work when I use
>> the -ansic flag, but that flag is needed or I can't compile:
>>
>> -------- 7.c ---------
>> #include <stdio.h>
>> #include <complex.h>
>>
>> int operator = (42);
>>
>
> Here the compiler thinks you are starting to define an operator
> assignment and finds the number 42. This has two solutions
>
> 1) Eliminate the unneeded parentheses enclosing (42)
> 2) Wait till tomorrow when I fix this.
I see no bug here. I was just explaining why the -ansic flag is
important to people who want to write portable C. Without it, you may
do whatever you like since the language is not C -- rejecting this
program is fine. Obviously, if you see something you want to fix here
that's fine but I was not reporting a bug with this example.
<snip>
>> A couple of small points (and neither depends on the -ansic flag) are:
>> _Complex_I seems not to be defined in complex.h and the types of creal
>> and cimag seem to be wrong:
>>
>
> All complex numbers are represented in long double
> precision. The creal macro is missing a cast.
I don't follow. Are you saying I've made a mistake here and that
neither of these is a bug in lcc-win32? You only comment on one of
them.
Note that I need your help here, because I can't compile anything that
uses complex.h with the -ansic flag so, in effect, so you are free to
have an extended language where _Complex_I is not defined in complex.h
and where the types of some function like creal are chosen by you. It
may be that when -ansic is working with complex numbers, these
problems go away. If so, all I would say is that both of these are
very odd choices to have made as "extensions" to C99.
--
Ben.
Here is a copy of the correct complex.h
This should eliminate all complex bugs (pun intended)
when you include <complex.h>, even if -ansic is specified
The problem with
int operator = (42)
is solved too, but will be in the next version,
available tomorrow. In the meantime eliminate the parentheses. You
can put them back tomorrow. Please tell me if this works
---------------------------------------------------complex.h
#ifndef __complex_h__
#define __complex_h__
#include <math.h>
#include <iostream.h>
#pragma extensions(push,on)
extern long double log1pl(long double);
//------------------------------------------------------------
// _Complex data structure
// It is now automatically defined by the compiler at startup for
// the types float, double, and long double.
//typedef struct __complex {
// double re;
// double im;
//} _Complex;
#define creal(a) ((double)a.re)
#define cimag(a) ((double)a.im)
#define creall(a) ((long double)a.re)
#define cimagl(a) ((long double)a.im)
#define cimagf(a) ((float)a.im)
#define crealf(a) ((float)a.re)
#define complex _Complex
long double _Complex operator -= (long double _Complex &a,const long
double _Complex r);
long double _Complex operator *= (long double _Complex &a,const long
double _Complex r);
double _Complex operator *=(double _Complex &a,const double _Complex r);
double _Complex operator +(double _Complex x, double _Complex y);
//
// Addition operator
//
long double _Complex operator +(const long double _Complex x, const long
double _Complex y);
long double _Complex operator += (long double _Complex a,const long
double _Complex r);
long double _Complex operator+(long double,const long double _Complex);
long double _Complex operator+(long double,const long double _Complex);
//
// Minus operator
//
long double _Complex operator -(const long double _Complex x, double y);
long double _Complex operator -(const double y,const long double
_Complex x);
long double _Complex operator -(const long double x, const double
_Complex y);
long double _Complex operator-(const long double x,const long double
_Complex y);
long double _Complex operator- (const long double _Complex,const long
double _Complex);
//
// Multiplication
//
long double _Complex operator * (const long double _Complex x, const
long double _Complex y);
long double _Complex operator * (const long double _Complex x, long
double y);
long double _Complex operator *(const long double x, long double
_Complex y);
//
// division
//
double _Complex operator / (const double _Complex x, double y);
double _Complex operator /= (double _Complex &a,const double _Complex y);
//double _Complex operator / (const double _Complex x, const double
_Complex y);
double _Complex operator / (double x, const double _Complex y);
long double _Complex operator / (const long double _Complex x, long
double _Complex y);
double _Complex operator - (const double _Complex x);
int operator == (const double _Complex x, const double _Complex y);
int operator == (const double _Complex x, double y);
int operator == (double x, const double _Complex y);
int operator != (const double _Complex x, const double _Complex y);
int operator != (const double _Complex x, double y);
int operator != (double x, const double _Complex y);
//
// Casts
//
long double _Complex operator()(double _Complex &a);
double _Complex operator()(long double _Complex &a);
long double _Complex operator()(float _Complex &a);
double _Complex operator()(float _Complex &a);
long double _Complex operator()(long double ld);
double _Complex operator()(double d);
long double _Complex operator()(double);
long double _Complex operator()(long double);
long double _Complex operator()(int);
long double _Complex operator()(unsigned long);
long double _Complex operator()(unsigned long long);
//
//Assignments
//
long double _Complex operator=(long double _Complex &a,long double d);
long double _Complex operator=(long double _Complex &a,double _Complex d);
double _Complex operator=(double _Complex &a,long double _Complex d);
long double _Complex operator=(long double _Complex &a,float _Complex d);
float _Complex operator=(float _Complex &a,long double _Complex d);
double _Complex operator=(double _Complex &a,float _Complex d);
float _Complex operator=(float _Complex &d,double _Complex a);
extern float _Complex I;
#define _Complex_I I
double norm (const double _Complex);
// cabs
double cabs(const double _Complex x);
long double cabsl(long double _Complex);
float cabsf(float _Complex);
double arg(const double _Complex x);
// conj
double _Complex conj(const double _Complex x);
long double _Complex conjl(const long double _Complex x);
float _Complex conjf(const float _Complex x);
//ccos
double _Complex ccos(const double _Complex);
long double _Complex ccosl(const long double _Complex);
float _Complex ccosf(const float _Complex);
//cacos
double _Complex cacos(const double _Complex);
long double _Complex cacosl(const long double _Complex);
float _Complex cacosf(const float _Complex);
// ccosh
double _Complex ccosh (const double _Complex x);
long double _Complex ccoshl(long double _Complex);
float _Complex ccoshf(float _Complex x);
//ctanh
double _Complex ctanh(double _Complex);
long double _Complex ctanhl(long double _Complex);
float _Complex ctanhf(float _Complex);
//ctan
double _Complex ctan(double _Complex);
long double _Complex ctanl(long double _Complex);
float _Complex ctanf(float _Complex);
//catan
double _Complex catan(double _Complex);
long double _Complex catanl(long double _Complex);
float _Complex catanf(float _Complex);
double _Complex c_polar (double r, double t);
// Cexp
double _Complex cexp(const double _Complex x);
long double _Complex cexpl(long double _Complex x);
float _Complex cexpf(float _Complex x);
// Clog
double _Complex clog(const double _Complex x);
long double _Complex clogl(long double _Complex x);
float _Complex clogf(float _Complex x);
// Cpow
double _Complex cpow(const double _Complex x,const double _Complex y);
long double _Complex cpowl(long double _Complex x,long double _Complex y);
float _Complex cpowf(float _Complex x,float _Complex y);
// Csqrt
double _Complex csqrt(const double _Complex x);
long double _Complex csqrtl(long double _Complex x);
float _Complex csqrtf(float _Complex x);
// csin
double _Complex csin(const double _Complex x);
long double _Complex csinl(long double _Complex x);
float _Complex csinf(float _Complex x);
// casin
double _Complex casin(double _Complex);
long double _Complex casinl(long double _Complex);
float _Complex casinf(float _Complex);
double _Complex csinh(const double _Complex);
long double _Complex csinhl(long double _Complex);
float _Complex csinhf(float _Complex);
// CASINH
double _Complex casinh(const double _Complex);
long double _Complex casinhl(long double _Complex);
float _Complex casinhf(float _Complex);
// CACOSH
double _Complex cacosh(const double _Complex);
long double _Complex cacoshl(long double _Complex);
float _Complex cacoshf(float _Complex);
// CATANH
double _Complex catanh(const double _Complex);
long double _Complex catanhl(long double _Complex);
float _Complex catanhf(float _Complex);
double _Complex c_intpow (const double _Complex xin, int y);
//long double _Complex operator()(float _Complex x);
//long double _Complex operator()(double _Complex x);
double carg(const double _Complex);
long double cargl(long double _Complex);
double _Complex ctgamma(double _Complex);
long double _Complex ctgammal(long double _Complex);
long double _Complex clgammal(long double _Complex);
#pragma extensions(pop)
#endif
> Hi Mr Becarisse
B*a*carisse -- and it's a French name! But, please, call me Ben.
> Here is a copy of the correct complex.h
>
> This should eliminate all complex bugs (pun intended)
> when you include <complex.h>, even if -ansic is specified
Yes, after fixing a wrapped // comment it did as you describe. Of
course, that does not make lcc-win32's complex number support C99
conforming since example 1 still fails (and other similar uses).
> The problem with
>
> int operator = (42)
OK, but I don't see that as a problem.
--
Ben.
If I understand you correctly, that would seem to be non-conforming.
See C99 6.2.5p13:
Each complex type has the same representation and alignment
requirements as an array type containing exactly two elements of
the corresponding real type; the first element is equal to the
real part, and the second element to the imaginary part, of the
complex number.
For example, this:
sizeof(float _Complex) == 2 * sizeof(float)
must be true.
--
Keith Thompson (The_Other_Keith) <ks...@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"