throopw@rtp47.UUCP (Wayne Throop) (06/23/85)
The C notion of "cast" and the Ada notion of "unchecked conversion" (at least the way I read K&R & the ANSI Ada standard) are not really related, but a question about casts of pointers raised by Stavros Mcrakis leads me to respond. > > 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. 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; I don't even want to begin to think about the > semantics of conversions involving unsigned's. Close, but not quite right. From page 42 of K&R: In the construction (type-name) expression the expression is converted to the named type by the conversion rules above. where "the conversion rules above" went to great lenghts to detail conversions done when when various arithmetic operators are fed "mismatched" operands (including some of the messy unsigned cases). K&R then proceeded to use casts only when dealing with pointers in most of the book. Nowhere is it stated explicitly what conversions are done with pointers, and this is the main point I want to raise, below. > 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.? "Happens to be implemented" is just the right phrase, it seems to me. Conceptually, a cast is a production of a *new value*, not just looking at a bucket of bits through given-type colored glasses. But here is the main point, about casts of pointers. K&R strongly imply that casts of pointers deal with alignment problems. That is, given a machine where (say) 16-bit integers must be instantiated in storage with address aligned mod 16 bits, and 8-bit characters must instantiated in storage with address aligned mod 8 bits, the cast "(char *) int_ptr" might pass the bits thru unchanged, but "(int *) char_ptr" would be free to align the pointer value mod 16 bits. The above covers a covers a use for casts between incompatible pointer types. There is also a use for a non-nop transform for pointers to integers (and vice versa). On a machine where 8-bit-granular pointers have a *different bit-wise representation* than 16-bit-granular pointers, K&R implies that it is up to the user to be careful when assigning pointers to integers and then back to pointers to be sure that the pointer types involved are the same type. Unfortunately, almost no current C programs follow this K&R compatible discipline. Therefore, to support those (strictly speaking, incorrect) programs, a compiler might (and I know of a compiler that does) always convert 16-bit granular pointer format to 8-bit granular format when the pointer is cast to or stored in an integer. > 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. I wouldn't exactly call it a bad idea, since even though the concepts are not *closely* related they *are* related. However, I'd say that Ada's notion of unchecked conversion is more closely related to (the nonportable) use of C's union types to view memory using a variety of type interpretations. It might have been better to use that analogy. [As an aside, I think that all pointer formats should be 1-bit-granular to get rid of such things as pointer-format nonsense but that belongs in another newsgroup, net.arch] [Another aside. The original thread of this conversation (I think) was "Who needs Ada?". Well, *I* need Ada (or *some* strongly typechecked language) so that I don't have to worry about stuff like pointer formats and what happens to them when they are abused. I druther the compiler didn't let me abuse them in the first place. That is, the compiler should *not let* pointers be assigned to integers, except via unions or explicit unchecked conversion. But I suppose that belongs in net.religion.] [Sorry this article is so long. I didn't have time to make it shorter. Can you say "long-winded"? Can you say "overkill"? I knew you could.] -- Wayne Throop at Data General, RTP, NC <the-known-world>!mcnc!rti-sel!rtp47!throopw
david@ukma.UUCP (David Herron, NPR Lover) (06/25/85)
In article <74@rtp47.UUCP> throopw@rtp47.UUCP (Wayne Throop) writes: > ... >But here is the main point, about casts of pointers. K&R strongly imply >that casts of pointers deal with alignment problems. That is, given a >machine where (say) 16-bit integers must be instantiated in storage with >address aligned mod 16 bits, and 8-bit characters must instantiated in >storage with address aligned mod 8 bits, the cast "(char *) int_ptr" >might pass the bits thru unchanged, but "(int *) char_ptr" would be free >to align the pointer value mod 16 bits. This is why (when I'm coding) I make extensive use of casts, etc. Especially when I'm the least big sure of how the types will mix. Generally, I feel that it's the programmers duty to give the compiler *as much* information as possible. That is the only way the compiler will be able to make any informed intelligent decisions about what code to generate. And if it still doesn't come out right then you can point fingers at the compiler writer and shout "LAZY!". This is certainly the way the C standard is heading. At least in the draft as of last October, it mainly consisted of strict definitions of what all the operators did. But also general enough that it wasn't tied very closely to a PDP-11 type architecture. (I have April's draft but haven't looked at it yet). But with such a definition (and compilers that follow it) a programmer can confidently write expressions and know that the compiler knows enough about the machine to know what conversions he has in mind. What's wrong with giving the compiler a lot of intelligence? Teaching it what all the conversions mean. And so forth. Then when you have your intelligent compiler, the programmer can make use of the intelligence to have more confidence in their code. At least that is the ideal. >[Another aside. The original thread of this conversation (I think) was > "Who needs Ada?". Well, *I* need Ada (or *some* strongly typechecked > language) so that I don't have to worry about stuff like pointer > formats and what happens to them when they are abused. I druther the > compiler didn't let me abuse them in the first place. That is, the > compiler should *not let* pointers be assigned to integers, except via > unions or explicit unchecked conversion. But I suppose that belongs in > net.religion.] I prefer to describe in detail what I want to do. But I also find assembly language cumbersome (It takes too many lines of code to describe a simple expression). It's like the reason I drive a standard shift, I like having control of my tools. -- --- David Herron --- ARPA-> ukma!david@ANL-MCS.ARPA or ukma!david<@ANL-MCS> --- or david%ukma.uucp@anl-mcs.arpa --- Or even anlams!ukma!david@ucbvax.arpa --- UUCP-> {ucbvax,unmvax,boulder,oddjob}!anlams!ukma!david --- {ihnp4,decvax,ucbvax}!cbosgd!ukma!david "It's *Super*User* to the rescue!"