[comp.std.c] Thoughts on `const' parameters

friedl@vsi.COM (Stephen J. Friedl) (11/30/88)

Hi folks,

     I would like a little thoughtful input on something
related to the const type qualifier.  I have been using it
heavily and am a little nervous about what seems to me to
be questionable usage.

     Let's say that I have a function like strchr(), which
might be written as:

	char *strchr(const char *string, int ch)
	{
		do
		{
			if (ch == *string)
				return((char *)string);
		} while (*string++);

		return(NULL);
	}

     What prevents me from passing a const argument (say, a string
in readonly memory), locating my desired character within the string,
and then storing a NUL there?  Nothing in the declaration prevents
this, and I've not done anything illegal like playing cast games.
If I were a paranoid.library.function.writer, presumably, one could
do one of:

	const char *strchr(const char *string, int ch)
or
	char       *strchr(char       *string, int ch)

but obviously the Fine Folks At X3J11 have thought a lot about
this; I'd like to hear the reasoning for this kind of thing.

     Note that I'm not objection to the case of strchr() here, as
it's part of the standard and it's part of history.  I am thinking
here of the general case of cheating the const mechanism.

     Steve

P.S. - did anybody consider putting `index' and `rindex' into the standard?

-- 
Steve Friedl    V-Systems, Inc.  +1 714 545 6442    3B2-kind-of-guy
friedl@vsi.com     {backbones}!vsi.com!friedl    attmail!vsi!friedl
---------Nancy Reagan on cutting the grass: "Just say mow"---------
:wq!

bill@twwells.uucp (T. William Wells) (12/01/88)

In article <957@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes:
:      Let's say that I have a function like strchr(), which
: might be written as:
:
:       char *strchr(const char *string, int ch)
:       [function body omitted]
:
:      What prevents me from passing a const argument (say, a string
: in readonly memory), locating my desired character within the string,
: and then storing a NUL there?  Nothing in the declaration prevents
: this, and I've not done anything illegal like playing cast games.

Nothing at all prevents you from doing this, other than your skill as
a programmer.  It's one of the loopholes.  All that the const modifier
says here is that the string isn't modified in the function.

---
Bill
{uunet|novavax}!proxftl!twwells!bill

gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/02/88)

In article <957@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes:
>	char *strchr(const char *string, int ch)

The reason there is a "const" in the first parameter is that it documents
the interface requirement that strchr() is not permitted to modify data
through that pointer.  The reason the result type does NOT have "the
const" qualifier is that having it there would prohibit using the returned
pointer to modify anything.

Whether data is really constant depends on whether it was defined with
the const attribute.  Pointers to qualified types are representation-
compatible with pointers to non-qualified types, so any style of char*
can be passed as the first argument to strchr().

>P.S. - did anybody consider putting `index' and `rindex' into the standard?

Not for very long.  They have been obsolete since 1980, although
systems based on obsolete C technology (such as 4BSD) continue to
provide them.  Use strchr() and strrchr() instead.

henry@utzoo.uucp (Henry Spencer) (12/02/88)

In article <957@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes:
>     Let's say that I have a function like strchr(), which
>might be written as:
>
>	char *strchr(const char *string, int ch)	...
>
>     What prevents me from passing a const argument (say, a string
>in readonly memory), locating my desired character within the string,
>and then storing a NUL there?  ...

Unless the compiler is very smart, it can't prevent this, but the effect
of the store is undefined because the original object was declared const.
(This essentially means that you shouldn't do it but X3J11 felt that a
rule against it would be unenforceable.)

The problem is that "const" is used for two different things:  creating
invariant objects, and declaring that a function is not allowed to modify
parameters (ones passed via pointers).  What is really wanted is a way
to declare strchr as taking a read-only parameter that might or might
not be const, and returning a value that is just as const as the parameter.
You might be able to do this (by using overloading and two functions) in
C++, but you can't do it in C.

So X3J11 const is a compromise, which accomplishes its most prominent
objectives but cannot fully protect const objects in the presence of
pointers.
-- 
SunOSish, adj:  requiring      |     Henry Spencer at U of Toronto Zoology
32-bit bug numbers.            | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

friedl@vsi.COM (Stephen J. Friedl) (12/07/88)

In article <957@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes:
< P.S. - did anybody consider putting `index' and `rindex' into the standard?

In article <9027@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:
< Not for very long.  They have been obsolete since 1980, although
< systems based on obsolete C technology (such as 4BSD) continue to
< provide them.  Use strchr() and strrchr() instead.

OK, does BSD have strchr() and strrchr()?  Which versions of BSD?

-- 
Stephen J. Friedl        3B2-kind-of-guy            friedl@vsi.com
V-Systems, Inc.                                 attmail!vsi!friedl
Santa Ana, CA  USA       +1 714 545 6442    {backbones}!vsi!friedl
Nancy Reagan on my new '89 Mustang GT Convertible: "Just say WOW!"

dhesi@bsu-cs.UUCP (Rahul Dhesi) (12/07/88)

"...did anybody consider putting `index' and `rindex' into the standard?"
"...They have been obsolete since 1980..."
"...OK, does BSD have strchr() and strrchr()?"

4.3BSD provides index, rindex, strchr, and strrchr.  Take your pick.
(It also provides ftruncate, an obsolete system call that modern UNIXes
don't have :-)
-- 
Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi

jbuck@epimass.EPI.COM (Joe Buck) (12/08/88)

In article <957@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes:
>< P.S. - did anybody consider putting `index' and `rindex' into the standard?

In article <9027@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:
>< Not for very long.  They have been obsolete since 1980, although
>< systems based on obsolete C technology (such as 4BSD) continue to
>< provide them.  Use strchr() and strrchr() instead.

I can see why you think index and rindex reflect "obsolete C
technology".  strchr is identical to index, and strrchr is identical
to rindex.  But it wasn't BSD who introduced an incompatible name
change, it was the USG folks.  This didn't make the older names
"obsolete", only incompatible, since at that point there were a lot of
Version 7 unixes with the older names out there.  Only with the
adoption of the new C standard will the names "index" and "rindex"
become obsolete.

In article <965@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes:
>OK, does BSD have strchr() and strrchr()?  Which versions of BSD?

Bring your C compiler into the 20th century :-) !  Add

#define strchr index
#define strrchr rindex

to your <string.h> or <strings.h> or whichever one BSD has.
-- 
- Joe Buck	jbuck@epimass.epi.com, or uunet!epimass.epi.com!jbuck,
		or jbuck%epimass.epi.com@uunet.uu.net for old Arpa sites
I am of the opinion that my life belongs to the whole community, and as long
as I live it is my privilege to do for it whatever I can.  -- G. B. Shaw