[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New warnings (hopefully) in gcc 3.4

From: Nicola Pero
Subject: Re: New warnings (hopefully) in gcc 3.4
Date: Wed, 3 Sep 2003 13:09:57 +0100 (BST)

> > NSMenu.m: In function `-[NSMenu update]':
> > 
> > NSMenu.m:804: warning: multiple methods named `-validateMenuItem:' found
> > ../Headers/AppKit/NSMenu.h:562: warning: could be using 
> > `-(BOOL)validateMenuItem:(id <NSMenuItem>)menuItem'
> > ../Headers/AppKit/NSMenu.h:567: warning: or 
> > `-(BOOL)validateMenuItem:(NSMenuItem *)aMenuItem'
> > NSMenu.m:804: warning: (Messages matching multiple method prototypes
> > NSMenu.m:804: warning: will be assumed to return `id' and accept
> > NSMenu.m:804: warning: `...' as arguments.)
> > NSMenu.m:804: warning: assignment makes integer from pointer without a cast
> > 
> > It seems there are two method definitions, both taking an object argument,
> > and returning a BOOL.
> > 
> > They differ in the details of the class/protocol declared for the object
> > argument, which is only used to do compile time type-checking, but should
> > not affect generated code.
> In this case, yes.
> > It's uncertain how type-checking is to be done for the object argument
> > (and the compiler is right to complain in that respect), but it's obvious
> > that the method call should be compiled as taking an object argument and
> > returning a BOOL, since both declarations agree on that.
> I disagree. From a compiler pov, we don't know that the receiver
> responds to this method at all in this case. Instead, we gamble that if
> all prototypes for the selector are identical, then the prototype for
> this receiver will probably be the same (this is case d. in my list).
> When the prototypes aren't identical (case c.), we're stuck with a bunch
> of prototypes and a receiver not known to implement any of them. I'm not
> really happy about trying to combine prototypes or picking one randomly
> (they might all be wrong, for all we know).

Ok.  But from that point of view, even if you have a single prototype
given, it might be all wrong, for all we know.

Maybe that 'id' actually is a of a class whose interface was not seen in
that compilation unit and which has a method with the same name but taking
(or returning) completely different types.

If you want to consider this option, it is always open, no matter if zero,
one or seven method prototypes with that name have been seen in that
compilation unit.  So whatever the compiler does, it might always be the
wrong thing.

I think the basic assumption is that the compiler assumes that in a
'correct' program the programmer has made sure that the compiler sees all
the relevant prototype definitions before the method call.  That if an
'id' is involved and messaged, a declaration of the class/protocol that
the 'id' belongs to has been seen in the compilation unit.

If you accept that this assumption holds for 'correct' programs, then when
the compiler finds a method invocation for a method aaa:bbb: and the
receiver is an 'id', it is correct for it to look in the method prototypes
it has read up to that point, in all classes and protocols and categories.  
If a single declaration is found, it uses it; if no declaration is found,
it emits a warning, and falls back to a default prototype.

If multiple declarations are found, the compiler can assume that the right
one is one of those (accepting the assumption above).  If the different
declarations would cause it to generate the same code, then no matter
which one is chosen, generated code will always be right - no matter which
of the different declarations which have been seen is actually implemented
by the id (it must be one of those, accepting the assumption above!), the
generated code is right.

If it finds multiple conflicting declarations, say 2 really conflicting
declarations, then - again assuming that the compiler has seen all the
relevant method prototypes before the method call - the 'id' must
implement the first one, or the second one: the compiler has a 50% of
getting it right if it picks up one randomly.  If the compiler fallbacks
to a default fallback prototype in this case, it has a different
probability of getting it right, which I feel would be less than 50%.  So
maybe the compiler should actually pick up one randomly.  The only other
option I see is aborting compilation - falling back to an abstract default
does not seem particularly useful to me.

You'll probably argue that finding different prototypes for the same
method and then an 'id' receiving that method call is an indication that
the program might not be correct, so the compiler could challenge its
assumption that it has seen all the relevant prototype definitions before
the method call.  While I agree there is a reasonable suspect that the
program is not correct (it's actually sort of evident that something is
not quite right), it's more likely to be that the types of one of the two
declarations have been mistyped (and the two declarations were meant to
have the same types) or that a completely unrelated declaration
(conflicting) from a different framework has been included, rather than
the fact that the real, correct declaration is missing.  So it still seems
to me that the best compiler choice is to pick one randomly, since it
still probably has around 50% probability of getting it right (which is
quite good), while using a fallback prototype is much more likely to get
it wrong. :-)

I suppose the really 'correct' way of doing things when two conflicting
(or even unconflicting but just different) declarations are found and used
by an 'id' is to abort compilation, having determined that the program is
'incorrect'.  That satisfies my "compiler feeling".  Anything which is
done to get to the end of compilation in this case is just the compiler
trying to patch errors in the code, and trying to get the error correction 
right, which is always a thing which is done in probability.

Anyway, yes discussing this shows that Objective-C is somewhat lossy and
unformalized, and has a very practical spirit.  I guess it would be nice
to have things standardized.

Thanks for looking into this.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]