Questions on X3J11 draft

Ray Butterworth rbutterworth at watmath.UUCP
Tue Dec 9 02:19:05 AEST 1986


In article <775 at axis.UUCP>, philip at axis.UUCP (Philip Peake) writes:
> In article <3800 at watmath.UUCP> rbutterworth at watmath.UUCP writes:
> >                          But under ANSI, almost any function can
> >be defined as a macro in the header files.  That means that almost
> >any program that contains an "extern type libCfunc();" in it can
> >potentially break under a conforming ANSI compiler.
> This is a *very* good point ! (Why didn't I think of it ? ......)
I didn't think of it either.  I was hit over the head with it when
I tried to port a program to a compiler that is trying to conform
to ANSI's moving target.  It had several functions defined as macros
to call other functions in their existing library of non-ANSI functions.

> Taking the above example (sligtly modified), what if the function
> actually returns something other than int ?
> You HAVE to put the extern definition, if not other things will
> probably (certainly ?) break.
Each function has an associated header file (one file may describe
many functions) that contains its external prototype definition, and
possibly a macro defining the function.  If you do not include that
header file, you must put in the explicit external prototype yourself.
It can be very awkward to do if that is what you really want (e.g.
if you want your own external prototype for printf() you cannot include
stdio.h, or any other header file that might include that one).
If, however, you always use the header files, everything is taken
care of automatically and you never need to use an explicit extern
statement (and in fact you might get into trouble if you do).

> How can I know, when trying to write portable code, if the 'library'
> function I am going to use is a real function or a macro ?
Normally it shouldn't matter to you whether you are actually getting
a macro or a function.  On those occasions where you really do want
to get a function and not a macro, you can do one of two things.
Either put "#undef FunctionName" in the source immediately before
you use it (this gets rid of the possibility of using the macro,
and the header file should still contain the external prototype
and the library should contain a real function version of the function)
Or, you can call the function as "(FunctionName)(args)".  The extra
parentheses stop it from looking like a macro invocation.  The advantage
to this second method is that you can still get the macro version
later on in the source file; you can't if you use #undef.  (I think
that the latest version of ANSI still allows this second method, but
I don't guarantee it.)
Of course if a function cannot be implemented as a macro without
causing side effects on its arguments (i.e. each argument must be
evaluated exactly once), then that function is not allowed to be
implemented as a macro.

For compatibility with past mistakes, a few functions such as
getchar() are explicitly allowed to violate the above rule.



More information about the Comp.lang.c mailing list