delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/05/07/04:05:30

Sender: vheyndri AT rug DOT ac DOT be
Message-Id: <35516B1B.44B4@rug.ac.be>
Date: Thu, 07 May 1998 10:04:43 +0200
From: Vik Heyndrickx <Vik DOT Heyndrickx AT rug DOT ac DOT be>
Mime-Version: 1.0
To: Bill Currie <bill AT taniwha DOT tssc DOT co DOT nz>
Cc: Nate Eldredge <nate AT cartsys DOT com>, djgpp-workers AT delorie DOT com
Subject: Re: Far string/mem functions
References: <19980427032245 DOT AAD5484 AT ppp100 DOT cartsys DOT com> <354439F1 DOT 7CC2 AT rug DOT ac DOT be> <354586DF DOT 44A78F00 AT taniwha DOT tssc DOT co DOT nz> <35459F49 DOT 6AA0 AT rug DOT ac DOT be> <3545AC81 DOT 34B3F740 AT taniwha DOT tssc DOT co DOT nz>

Bill Currie wrote:
> 
> Vik Heyndrickx wrote:
> >
> > Not suggested until now. I thought of it a little, but there is nearly
> > no use for having a single variable instead of (sel, ofs).
> > 'long long' as a return value is nearly as bad as the situation
> > experienced with functions like lseek that return -1 on failure: it will
> > eventually turn in some problem.
> 
> True, that's why I suggested the structure hack below.
> 
> > > What about a __far_pointer structure? ie
> > >
> > > typedef struct {
> > >     unsigned long offs __attribute__((packed));
> > >     unsigned short sel __attribute__((packed));
> > > } __far_pointer;
> >
> > The disadvantage may be that users will have to declare a struct,
> 
> Why?  __far_pointer would be declared by the `far' function header file.

There is problem with return a pointer instead of the position of the
``match'' position within the string. On DJGPP the problem is really
well hidden since DJGPP has no far pointers but on systems that do
support far pointers as (seg, ofs) you can observe the following
problem:

Let's consider the standard ``memchr'' function:
  void *memchr (const void *, int, size_t)
It takes a ``const void*'', and returns a ``void*'' pointing into a
potentially UNmodifyable memory region.
'f course memchr was redesigned this way in the latest ANSI standard to
prevent existing programs from breaking when passed a non-const pointer,
so let's consider a self-implemented function ``memchr_vh0'' which has
the same functionallity as ``memchr'', BUT with the following prototype:
  const void *memchr_vh0 (const void *, int, size_t)
Passing a const pointer to this function will always work as wanted. But
when a non-const pointer is passed, still a const pointer is returned
and more than often that is not what the user wants (from experience).
There's a cumbersome and very ugly workaround, but since one way or
another it always fails to work neatly, my understanding is that the
orginal standard committee that implemented the library requirements
would have chosen a solution similar to mine too when ``const'' was part
of the language those days.

These days, passing a single argument more to a function is really not a
big time/space issue anymore, so strongly feel }:-) that memchr would be
prototyped and implemented on a system that supports far pointers like:

int memchr (size_t *pos, const void *, int, size_t cnt);

I've been using these kind of function (not str/mem* fns) for some time
now, and until know I've found nothing bad about their use yet :)

Since we cannot alter the standard, but we can set our own for the far
versions of the function it strongly feel we should do it right, and IMO
this is the only one that feels right (apart from the ordening of the
arguments).

The solution Nate uses, which is returning an offset within the segment
may seem right for DJGPP, but I think it will yield portability problems
for systems that do support real far pointers like the i860 ;-)
The solution I propose doesn't. IMO, compatibility is not only a matter
of writing programs that can be compiled and run as expected on systems
and compilers that already exist, but also write your programs in a such
a way that they can be compiled on  systems or with compilers that don't
exist yet. Especially in the past this was apparently a common way of
working, but I cannot approve, not even in 2000 years.
 
> > Returning the position within the string, however, seems still more
> > useful.
> 
> But you can return a __far_pointer with the selector and offset (?
> irrelevant, really, but I feel both is best) set to 0.

Yes you can, but note my (const/non-const) objections above.

Cheers.

-- 
 \ Vik /-_-_-_-_-_-_/
  \___/ Heyndrickx /
   \ /-_-_-_-_-_-_/  Knight in the Order of the Unsigned Types

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019