fabs(x) vs. (x) < 0 ? -(x) : (x)
Alan Mycroft
am at cl.cam.ac.uk
Tue Feb 3 22:01:08 AEST 1987
In article <2550005 at hpisod2.HP> decot at hpisod2.HP (Dave Decot) writes:
>> In article <4477 at ut-ngp.UUCP> jjr at ngp.UUCP (Jeff Rodriguez) writes:
>> >Why isn't fabs() implemented as a macro [ (X) < 0 ? -(X) : (X) ]?
>>
>You could implement fabs() as a macro as follows:
>
> #define fabs(X) ((_fabs = (X)), (_fabs < 0? -_fabs : _fabs))
>
>if _fabs were declared as a float in the math library.
>
Of course you could (modulo volatile), but what this example (and many
others like it) REALLY SHOWS, is that C suffers from the lack of the ability
to make declarations within expressions. The pre-processor merely
amplifies this deficiency -- as we would all like to be able to write
macro's which evaluate each argument once (wouldn't we?).
Many languages (including BCPL from which C derives) have this ability.
E.g. (ML) <exp> ::= let <decl> in <exp> | ...
(BCPL) <exp> ::= valof <cmd> | ...
<cmd> ::= <block> | resultis <exp> | ...
The absence of this ability (in suitably C-like syntax) to create explicit
temporaries in C expressions explains why getc() and putc() are allowed
to evaluate their parameters more than once.
Question: do not the ANSI committee find this uncomfortable too?
Is the absence of suitable concrete syntax the justification?
BTW, I have been involved in writing a C compiler in which this facility
was abstract syntax (with no concrete correspondent) and which proved very
useful for (almost-)source level sub-expression elimination and de-sugaring of
bitfields etc.
More information about the Comp.lang.c
mailing list