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