jacob navia said:
Flash said:
jacob navia wrote, On 21/03/08 21:47: [...]
Well, they are accepted
double _Complex a,b;
// ...
a = a+b;
If my compiler uses operator overloading to implement that,
it complies with the AS IF rule, as far as I see.
Ah, but does it still work and produce all required diagnostics if
you put it in standard compliant mode? I seem to recall that for
operator overloading you use a syntax that in standard compliant
mode requires a diagnostic (not that there is anything wrong with
extensions that require a diagnostic in standard compliant mode).
1) During compilation of tgmath.h I put the compiler in non-compliant
mode even if you requested the contrary. After compiling that, I
reset it again, the AS IF rule is then followed. Unless you
modify tgmath.h what is not a good idea.
Not a bad approach. Standard headers absolutely don't have to be
written in standard-conforming C (they don't have to be written in C,
or even exist as files).
2) There is some stuff that can't be done with operator overloading,
specifically the strange syntax that C99 uses:
double _Complex b = 1+2*I;
What strange syntax? "1+2*I" isn't single literal, it's an
expression. I is a macro that expands to _Complex_I, which in turn
expands to a constant expression of type "const float _Complex". From
there, the rest is just ordinary complex arithmetic with the usual
arithmetic conversions (C99 6.3.1.8, though the wording that describes
promotion from real to complex is a bit subtle). There's nothing
there that requires any more special handling than the initialization
of z in:
int a = 1;
int b = 2;
float _Complex c = I;
double _Complex z = a + b * c;
C99 has no complex literals (just as it has no negative literals;
``-42'' is a unary "-" applied to a constant 42).
This part has to be done in the compiler proper. It would be much
more convenient if there was a simple way to parse a complex constant
without having a full expression simplifier with complex arithmetic
in the compiler obviously. I have still not finished this part, and
if you type
double _Complex b = 1+2*I-245-56*I+56+66*I;
the operations will be done at run time and not at compile time.
Operator overloading can't help here since this is compile time.
The same problem appears in C++ by the way. The solution of
course is to be able to define compile time functions, but after
all the critic for this simple operator overloading stuff I will
not propose any further extensions here.
As far as I know, performing those operations at run time is perfectly
legal as far as the standard is concerned. Obviously doing as much as
possible at compilation time would be a nice optimization, but that's
not a conformance issue.
3) There is not a lot of complex C99 code available that would test
my implementation, and even if I have ported into the new syntax
some codes, it needs more testing.
Thanks for acknowledging that. Perhaps some subset of the gcc test
suite would be useful. (I haven't looked at it myself; it might well
turn out to be totally useless for this purpose.)
This raises an interesting question (for the group in general, not
necessarily just for jacob). In complex.h, the macro _Complex_I
expands to a constant expression of type const float _Complex,
with the value of the imaginary unit.
Is there any portable way to do this, or must it be done via some
extension? One example: GNU libc's <complex.h> has
#define _Complex_I (__extension__ 1.0iF)
There doesn't actually *need* to be a portable way to do this, but it
seems odd to define built-in complex types but not be able to express
the value ``i'' without using (directly or indirectly) a compiler
extension. It might have been more consistent either to make
_Complex_I a new keyword, or to define a new suffix to specify complex
or imaginary constants.