Mail Archives: djgpp-workers/1998/02/11/06:34:36
Hans-Bernhard Broeker wrote:
>
> On Tue, 10 Feb 1998, Vik Heyndrickx wrote:
>
> > The following is an ANSI compliant behaving macro, and it supports also
> > 'signed char'
> > It yields reasonably efficient hard-code.
> >
> > #define isupper(c) ({int t=(c);unsigned v;\
> > ++t;\
> > if(t<0)t+=256;\
> > v=__dj_ctype_flags[t];\
> > (v&__dj_ISUPPER)!=0;})
>
> Which brings me to an idea: why should we provide is* _macros_ at all? As
> the DJGPP libc is for gcc, anyway, why not use 'extern inline' functions
> instead? That'd save all the special casing and whatnot, and automatically
> turn it into a function call whenever gcc thinks that's the better idea...
Why would this save us the special casing?
> I.e., why not put *this* in inlines/ctype.ha:
>
> extern int isupper(int c);
> extern inline int isupper(int c) {
> return __dj_ctype_flags[c+1]&__dj_ISUPPER;
> }
The macro's I offered were also acceptable. Every library I've seen so
far (bo*nd, djgpp, FreeBSD, gnulibc) does offer a set of macro's.
> > The following is an ANSI compliant behaving macro, it supports only
> > 'unsigned char'.
> > It yields the most efficient hard-code possible in many cases.
> >
> > #define isupper(c) ({int t=(c);unsigned v;\
> > ++t;\
> > v=__dj_ctype_flags[t];\
> > (v&__dj_ISUPPER)!=0;})
> >
> > Note that ANY change you will make to these macro's will turn them less
> > efficient. I know where I am talking about.
>
> Could you unclose some of that knowledge? Like: why should your solution
> with two temporary variables be more efficient than a simple
>
> ((int)((__dj_ctype_flags[((int)(t))+1]&__dj_ISUPPER))
Because of the gnu c compiler optimization strategies. According to the
manual, you can't just assign enough to temporary variables. If you have
a look at the produced asm code, you will that this is correct. In this
particular example you could as well write "v=__dj_ctype_flags[t+1]",
but in the other (more fail safe) example I gave, this sequence is
essential. Although, I must admit that 'eggs' does a better
optimization, but that is not unexpected, is it?
> And how could a comparison ('!=0' at the end of your code) be more
> efficient than a simple cast to int? The is* functions aren't required to
> return only 1 or 0, after all, so there's no real need to translate '!=0'
> to 1.
My proposal never yields worse code, and in case the user wants to
assign the result from this macro to e.g. a char (for memory
conservation) this will always work, something that cannot be said from
your example. In case that I have two choices which offer equivalent
efficient code, I always choose the safer solution.
--
\ Vik /-_-_-_-_-_-_/
\___/ Heyndrickx /
\ /-_-_-_-_-_-_/
- Raw text -