tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Local procedures


From: Antti-Juhani Kaijanaho
Subject: Re: [Tinycc-devel] Local procedures
Date: Thu, 13 Sep 2007 17:08:44 +0300
User-agent: Mutt/1.5.16 (2007-06-11)

On Thu, Sep 13, 2007 at 03:14:40PM +0200, Zdenek Pavlas wrote:
> Antti-Juhani Kaijanaho wrote:
>> as a case in point, it would help tremendously with
>> callbacks and with qsort
> What's wrong with qsort(), bsearch() and friends?  To compare two objects 
> you hardly need anything more than two references.  Charset conversion, 
> collation etc is traditionally controlled by the global environment and 
> since it's *your* code that invokes qsort(), you can easily set it as 
> needed.  Much cheaper than passing extra arg zillion times, IMO.

What's wrong is exactly that any extra parameters to the comparison
function *has* to be in the global environment - you don't get to choose
this.  This makes any code that uses qsort and bsearch nonreentrant (and
thus thread-unsafe), not to mention the clunkiness it induces in the
code.

A trivial example, in current C (untested):

8<--------------------------------------------------
static int dir;

static int cmpint(const void *av, const void bv)
{
        int a = *(const int *)av;
        int b = *(const int *)bv;
        if (a < b) return dir * -1;
        if (a > b) return dir * +1;
        return 0;
}

void sortint(int arr[], size_t n, _Bool desc)
{
        dir = desc ? -1 : +1;
        qsort(arr, n, sizeof arr[0], cmpint);
}
8<-----------------------------------------------------

Of course, real code where this issue comes up is much more complex and
it isn't as easy as here to just make different versions of the
comparison function for every variant you need.

Now, with local functions (again, untested):

8<--------------------------------------------------
void sortint(int arr[], size_t n, _Bool desc)
{
        int cmpint(const void *av, const void bv)
        {
                int a = *(const int *)av;
                int b = *(const int *)bv;
                if (a < b) return desc ? +1 : -1;
                if (a > b) return desc ? -1 : +1;
                return 0;
        }
        qsort(arr, n, sizeof arr[0], cmpint);
}
8<-----------------------------------------------------

Notice how the code becomes simpler, how we eliminate a file-scope
variable (whose only reason for being there was to communicate between
sortint and cmpint and is no business of any other functions defined in
the same file) and how sortint is thread-safe (assuming qsort is).

-- 
Antti-Juhani Kaijanaho, Jyväskylä
http://antti-juhani.kaijanaho.fi/newblog/
http://www.flickr.com/photos/antti-juhani/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]