I just spent some time finding out why a mutable set didn't correctly intersect itself with another set, using
[someMutableSet intersectsSet:anotherSet]; // not the best idea
Of course, the correct syntax is [someMutableSet intersectSet:anotherSet]
and the above line means something different – it's an method call with return value of BOOL
type.
Since I have -Wall -Wextra
options enabled this should have been caught as a warning. But it wasn't caught. I investigated further by trying, where types
is an NSMutableSet
:
(void)[types intersectsSet:types]; // -> no warning, this is expected
(BOOL)[types intersectsSet:types]; // (1) -> warning, this is expected
And, again, if I do this:
[types intersectsSet:types]; // (2) -> no warning, UNEXPECTED
there is no warning, even thought the method is defined as - (BOOL)intersectsSet:(NSSet *)otherSet;
so one would expect (1) and (2) to be equivalent. Mayhaps the vile compiling tool considers (1) to be of a more dangerous nature compared to (2), but why does that affect warnings, I ask?
So, how to make compiler produce the same warning in (2) as in (1)?
This behavior in the compiler seems intentional (and reasonable.)
If the
-Wunused-value
warning were emitted for all ObjC message send expressions where the method has a return value that is implicitly discarded (i.e. there is no void cast,) it would be so “chatty” that it would render itself useless. In other words, people would get such large numbers of warnings for existing projects that they would simply turn the warning off, rather than annotate all such cases with(void)
casts.The fact that the warning is emitted in the case where the return value is cast to
BOOL
is a nice surprise, and makes sense: it's reasonable for the compiler to then assume that the programmer is indeed interested in the return value (because why otherwise include the cast?)The Clang development community on the cfe-dev mailing list might be able to give you more information on the thinking behind this.
I don't know of any way to force the behavior you want in general, but for the interfaces in your own code you can force this warning by using the
warn_unused_result
attribute in the ObjC method (or C function) declaration: