Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Uncle Steve Newsgroups: comp.lang.c Subject: Re: Malloc Query Date: Mon, 23 May 2011 02:36:47 -0400 Organization: Friends of the Galactic Collective Lines: 165 Message-ID: References: <0.3ac369f64d11bcd06d18.20110519002615BST.87ei3vtwtk.fsf@bsb.me.uk> <98a074c87051012-452fb@gmail.com> <0.bf5e9ff46dfbfc1e78d6.20110519032218BST.87tycrsa3p.fsf@bsb.me.uk> <2b5874771e1859c-5f9fd@gmail.com> <22a91a32-b2c6-4ce1-bb2b-23c2455bc195@z13g2000yqg.googlegroups.com> <708913a057f3f9c-34aa7@gmail.com> <0.47b2d301a43a01009630.20110522231836BST.87fwo6nzur.fsf@bsb.me.uk> <21ceccb2e03a4dc-edfd3@gmail.com> <0.dd74e92a138404c43559.20110523010437BST.874o4mnuy2.fsf@bsb.me.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit Injection-Info: mx04.eternal-september.org; posting-host="job9yP/rmK/fxQbJrcqEcA"; logging-data="8692"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19xgKZb8mJ+7ILldafVWKNi" User-Agent: nn 6.7.3 Content-Length: 7032 Cancel-Lock: sha1:RaGuwRJ+AFcENljohk8psss+/sc= Xref: x330-a1.tempe.blueboxinc.net comp.lang.c:4545 On Mon, May 23, 2011 at 01:04:37AM +0100, Ben Bacarisse wrote: > Uncle Steve writes: > > > On Sun, May 22, 2011 at 1u1:18:36PM +0100, Ben Bacarisse wrote: > >> Uncle Steve writes: > >> > >> > On Sun, May 22, 2011 at 02:49:51AM -0700, luser- -droog wrote: > >> >> > >> >> I've been using integer offsets instead of pointers a lot lately and > >> >> I think you might be better off using the array formula explicitly: > >> >> > >> >> #define arena_obj_addr(x, n) ((void *) (x->arena + n * x->obj_size)) > >> > >> Everyone is taking chances here. The x and n should be in parentheses > >> so that the macro expands as expected. This is one reason why functions > >> are usually preferred. > > I should also have said especially if the macro does not have an > ALL_CAPS name flagging it's macrosity. But as some feel here, macrosity is a vanishing distinction. I use all-caps macro names for constant expressions and the like. If I think a macro will be more readable in lower-case, I'll do just that. Shouted macro definitions interrupt the flow of source text when a human is reading it, and I don't think I need that kind of distraction in the code as much as some do. > > For a long time I've thought macros were preferable to functions for > > the reason that a function call has to save registers, stuff it's arguments on the > > stack, and so on. Macros should just fold into the program text, > > They should, but the onus is on the programmer to make that reasonable > (and where there are side effects in the expressions used in the macro > "call" this may not be possible). > > > but > > today inline functions are just as fast as macros. > > Yes, using an inline function is better yet. You seemed dead against > them which is why I commented on the macro. Use a function and the > issue disappears. I'm not "dead against" function calls for simple things. I'm merely predisposed against them. > > It has become a > > matter of preference. gcc even has the ability to use register > > calling conventions for function calls in some circumstances. The > > distinction between a macro and a function call is becoming moot. > > I don't see how you can say that. The speed advantage that used to be > one of the main reasons to take the risk with macros has gone, but all > the potential bugs that function-like macros can hide are still there. Sorry, I should say 'moot' in consideration of the now historic performance advantage of macros over function calls. In reality, function calls /are/ slower than macro instances but the compiler masks this when it inlines a function by omitting function preamble and jinking the basic blocks of code to flow together as if they were part of the immediate text. > >> > >> > #define ARENA_TYPE struct foo > > > >> > struct arena_s { > >> > size_t arena_size; > >> > int free_list; > >> > size_t free; > >> > ARENA_TYPE * arena; > >> > }; > >> > > >> > And your access macro becomes: > >> > > >> > #define arena_obj_addr(x, n) &x->arena[n] > >> > >> Here the [n] is OK, but why risk it with x? The (x) costs nothing and, > >> I think, saves time reading the macro since the reader does no have to > >> start worrying about what might be passed. > > > > No worries here. I've edited for brevity in posting, but I always > > protect macro arguments from side-effects these days. It doesn't look > > as clean and concise, which is why I omitted those statements from > > example code. No biggie. > > OK. I'll try to remember to assume any errors in future code were added > for brevity and I'll save time by not commenting on it. Please do. I find it's the cut-and-paste-modify step that introduces errors into program code more so than writing it in the first place. > > In this newsgroup is it really preferable to see > > > > #define arena_object_addr(x, n) ({ \ > > struct arena_s X = x; \ > > int N = n; \ > > *X->arena[N]; }) \ > > > > for every dumb example that is posted? > > The correct version of the macro is simpler than the one you seem to > think you'd write to make it safe. Why would you write the above (it's > wrong, so it's obviously not what you really use) instead of > > *(x)->arena[n] That's only correct if the macro is a simple one-liner. If (x) is used more than once and has side-effects, such as in (x++), you're toast. > ? Also, why would you use a non-standard feature when it's not needed? There > might be a reason to use ({...}) when a macro parameter is used more > than once that's not the case here. I suppose if you know you'll never > use another compiler, tying code to language extensions is not a problem. I'm a creature of habit, I guess. Note that while I didn't learn C under gcc, it's about the only compiler I've used in the last seventeen years. Consequently, avoiding its extensions is not an automatic process. I'm making an effort to avoid non-portable code, but it is slow going. > > Possibly not if people can be > > reminded that all code posted in comp.lang.c is generally intended as > > an example. > > One of the bug-bears of Usenet is "oh that's not the real code". This > translates to "you've just wasted your time". I'd vote for real code > (at the last code that's gone though a compiler) every time. I look at the majority of the example code posted in Usenet messages as being contrived for the purposes of demonstration. When I was a total noob, comp.sources.unix and a few others were places where real code was made available to Usenet readers. So called real code is no longer posted to newsgroups. I'm not ecstatic that my contrived examples are not perfect, but the alternative is to post my 'real code' and annoy people who would prefer the exemplar pared down to the bare minimum. The arena allocator I've been on about is instantiated as a .h file and is over 500 lines of code at this time. It carries with it all the 'baggage' of my development environment and would make the discussion of its data structures and algorithm very awkward. A reasonable compromise would be to ensure that posted code compiles and works as expected, but even than that won't correct for all possible errors: note that I buggered up the for() loop in the arena_creat() function without triggering the error during testing. I'll endeavor to post better code in subsequent messages, but it is not always practical to test quick one-off constructs completely when so many things compete for my (and your) time. I suppose I might sound more intelligent and authoritative if my messages never contained errors, but then I might never post at all if that were a basic prerequisite for Usenet participation. Somewhere there is a happy medium that will satisfy everyone here. I'll look more closely for it. :) Regards, Uncle Steve -- Should a professional politician be charged with molestation if he kisses babies while attending political rallies?