Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84 SMI; site sun.uucp Path: utzoo!linus!decvax!decwrl!sun!guy From: guy@sun.uucp (Guy Harris) Newsgroups: net.micro,net.lang Subject: Re: Unchecked conversion in Ada Message-ID: <2341@sun.uucp> Date: Sun, 23-Jun-85 15:32:10 EDT Article-I.D.: sun.2341 Posted: Sun Jun 23 15:32:10 1985 Date-Received: Mon, 24-Jun-85 08:20:58 EDT References: <1649@reed.UUCP> <186@harvard.ARPA> <453@calmasd.UUCP> Organization: Sun Microsystems, Inc. Lines: 99 Xref: linus net.micro:9627 net.lang:1423 > > > ...converts between...two types bit-to-bit; something like C's casts. > > > C casts are not bit-for-bit conversions unless the conversion happens > > to be implemented as such... > > I would put it differently: C casts ARE bit-for-bit conversions except > sometimes for numerical types. "You play Bach your way; I will play him his way." -W. Landowska You can read K&R your way; I'll read it their way. The only mention they make of a conversion being a copy of the bits is under the int-to-unsigned conversion: The value is the least unsigned integer congruent to the signed integer (module 2^wordsize). *In a 2's complement representation*, this conversion is conceptual and there is no actual change in the bit pattern. Maybe they should have left the sentence about 2's complement representation out, so people wouldn't think of it as a bit-for-bit copy. As for pointer-to-integer conversions: A pointer may be converted to any of the integral types large enough to hold it. ... The mapping function is also machine dependent, but is intended to be unsurprising to those who know the addressing structure of the machine. This may be a bit-for-bit copy on most machines, but it need not be. > To the extent that one can speak of C having any semantics at all, this > makes the semantics of C casts grossly inconsistent. For instance, > (int) 2.3 == 2, but (*var=2.3, *((int *) var) ) == garbage; So? Presumably, in other languages (like Ada), if you convert 2.3 to an integer, you get 2, while if you do an (unchecked) conversion of a pointer to a floating-point variable into a pointer to an integer, and then dereference that pointer, you also get an integer with the same bit pattern as the floating-point number in that variable (which isn't "garbage" if you're picking the bits apart). > I don't even want to begin to think about the semantics of conversions > involving unsigned's. Why not? The C rules are mathematically reasonable; what else would you do, aside from generating an exception of the signed quantity is negative. Or is the lack of checking what you object to? I might agree with you on that one, although C doesn't have an exception mechanism (people have debated the merits of general exception mechanisms, so they're not considered a Good Thing by the entire community). > I also don't understand what `happens to be implemented as' means. What > other possibilities are there for converting pointers to integers, > incompatible pointers, etc.? Well, I'm not sure why you have trouble understanding it, but I'll explain; I was referring to the int <-> unsigned conversion, which happens to be implemented that way on 2's complement machines. Pointer-to-pointer conversions aren't necessarily bit-for-bit on word-addressed machines; byte pointers (like "char *") and word-pointers (like all other pointers might be) don't have the same bit pattern (or even the same number of bits) in all implementations. > So perhaps it was a bad idea to compare Unchecked_conversion in Ada to C > casts. I just wanted to use a reference point familiar to C users. A better comparison would point out that C has no formal unchecked conversions, and as such certain conversions which should require the programmer to say "yes, I'm cheating, but I know what I'm doing" don't. If C had such a concept, conversion of pointers to integers, integers to pointers, and pointers to other types of pointers should require that the programmer explicity specify the conversion as unchecked, so that they're at least reminded that they're Doing Something Potentially Nasty. In practice, the portable C compiler does generate warnings for all three of those cases; you can defeat those warnings by doing the cast on the RHS of the assignment instead of by default in the assignment. However: 1) this is a gross hack, since a cast is merely a way to explicitly indicate a coercion - or at least that's what it should be ("An expression preceded by the parenthesized name of a data type causes conversion of the value of the expression to the named type.") "a = b" and "a = (typeof a)b" should be equivalent expressions. 2) warnings can be ignored, so to be truly secure it should give something stronger than a warning. C certainly has its share of things to criticize; however, a large number of them are shared by other popular languages of its general class. Criticism should be accurate and fair; I think the point you really want to make (i.e., that certain conversions in C should not be so cavalierly accepted) can be made in a better way (by saying as much, rather than by dismissing C casts as bit-for-bit copies). Guy Harris