diamond@tkou02.enet.dec.com (diamond@tkovoa) (08/07/90)
In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes: SF> extern int stat(char *filename, struct stat *stptr); SF>Shouldn't the "filename" argument be const qualified? In article <1893@tkou02.enet.dec.com> diamond@tkou02.enet.dec.com (diamond@tkovoa) writes: ND>But if const is included, it would break a lot of code that presently ND>works under Unix(tm) operating system. In article <386@taumet.com>, steve@taumet.com (Stephen Clamage) writes: SC>No, it wouldn't break any code. A const-qualified parameter type may SC>be passed a non-const argument, but the reverse is not true. Section 3.3.2.2: "Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter." Consider: typedef const char * const const_ptr_to_const_char; /* (1) */ typedef const char * modifiable_ptr_to_const_char; /* (2) */ typedef char * const const_ptr_to_modifiable_char; /* (3) */ typedef char * modifiable_ptr_to_modifiable_char; /* (4) */ I interpret that the "unqualified version" of a type only removes the top-level qualifiers. For example, the unqualified version of (1) is (2), not (4). And that (2) is already unqualified. Section 3.1.2.5 supports this interpretation. "Any type so far mentioned is an unqualified type. Each unqualified type has three corresponding qualified versions of its type: a const-qualified version, a volatile- qualified version, and a version having both qualifications." A const-qualified version does not seem to be one which propagates a "const" qualification down the chain of indirection. If this is true, then an argument of type (1) or (2) can be passed to a parameter of type (1) or (2), and an argument of type (3) or (4) can be passed to a parameter of type (3) or (4), but not (2) to (4). SC>If the parameter is not const-qualified, you cannot pass it a literal SC>string without a cast. So the *failure* to const-qualify will break SC>existing code. That is, with the above prototype, SC> r = stat("myfile", &data); SC>is illegal under ANSI. Section 3.1.4: "For character string literals, the array elements have type char, and are initialized ..." Not type const char. The Rationale emphasizes this. Capability to change the elements from their initialized values has usually been considered implementation-dependent. The Rationale for section 3.1.4 further emphasizes the matter of what cannot be assigned to what, which seems to support my opinion on the function arguments. SC>But given SC> extern int stat(const char *, struct stat *); SC> ^^^^^ SC>the following are legal: SC> char *fname; /* not const */ SC> stat(fname, &data); SC> stat("myfile", &data); Exactly backwards. I think these become illegal. In article <17240@haddock.ima.isc.com> karl@kelp.ima.isc.com (Karl Heuer) writes: KH>Sorry, 3.2.2.3 agrees with me. It doesn't break existing code, because it's KH>perfectly legal to assign from `char *' to `char const *'. (Only *removing* KH>the qualifier requires an explicit cast, and even then you'd better know what KH>you're doing.) Section 3.2.2.3 specifies what pointers may be converted and still compare equal. It does not specify that conversions are applied automatically without a cast. Sorry, but I believe it is irrelevant to the topic. -- Norman Diamond, Nihon DEC diamond@tkou02.enet.dec.com This is me speaking. If you want to hear the company speak, you need DECtalk.