[cfe-dev] ObjC blocks documentation

David Chisnall via cfe-dev cfe-dev at lists.llvm.org
Tue Mar 8 10:08:39 PST 2016


This seems like an odd rationale.  For example, in C, clang happily accepts this:

struct {
  int arr[10];
} s;
int* (^bl)() = ^ int*() {return s.arr;};

This will generate similarly inefficient code.  Indeed, it’s semantically equivalent to Anastasia’s example, yet clang accepts it and is happy to perform the copy.

In C++, it’s even worse.  Clang will also accept structs with non-trivial copy constructors.  For example, consider this (which clang emits with no warnings):

#include <stdio.h>

struct F
{
	int x = 42;
	F() {}
	F(const F&o) {
		fprintf(stderr, "Copying!\n");
	}
};


int main() {
	struct v {
		F arr[1024];
	} s;
	int (^bl)() = ^ int() {return s.arr[10].x;};
	bl();
}


This program will print “Copying!\n” 1024 times to standard error (and this is only copying the array to the *stack* - if someone then calls _Block_copy() on bl then you will get another 1024 copy constructor invocations as the blocks runtime copies all of these to the heap).

This is a contrived example, but clang happily accepts blocks that perform implicit copying of objects whose copy constructors perform deep copies, which have overheads *vastly* more than any C array that you might plausible fit on the stack, all without warning.

David

> On 8 Mar 2016, at 17:53, fariborz jahanian via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> It was restricted due to performance implication of capturing the array. Earlier versions of ObjC blocks
> captured the array address with this syntax. This was a source of confusion and it was decided to outright ban it.
> 
> - Fariborz
> 
>> On Mar 8, 2016, at 2:30 AM, Anastasia Stulova via cfe-dev <cfe-dev at lists.llvm.org> wrote:
>> 
>> Hi,
>>  
>> It seems that capturing arrays is not allowed in Clang Blocks i.e. the following code:
>>  
>>   int arr[10];
>>  
>>   int* (^bl)() = ^ int*() {return arr;};
>>  
>> fails with:
>>  
>>   error: cannot refer to declaration with an array type inside block
>>  
>> I have checked the documentation on Blocks in Clang  and some ObjC manual but can’t find anything related to it.
>> Also the Clang commit history doesn’t provide much information.
>>  
>> Does anyone know why is this restricted? Or could anyone point to good documentation where such things are explained?
>>  
>> Thanks in advance,
>> Anastasia 
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list