Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!clyde!watmath!rbutterworth From: rbutterworth@watmath.UUCP (Ray Butterworth) Newsgroups: comp.lang.c Subject: Re: Questions on X3J11 draft Message-ID: <3837@watmath.UUCP> Date: Mon, 8-Dec-86 11:19:05 EST Article-I.D.: watmath.3837 Posted: Mon Dec 8 11:19:05 1986 Date-Received: Mon, 8-Dec-86 22:22:11 EST References: <351@danews.ATT.COM> <7373@utzoo.UUCP> <3800@watmath.UUCP> <775@axis.UUCP> Organization: U of Waterloo, Ontario Lines: 49 Keywords: C,X3J11 In article <775@axis.UUCP>, philip@axis.UUCP (Philip Peake) writes: > In article <3800@watmath.UUCP> rbutterworth@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.