When a block omits its return type, it now becomes the task of the compiler to infer the type of the block based on the returns in its body. But unfortunately, CLANG is looking for completely decomposed forms of return types, which leads to strange inconsistencies.
The most accessible example is array sorting. The comparator block type is NSComparisonResult(^)(id obj, id obj2) , but if you decide to omit the return type NSComparisonResult, the compiler gets a cry:
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj, id obj2) { if (
This block breaks up into a block of type int(^)(id obj, id obj2) , which the compiler considers incompatible (perhaps the enumerations are called only ints, so this should compile).
In the same way, id splits into objc_object* , which splits and continues until it reaches void* , or "any common pointer" (according to the C language specification). void * and id are definitely not the same type. To get around this, you must promise the compiler that the return type is really what it is, and the only way to do this is to quit.
LLVM 5.0 corrects this by making the compiler's conclusions more intelligent.
CodaFi
source share