U
Uncle Steve
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.
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).
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.
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.
<snip>
#define ARENA_TYPE struct foostruct 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.
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