🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #4362

Re: macro versus function in standard headers

#4362
From: Stephen Baynes
Date: Thu, 16 Nov 1995 09:27
76 lines
3526 bytes
Mark Brader (msb@sq.com) wrote:
: > > Is a conforming implementation _required_ to give a diagnostic if presented
: > > with the following source:
: > >    #include <stdlib.h>
: > >    int main(void) { return abs("0"); }
: > > ...
: > > or does one need to write (abs)("0") ... to be assured of the diagnostic.

: > I do not see any Constraint or Syntax rule requiring a diagnostic for
: > this violation [in either case].
<snip>
:
: Now as to the original question, it depends on what is meant when
: 7.1.7/4.1.6 says that a function "may be ... implemented as a macro".
: Does "implementing" a function as a macro require the implementation
: of the constraints on its arguments?  I think this is genuinely
: ambiguous in the standard.

: However, it is desirable for implementations to be so restricted, and
: in practice it seems very likely that this will follow in a natural
: way -- inside the macro, either the argument will be assigned to a
: hidden variable, or it will be passed to a real function, and in either 
: case the constraint comes in automatically.  So I would favor a
: corrigendum making it clear that the constraint does apply.

I agree it is desirable  essential. However it does come at a cost.
Consider    feof( FILE *stream );
    The following code is legitimate (assuming feof is a function)

     void *s = stdout;
     if( feof( s ) ) ...

However a typical macro implementation (this one is from HPUX)

#    define feof(__p)      ((__p)->__flag & _IOEOF)

will obviously break when used as above.
The trivial way to make it work is:

#    define feof(__p)      (((FILE*)(__p))->__flag & _IOEOF)

However that would allow:

      feof( "abc" )

past the compiler.

To use a hidden variable here which makes it behave correctly and force the
correct constraints would make the code less efficient:

FILE * __hidden_f;
#    define feof(__p)      (__hidden_f=(__p),__hidden_f->__flag & _IOEOF)

I doubt many compilers would be able to always optimize out the assignment.
Thus implementors will have to introduce a hidden language extension to make
it worth while continueing to use a macro here. The extension could either
be inline functions:

inline __feof( FILE *p ) { return p->__flag & _IOEOF ; }
#define feof( __p ) __feof( __p )

or a 'safecast' which acts as a cast but will only do it when the conversion 
would be permited for normal assignment.

#    define feof(__p)      (__safecast((FILE*),(__p))->__flag & _IOEOF)

Both of these would be useful as proper language extensions. 'inline' has
been requested many times. 'safecast' is also useful in circumstances other
than macros (eg when casting typedefed types, to trap a change in the typedef
that invalidates the cast.)

--
Stephen Baynes                              baynes@mulsoc2.serigate.philips.nl
Philips Semiconductors Ltd
Southampton                                 My views are my own.
United Kingdom
Technical Details
Message-ID: <DI4q9v.61n@ukpsshp1.serigate.philips.nl>
Path: arc1-ca.pugleaf.net!phcoms4.seri.philips.nl!panther!baynes
References: <487rls$rci@newshost.lanl.gov> <48caqa$rl@usenet.pa.dec.com> <1995Nov15.103729.9184@sq.com>

Show Full Headers
Complete Article Headers
Newsgroups: comp.std.c
Path: arc1-ca.pugleaf.net!phcoms4.seri.philips.nl!panther!baynes
From: baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes)
Subject: Re: macro versus function in standard headers
Sender: news@ukpsshp1.serigate.philips.nl (account for localnews)
Message-ID: <DI4q9v.61n@ukpsshp1.serigate.philips.nl>
Date: Thu, 16 Nov 1995 09:27:31 GMT
References: <487rls$rci@newshost.lanl.gov> <48caqa$rl@usenet.pa.dec.com> <1995Nov15.103729.9184@sq.com>
Organization: Philips Semiconductors, Southampton, UK
X-Newsreader: TIN [version 1.2 PL2]