Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.std.c++ Subject: Re: Pre-proposal: ~const [Rev 1.6] Message-ID: <60083@microsoft.UUCP> Date: 27 Dec 90 19:56:22 GMT References: Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Distribution: comp Organization: Microsoft Corp., Redmond WA Lines: 114 In article ngo@tammy.harvard.edu (Tom Ngo) writes about ~const [not-const] and ~volatile [not-volatile]. I like this idea, and suggest below further "flavours" that it should be possible to revoke or invert through negation. ---- I think ~const would be a good idea, iff we use this opportunity to clean up the problems with cast-from-const. Namely, if we have a supportive way to do caching "correctly" without cast-from-const, then we can take the opportunity to make cast-from-const a deprecated, strictly "implementation dependent" construct -- a construct which is not guaranteed to work as you intend in all situations on all compilers. This would allow optimizing compilers a chance to do meaningful optimizations on const member functions invoked on const objects, and would allow compilers to at least generate warnings on casts-from-const that appear to have little chance of working correctly. What I am suggesting then, is that the statement in 5.4 [regards an object cast from const] be changed slightly to: "The result of attempting to modify that [const] object through such a [non-const] pointer or reference is implementation dependent. Possible results include acting as if the object were originally declare non-constant, or addressing exceptions or other undesired behaviors." and the language in 7.1.6 be changed slightly to: "A const object of a type that does not have a constructor or a destructor might be placed in readonly memory. A const object that does have a constructor might be placed in discardable memory -- virtual memory that is only paged to disk the first time faulted out after construction. Therefor, the effect of any write operation to any const part of any such object is undefined." [constructed constant bit maps would be good candidates for such discardable memory] |[-] Nothing can be done with the ~const specifier that can't | already be done with the existing constructs. [+] On the other | hand, there are other things in C++ that are really just syntactic | sugar. For instance, there is really no difference between a | reference "X&" and a constant pointer "X *const", besides the | obvious syntactic difference. IE in the typical example case where you have a const object except for one or two caching member variables, one could just write two intermediate classes -- one with non const fields, one with all fields const except the caching member varibles? Yuck. Or are you saying that today one is guaranteed to be able to cast from const? -- I claim not. This is another example of "enabling" verses "supporting." It seems that the issue of caching member variable has caused hassles often enough that C++ ought to support it, not just "enable" it. Having explicit support for non-const members within const objects then lets us clean up the issue of cast from const, and clearly label such as "implementation dependent" in all cases. Other examples of supporting verses enabling in C++ is MI support, verses having to explicitly linearize every method to combine the functionality of two classes. Or having overloadable operator dot to support delegation, smart references, etc, verses having to write a forwarding class that trivially re-derives all methods of a class. Or having access adjustments so that individual members can be adjusted from a default access, rather than having to specify the access of each member individually. | If this usage of ~const were to be adopted, we would be obligated | to consider a similar type-specifier, ~volatile, whose purpose is | to remove the volatile attribute from an unknown type. What's the status of const volatile? Does the ~'s then imply we also have ~const volatile, const ~volatile, ~const ~volatile .... ???? ....if const volatile is a relatively rare construct, then then inverting messiness above is not a big deal -- inverting a const volatile flavor is a rare action taken on an already rare construct. I support this ~const idea. I think it helps resolve a lot of the "does const mean const?" debates. ---- Further implication [in my mind] : If you can undo const and volatile flavors, maybe you ought to be able to undo other default flavors explicitly: ~virtual [not virtual] ~inline [not inline] In particular, then one could add a ~inline flavor to one particular method declared implicitly inline in a class declaration -- to aid debugging that one method. You wouldn't have to hack your class to move that one method being debugged from the .h file to the .c file. A complete list of keywords that I think could be possible candidates for negation is: ~const do allow this object to be changed after init. ~inline do make this method outline -- IE a real function call. ~register do not enregister this object, not even when optimizing [similar to volatile?] ~virtual do not put this method in the vtable. [keep the inherited vtable entry?] ~volatile do allow optimization on this object. Again, C++ does "enable" work arounds for all this negations. Typically the work around entails not specifying a flavor in a superclass, derive two subclasses, one with the flavor, and one without, etc. "Obviously", encapsulation and reusability are served if flavours specified in the superclass can be negated by sub-classes, without having to hack the super class. Comments?