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 Mime-Version: 1.0 To: Bill Currie Cc: Nate Eldredge , 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> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Precedence: bulk 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