From -8207795895852752105 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: f78e5,8fe125a4c11ad8a X-Google-Attributes: gidf78e5,public X-Google-ArrivalTime: 1990-11-19 18:01:07 PST Path: gmdzi!unido!mcsun!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.std.c++ Subject: Re: X3J16/90-0091 typos and comments Message-ID: <59197@microsoft.UUCP> Date: 20 Nov 90 02:01:07 GMT References: <58861@microsoft.UUCP> <1990Nov13.222700.1194@lia> Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Organization: Microsoft Corp., Redmond WA Lines: 139 Posted: Tue Nov 20 03:01:07 1990 In article <1990Nov13.222700.1194@lia> jgro@lia.com (Jeremy Grodberg) writes: |In article <58861@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes: |>5-8 "A pointer to an object of const type can be cast into a pointer |> to a non-const type....The result of attempting to modify that |> object through such a pointer will either cause an addressing |> exception or be the same as if the original pointer had referred |> to a non-const object. It is implementation dependent whether |> the addressing expection occurs. |> |> In my opinion, this section is oxy-moronic. A standard should not |> sanctify two bipolar implementation choices that so differ that no |> reasonable strictly-conforming program can make use of both |> behaviors. |I disagree strongly on this point. By specifying exactly 2 options |for compiler writers, ANSI gives a needed degree of freedom while minimizing |the difficulty for programmers. Hm, let me try to clarify this. I see at least three good, realistic ways people might want to implement compilers regards "const." 1) A compiler that places constant objects without constructors in honest-to-god read-only memory. 2) A compiler that allows programmers to successfully cast away from const anywhere. 3) A compiler that considers a "const" declared function param as a contract with that function's implementer, allowing significant calling optimizations in the context of separate module compilations, and with libraries delivered from multiple vendors sans source code. The needs of #3 -- optimizing compilers with separate compilation modules/ libraries is not currently supported in the proposed standards. This then requires that all of an object's member values be flushed from registers over function calls, even when a "const" member function is called. library from TinCo: // .... int OB::intval() const { return this->intmember; } // ... used by Bob Customer's program: // .... int i = ob->intval(); // oops, we must purge all enregistered // members of ob, since we are not guaranteed // intval doesn't violate its const-ness // contract! [Even though, in this case // and 99.5% of the rest of the cases, // member functions *do* respect their // const-ness contracts. Thus the needs of customers desiring well-optimized code are ignored. The user of a #1 - type compiler are ill-served by the present proposal too -- the proposal says: even though the compiler can recognize that an object is going into read-only memory, and thus cast-from-const is going to bomb at runtime, the type #1 compiler is not allowed to catch this error, but rather must "accept" the cast -- even though the compilers "knows" the cast is going to result in a runtime crash. Why is this desirable??? Perhaps what the standard should specify is that either of two behaviors are allowed from compilers in a given situation: 1) the compiler can accept the cast-from-const or 2) a compiler can reject the cast-from-const ? --The end programmer result is the same as you propose: the programmer must come up with both a cast-from-const and a non-cast-from-const way of doing the job, and for a given compiler enable one or the other. ... |And I suppose you then would write: | |if (&r == 0) cerr << "r is null"; Yep. |This strikes me as too error prone. In general, a reference is just |another name for a real object. I consider null objects 'real objects.' You just aren't allowed to do anything with them other than take their address.. Such type safe sentinel objects are quite useful -- in my experience. Safer than just using NULL every where. | If you want to allow for there not |being an object, then use a pointer. Again, there's no way in general for compilers to prohibit such a programming style -- other than put in expensive runtime checks everywhere, so why not declare it "legal", and leave its use or abuse up to the tastes of an individual programmer? [give me a few reference abuses over the present pile of pointer abuses anyday :-] This constraint is the counter style of a vacuous constraint: instead of a constraint on a compiler, this one is a constraint on programmers, that keeps programmers from doing something they might want to do, with no great benefits to compilers, and in practice no changes in the legality of programs according to real world compilers, nor to the quality of code they typically generate. |>9-4 "Nonstatic data membres of a class declared without an intervening |> access-specifier are allocated so that later members have higher |> addresses within a class object." |I would like to see the stronger statement that would provide for |strict correspondance between C++ class data members and ANSI-C structs. |Perhaps that was what was intended by this requirement, although it |appears in fact to be too weak to have much of any usage. Again, the meaning of order of addresses is only defined within an array of like objects, which members of a object aren't, so why define a constraint on conforming compilers that can't be used by conforming programs? If programmers desire to perform programming hacks that are outside of the language, let them choose compilers that support those hacks. If programmers desire their programs to run on all conforming compilers, let them then write conforming programs. If the ordering of members of an object is to mean something, then add wording to the standard whereby programmers are allowed to do _something_ legal and conforming based on these constraints. As it stands today, there's no legal way for a programmer to make use of the ordering of members. So why then constrain compilers? If you believe that order of members is an important thing to have in the language, then please add language to the standards allowing programmers to do _something_ [_anything_ !] legal based on that ordering. But as it now stands there is nothing legal programmers are allowed to do with member order. Thus member ordering is a vacuous constraint on compilers. The C++ standard should represent a contract between C++ programmer and compiler vendors. Constraints placed on compiler vendors should be matched by permissions alloted the C++ programmer. Constraints placed on C++ programmers should be matched by permissions alloted the C++ compiler vendor. Constraints on one, without matching permission on the other, represents an ill-formed contract that benefits neither, but rather is to everyone's disadvantage. Which is the basis of my above complaints.