Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!uunet!pdn!tscs!tct!chip From: chip@tct.uucp (Chip Salzenberg) Newsgroups: comp.std.c++ Subject: Re: Conversions to/from void*, redux Keywords: Sun, C++ Message-ID: <27D5708A.29CF@tct.uucp> Date: 6 Mar 91 22:43:22 GMT References: <70935@microsoft.UUCP> <27D18D22.1608@tct.uucp> <71031@microsoft.UUCP> Organization: Teltronics/TCT, Sarasota, FL Lines: 87 According to jimad@microsoft.UUCP (Jim ADCOCK): >Operator new and delete are *special* functions. Even if specified by the >user, there is no reason why a compiler couldn't generate two versions of >operator new and delete from the user specification. I see no reason to set "operator new" and "operator delete" aside into a set of "special" functions. They are "special" only in that the compiler calls them in contexts where their names are not explicitly mentioned, and in C++ that's not anything special. They're just plain functions: you can take their address and call them indirectly, etc. >A Cray C++ compiler might want to automatically generate two versions >of new and delete from the user specifications. One version would assume >"byte" alignment, and the other word alignment. The compiler would be >smart enough to intuit the right new/delete based on the type of the >object involved. First, I'd like to know what, _exactly_, the compiler would do differently when in the two compilations of "operator new". To me, such a double compilation seems wasteful and useless. But let's assume that such an implementation existed, and let's assume that there's a good reason for double compilation. Now, put yourself in the shoes of the implementor, and answer me this question: "If you can compile my one function two ways, thus adapting for alignment restrictions, why can't you make other casts of |void*| to |T*| work by using the same trick?" >In article <27D18D22.1608@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes: >|If that same compiler is unable to support such a cast in normal code, >|it is Brain Dead and not worth the floppy it's distributed on. > >I disagree and counter-claim that it is any programmer who insists on >doing such pointer hacks who is brain-dead. It's not so much that I insist on _doing_ such pointer conversions; if they were non-portable, I would avoid them. What I insist is that there be a recognition that the ARM already implicitly constrains implementations to be capable of them, unless the implementor is just being contrary. >|As has been mentioned before, ANSI C requires that |void*| and |char*| >|have the same representation. If ANSI C++ does not conform to this >|requirement, then compatibility with C libraries is compromised. >|That may or may not matter to you, of course, but it matters to me. > >It is acceptible to me that void* and char* have "the same representation" >[whatever that means -- hopefully the ANSI-C committee were not trying >to specify *implementation* choices] In fact, they _do_ specify this particular implementation choice. In particular, the following code must output "yes" in an ANSI C environment: #include #include #include main() { char c; char *cp = &c; void *vp = &c; assert(sizeof(cp) == sizeof(vp)); puts(memcmp(&cp, &vp, sizeof(cp)) == 0 ? "yes" : "no"); exit(0); } Since ANSI C++ will be based on ANSI C, I find myself hard-pressed to imagine a rationale for breaking it under ANSI C++. > -- as long as C++ then does not *require* that it be possible to convert >from char* to class X*. But it already does require that conversino to be possible! Remember that the definition of "object" is "region of storage" (section 3), and read from ARM section 5.4, with my comments in [brackets]: It is guaranteed that a pointer to an object of a given size [such as class T] may be converted to a pointer to an object of the same or smaller size [such as char] and back again without change. QED. -- Chip Salzenberg at Teltronics/TCT , "All this is conjecture of course, since I *only* post in the nude. Nothing comes between me and my t.b. Nothing." -- Bill Coderre