[comp.lang.c] index and rindex question...

Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) (01/31/90)

In an article of <27 Jan 90 02:04:19 GMT>, (Conor P. Cahill) writes:

 >They are equivalent to the system V functions strchr() and strrchr(),
 >respectively.

  Both the strchr() and strrchr() functions made it into the ANSI spec while  
index() and rindex() didn't. I believe this was because the latter two  
functions on some systems return an int offset of the character rather than a  
pointer to it. Based on this usage, I use:

#define index(s,c)  ((strchr((s),(c))) ? (size_t)(strchr((s),(c))-(s)) : -1)
#define rindex(s,c) ((strrchr((s),(c))) ? (size_t)(strrchr((s),(c))-(s)) : -1)

  Note that these are *not* safe macros since the `s' argument may be  
evaluated three times and the `c' argument twice. 

cpcahil@virtech.uucp (Conor P. Cahill) (02/01/90)

In article <11716.25C6818B@urchin.fidonet.org> Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) writes:
>In an article of <27 Jan 90 02:04:19 GMT>, (Conor P. Cahill) writes:
>
> >They are equivalent to the system V functions strchr() and strrchr(),
> >respectively.
>
>  Both the strchr() and strrchr() functions made it into the ANSI spec while  
>index() and rindex() didn't. I believe this was because the latter two  
>functions on some systems return an int offset of the character rather than a  
>pointer to it. Based on this usage, I use:

The original poster has asked about the "BSD" functions index() and rindex().
The documentation as far back as 4.1BSD shows that they are the equivalent
to strchr()/strrchr() (i.e. they return pointer to char).

>#define index(s,c)  ((strchr((s),(c))) ? (size_t)(strchr((s),(c))-(s)) : -1)
>#define rindex(s,c) ((strrchr((s),(c))) ? (size_t)(strrchr((s),(c))-(s)) : -1)

This would work to replace index() only when the original software came
from a system that did not use the BSD implementation.  I would guess that
it would be rather rare today. If I remember correctly, PWB Unix had an
index() that returned int.

For most of the code that you run into today (yes, I know that there are
still V6 and PWB systems around, in fact I work on one every once in a 
while) the following defines will suffice:

	#define index(s,c)	strchr(s,c)
	#define rindex(s,c)	strrchr(s,c)

-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

karl@haddock.ima.isc.com (Karl Heuer) (02/02/90)

In article <11716.25C6818B@urchin.fidonet.org> Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) writes:
>Based on this usage, I use:
>#define index(s,c)  ((strchr((s),(c))) ? (size_t)(strchr((s),(c))-(s)) : -1)
>#define rindex(s,c) ((strrchr((s),(c))) ? (size_t)(strrchr((s),(c))-(s)) : -1)
>
>Note that these are *not* safe macros since the `s' argument may be
>evaluated three times and the `c' argument twice.

They also do twice as much work, and would be confusing to anyone who expects
those names to have the V7/BSD semantics.  Wouldn't it be simpler to just use
strchr and strrchr, which should be present in any modern system?

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint

chris@mimsy.umd.edu (Chris Torek) (02/02/90)

In article <11716.25C6818B@urchin.fidonet.org>
Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) writes:
>  Both the strchr() and strrchr() functions made it into the ANSI spec while  
>index() and rindex() didn't. I believe this was because the latter two  
>functions on some systems return an int offset of the character rather
>than a pointer to it.

Unless there are some *extremely* broken systems out there (this is
always a possibility), there are no systems on which index() and rindex()
return an int.

index and rindex, wherever present, should be EXACTLY identical to
strchr and strrchr, so that, e.g.,

	#define index strchr
	#define strrchr rindex

should work (if you have both in your C library).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) (02/03/90)

In an article of <1 Feb 90 16:33:33 GMT>, (Karl Heuer) writes:

 >>#define index(s,c)  ((strchr((s),(c)))?(size_t)(strchr((s),(c))-(s)):-1)
 >>#define rindex(s,c) ((strrchr((s),(c)))?(size_t)(strrchr((s),(c))-(s)):-1)
 >>
 >>Note that these are *not* safe macros since the `s' argument may be
 >>evaluated three times and the `c' argument twice.
 >
 >They also do twice as much work, and would be confusing to anyone who 
 >expects those names to have the V7/BSD semantics.  Wouldn't it be simpler to 
 >just use strchr and strrchr, which should be present in any modern system?

  The point is that I use them primarily for porting code which *doesn't* use  
V7/BSD semantics and secondarily in situations where I need an array index  
rather than a pointer returned. Apparently you've never had a requirement for  
either. Although both circumstances are rare, both exist I can assure you.

  As for "doing twice as much work", any reasonably decent optimizing compiler  
will only call the function once although either macro could be implemented as  
a function in order to guarantee both safety and optimal execution speed. 

reidc@eliot.UUCP (Reid Carson/Development) (02/05/90)

In article <22236@mimsy.umd.edu>, chris@mimsy.umd.edu (Chris Torek) writes:

> Unless there are some *extremely* broken systems out there (this is
> always a possibility), there are no systems on which index() and rindex()
> return an int.
> 
> index and rindex, wherever present, should be EXACTLY identical to
> strchr and strrchr ...

  On at least one version of Masscomp's UNIX I've used, index/rindex exist,
as well as strchr/strrchr.  The functions work identically, EXCEPT, that
index/rindex return -1 (cast to a pointer, I suppose), in case of no match,
rather than a null pointer.  Mind, this was some time ago, and I would imagine
it's been fixed by now, but verbum sap.
-- 
Reid W. Carson (uunet!pyrdc!eliot!reidc)  -  Unitech Software, Inc.
What I tell you three times is true.

richard@aiai.ed.ac.uk (Richard Tobin) (02/14/90)

> any reasonably decent optimizing compiler will only call the function once

Anyone know of a compiler that does this for functions like strchr?

-- Richard
-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

karl@haddock.ima.isc.com (Karl Heuer) (02/15/90)

>> any reasonably decent optimizing compiler will only call the function once
>
>Anyone know of a compiler that does this for functions like strchr?

I was going to say that gcc has an extension to recognize pure functions, but
then I realized that strchr() is not pure--its result depends on not only the
value of its arguments, but also the *contents* pointed to.  So, in order for
a compiler to correctly optimize out a second call to strchr(), it has to not
only know that strchr() is an almost-pure function (probably by recognizing it
as a builtin) but it also has to prove that the pointed-to string could not
have been modified between the two calls.  This is a sufficiently hard problem
that I doubt that any current compilers bother to check for it.

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint

Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) (02/17/90)

In an article of <13 Feb 90 21:12:22 GMT>,  (Richard Tobin) writes:

 >> any reasonably decent optimizing compiler will only call the function once
 >
 >Anyone know of a compiler that does this for functions like strchr?

Nope - speak in haste, repent in public, to paraphrase an old homily...