Path: utzoo!attcan!uunet!lll-winken!csd4.milw.wisc.edu!uxc!garcon!uicsrd.csrd.uiuc.edu!mcdaniel From: mcdaniel@uicsrd.csrd.uiuc.edu (Tim McDaniel) Newsgroups: comp.lang.c Subject: Re: declarations in include files: how do YOU feel? Keywords: declarations include Message-ID: <1008@garcon.cso.uiuc.edu> Date: 16 May 89 19:59:40 GMT References: <179@larry.sal.wisc.edu> <10251@smoke.BRL.MIL> <181@larry.sal.wisc.edu> <5134@bunker.UUCP> Sender: news@garcon.cso.uiuc.edu Reply-To: mcdaniel@uicsrd.csrd.uiuc.edu (Tim McDaniel) Organization: Center for Supercomputing R&D (Cedar), U. of Ill. Lines: 86 In article <5134@bunker.UUCP> garys@bunker.UUCP (Gary M. Samuelson) writes: >First, if a function is replaced with a macro, it is no longer in lib.a. What's to prevent it? In f.c (to go into lib.a): #include #undef f int f(int x, char * y) { ... } That way, it's in lib.h as a macro and lib.a as a function. >Therefore, programs have to be recompiled, as opposed to merely relinking. Not in this scheme. Recompiling would cause some speedup, however, as well as increasing the code size. >Second, a pointer to a function can be passed as a parameter, stored in >a variable, and so forth. Any such usage will break with a macro. Not in pANS C. If "foo" is a macro that requires arguments, and a use of the token "foo" is not followed by a "(" token, it's not a macro call. I just tried this under gcc: #include int foo(x) int x; { printf("function %d\n", x); } #define foo(y) printf("macro %d\n", y); baz(p) int (*p)(); { (*p)(10); } main() { int (*p)() = foo; (*p)(5); baz(foo); foo(15); exit(0); } You should get: function 5 function 10 macro 15 (unless I screwed up in editing this for posting). So, in lib.h: extern int f(int x, char * y); #define f(x,y) ...whatever... The latter gets used for calls, the former for pointer references. Alas, "cc" under BSD 4.3 on a VAX doesn't follow that rule. In that case, in usercode.c: #include ... some code ... #undef f int (*p)() = f; ... more references to f as a parameter or as a ptr to func After the #undef, all references to f are function calls, not macros -- c'est la vie. Or define a convention for lib.a: ptr_f is an extern const variable which contains a pointer to f. Personally, I use pointers to functions so infrequently that I'm willing to type a few extra trivial keystrokes to use them. Your milage may vary. >Third, the size of the program increases as you replace functions >with macros. Maybe that's not an issue in your particular case, but >in some cases it is, and should be taken into account. A tradeoff of time versus space. If it's a problem in your code (many calls * large size), use #undef. >Debugging is also affected adversely; ever try to put a breakpoint >at a macro? #undef and recompile. I usually have to recompile with -g anyway. If the problem is the macro itself or its calls (for example, side effects in the argument list), perhaps it was a mistake to make it a macro in the first place. >In short, please do not change things by "sleight of hand" or "behind >the scenes." If you (generic "you" here) change something I use, >I want to know as precisely as possible why, preferably in advance. >And if you are inclined to say that a particular change won't have >any effect on me, well, I prefer that you let me be the judge of that. I suppose that when your vendor upgrades your OS, you read the diffs? :-) Seriously, a user can't and shouldn't be aware of *everything* that's going on in the implementation -- that's why libraries and data encapsulation/hiding are so useful. -- Tim, the Bizarre and Oddly-Dressed Enchanter mcdaniel@uicsrd.csrd.uiuc.edu {uunet,convex,pur-ee}!uiucuxc!uicsrd!mcdaniel mcdaniel%uicsrd@{uxc.cso.uiuc.edu,uiuc.csnet}