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