Path: utzoo!attcan!uunet!auspex!guy From: guy@auspex.UUCP (Guy Harris) Newsgroups: comp.lang.c Subject: Re: Do you have to cast void pointers when dereferencing them? Keywords: (With ANSI C) Message-ID: <773@auspex.UUCP> Date: 21 Dec 88 22:27:23 GMT References: <2414@ssc-vax.UUCP> <15012@mimsy.UUCP> <3050@arcturus> <749@auspex.UUCP> <3078@arcturus> Reply-To: guy@auspex.UUCP (Guy Harris) Organization: Auspex Systems, Santa Clara Lines: 64 >> >code must know the type of the lvalue to put the rvalue into the proper >> >representation. Is this not true? >> . . .Why is this any different from >> int foo; float bar; bar = foo; >> which also causes an implicit conversion from "int" to "float"? > >The statement I made was regarding implicit conversion between pointer >types. Sorry, but with regards to the question of whether the compiler knows enough about the types involved to do the conversion, that's *not* a difference. Pointer types, integral types, structured types, whatever; the compiler *does* have enough information to perform an implicit conversion in an assignment, if such a conversion is defined and is allowed. >Well, as far as K&R goes, no implicit pointer type conversion >is made (they do describe how ints can be converted to float (actually >double, but I digress)). Whether the language specifies that such conversions are performed or not is a different issue. There is sufficient information available to the compiler that it *can* perform such conversions. Why is this any different from: int foo; struct { int a; int b; } bar; foo = bar; Were a conversion between "int" and a "struct" of the given flavor defined, the compiler could arrange that it be performed; there doesn't happen to be such a conversion defined, however. >This, I believe, is the root of some of the >discussion lately that the following is non-portable: > > #define NULL (char *)0 > . . . > int *foo; > > foo = NULL; > >(note that different pointer types are on either side of the '='). Err, no, it's not the root of the discussion. The problem isn't just that this requires a pointer conversion; the problem is that some compilers may object to converting a "char *" to an "int *" without a cast (not because they don't know how to do it, but because it's not *required* to be permitted by the dpANS, and because it could be difficult or impossible in some implementations). If it's just a question of different types, #define NULL (void *)0 ... int *foo; foo = NULL; would be no better than your example; however, since the dpANS treats "void *" differently from other pointers when it comes to conversions, this construct is OK while the other isn't.