Path: utzoo!utgpu!watmath!att!cbnewsl!dfp
From: dfp@cbnewsl.ATT.COM (david.f.prosser)
Newsgroups: comp.lang.c
Subject: Re: use of if (!cptr) and if (cptr), where cptr is a *)
Message-ID: <1429@cbnewsl.ATT.COM>
Date: 9 Aug 89 20:30:38 GMT
References: <10099@mpx2.mpx.com> <660046@hpclwjm.HP.COM> <1603@mcgill-vision.UUCP>
Reply-To: dfp@cbnewsl.ATT.COM (david.f.prosser)
Organization: AT&T Bell Laboratories
Lines: 62

In article <1603@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes:
>In article <660046@hpclwjm.HP.COM>, walter@hpclwjm.HP.COM (Walter Murray) writes:
>> As a further exam[p]le of the latitude you have in writing a null
>> pointer constant, the following would also be legal.
>
>>    if (cptr == (signed short)0.3+sizeof(char)-'\1'
>> 	       +sizeof((long int*)myfunc()+3,000)-sizeof'M');
>
>> I think any ANSI-conforming compiler will accept this statement.
>
>Leaving aside the point (on which even Chris Torek is unsure) of
>whether or not a cast produces a non-"constant" expression, this is
>valid only if sizeof(long int *) equals sizeof(int), which isn't true
>everywhere.

Not as far as I can see.  The relevant part of the expression is

	sizeof((long int*)myfunc()+3,000)-sizeof'M'

and as the first sizeof expression is actually a (hidden) comma
expression, it is equivalent to

	sizeof(000)-sizeof'M'

Since 000 is an (octal) int constant, it must be the same size as 'M'.

>
>Your expression also requires that myfunc() be declared (possibly
>implicitly) as returning something that can be cast into (long int *);
>this might not be true (eg, it may return a struct).

Assuming no other information, then myfunc() is implicitly declared to
return int.  Any integral type can be converted to any pointer type
with a cast.  The result of the conversion is implementation-defined,
but the conversion is valid.

>
>Question: If it does happen that sizeof(long int *) == sizeof(int), is
>it correct to write "if (cptr == sizeof(long int *)-sizeof(int))"?  In
>other words, must we compare against an integer constant expression
>which is guaranteed to be zero or may we get away with using one which
>just happens to be zero for the compilation environment in use?

This is an example of a "conforming" program, instead of the above which,
as far as I can tell, is "strictly conforming".  (A strictly conforming
program works on all conforming implementations; a conforming program is
acceptable to at least one conforming implementation.)

>
>I'd guess it's the latter, but am curious.
>
>If I'm right, is it then possible to use this as a means of drawing a
>guaranteed compile-time warning if sizeof(long int *) is *not* equal to
>sizeof(int), or are compilers not required to warn about pointer/int
>mismatches like that?  (Yes, I know the warning probably will not be
>very descriptive of the *real* problem. :-)

You are correct: a diagnostic is required for an equality test of a
pointer with a nonzero integral expression.  Just how useful this is
is not at all clear.

Dave Prosser	...not an official X3J11 answer...