Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!uunet!van-bc!mdavcr From: lphillips@lpami.wimsey.bc.ca (Larry Phillips) Newsgroups: comp.sys.amiga Subject: Re: To macro, or not to macro? (LONG) ... a programming style. Message-ID: <2454@van-bc.UUCP> Date: 3 Jun 89 16:06:49 GMT Sender: usenet@van-bc.UUCP Lines: 163 In <18958@cup.portal.com>, Sullivan@cup.portal.com (sullivan - segall) writes: >I've been arguing out the fine points of whether or not macro assembly >is good programming style on a local BBS (Digital Mail Box 408/258-5463.) >Do macro enhance legibility, or decrease it? When should they be used, >and when should one resort to subroutines instead? > >I felt that it would be better to open the question to a wider community. >Below is an edited message tree as the discussion stands thus far. I would >be very interested in other opinions. -kls I guess it all depends on what you call legibility, or what makes things easier for you to read. I don't think the question is one of macros vs. subroutines, since they are two completely separate things, each having their own strengths and weaknesses. Personally, I feel that subroutines should be used for routines that are needed in a lot of places, and that are of significant size. Macros come in handy for two differnt things. The first is the small two or three liner that you use in many programs, and that are too small or inefficient when implemented as subroutines. The second, and to me, most important use of macros is to do the 'setup' for a subroutine call. An example might be a routine that prints a NULL terminated string, first finding the length of the string by scanning for the NULL. This is signficant in terms of size, and could be called a lot in a program, so should be made a subroutine. The macro that calls it can be perfectly understandable, and in fact I see no difference at all in the readbility between: lea label,a0 bsr printit and... print #label As for efficiency, yes, the macro can be less efficient. Take a look at the above two calls. The first used an LEA opcode, while the second generates a MOVE.L and a BSR. The reason for this is to make the macro more general, so that I can call it with: a string at a label... print #label a pointer stored at a label... print label a pointer contained in a register... print d5 or a pointer to a pointer... print (a4) or a pointer in an array of pointers... print 0(a3,d0.w) The inefficiency comes when my macro is defined as: print MACRO move.l \1,a0 bsr printit END and I happen to want to print the string at an address contained in A0.. print a0 which will, of course generate: move.l a0,a0 bsr printit Considering the number of times this might happen, vs. the number of times I call print, it is usually worthwhile. It is certainly no worse than I have seen in disassembled C code. If I want to get picky, I can just call it as: bsr printit if the pointer is already in A0. A few comments on the comments included from the debaters... >> Secondly macro EAT your memory if used for subprogram and will only save you >>a couple of cycle! Not necessarily so. short, two or three line macros, consisting of code you would write inline anyway, are no different than typing them in, except that if you don't put them in a macro, you have to type them in. Some things are best done inline, taking the memory hit, if you are optimising for speed. the bsr and rts might be 30% or more of the total time if the function is coded as a subroutine. Clearly, it is strictly a matter of readability, which is rather subjective (I can read asm easily. I cannot read C easily. I bet the reverse is more prvalent on this net). >>First for me CLR=0 to destination, ok you use CLRD, me ClearData somebody >>else ClearD You still have to look what to guy do in his call. >> ... >> I telling you have to guess what a macro do, and to be sure you have to look >>at it. Are subroutines any different? You have to look at them in order to see what they do. In what way is a macro less clear than a subroutine? Assuming you have the code for the subroutine or macros (if you don't, you'll have to guess, and rewrite them anyway), there really is no difference. >> For string I used library... Why have 1000 copy of the same rouitne in 10 >>diferent program run at the same time! Rather depends on what you need to do with strings. If I only have a few things I need to do with strings, and if the data is such that I can perform optimizations in the specific case that are not applicable to the general case, why have the general case in there? Why have the general cases for all string functions in memory if you only need a few string functions? Again, macros and subroutines serve two entirely different purposes. >>Inline code can speed up tight loops by double that required for subroutine >>calls. Anything this small *should* be duplicated thousands of times if >>neccessary. We aren't working with Z80's here. There is at least 400k >>available for applications, we don't have to scrimp on every byte of code. Right... but there are times when speed is not as important as size, and that's when you use subroutines (even small ones) for often called functions. You generally cannot optimize efficiently for both speed and size. Again, macros and subroutines serve differnt purposes. You should use what is appropriate in the circumstances, one or the other, or both together. >> Here again! can't you write jsr _xxx(a6) intead of CLVOCALL or somethinf >>the like!?! And I don't alway use a6 for dos dos, for speed I use a5 in tight >>loop where I need 2 diferent call to librarys! Yes, you can write it that way for lib calls, but the _LVOxxx(a6) wrapped around the actual function gets in the way of readability (for me, obviously not for him). I think it's cleaner to use the macro. I like the idea of a couple of different macros for the call.... CALL OpenLibrary ; a6 already contains ExecBase LIBCALL DoIO ; a6 needs to be loaded before the JSR CALLDOS Examine ; a5 is used for GfxBase In addition,if you happen to be using a linker as well, you can even include the XREF within the macro definition, or use conditional assembly and the SET pseudo-op within the definition, removing the need to worry about whether or not you have already defined a label, or an XREF, and save yourself some time typing it in again for each new program. Looks cleaner to me. >>I still don't see the point of macro, it's a extra work that you don't have >>to do, and if you alway want to use them it's a limit. Extra work? Hmm... when I type in a 4 or 5 line macro defintition, I type it in once. The work saving comes from only typing in one line any time I want to use it. >> But I don't say you shouldn't use macro, just macro are not my style. That's it in a nutshell, it's a question of style and preference. Macros can be overused, abused, can eat memory, and can generate inefficient code, but by no means do they always do these things. Macros, subroutines, inline code, unrolled loops, taking advantage of things you already know.. all have their place. -larry -- Van Roy's Law: An unbreakable toy is useful for breaking other toys. +----------------------------------------------------------------------+ | // Larry Phillips | | \X/ lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips | | COMPUSERVE: 76703,4322 | +----------------------------------------------------------------------+