Question

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)?

Was it helpful?

Solution

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:

@interface MyClass : NSObject
- (int) myReturnValueMustNotBeIgnored __attribute__((warn_unused_result));
@end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top