[cfe-dev] ObjC blocks documentation

Anastasia Stulova via cfe-dev cfe-dev at lists.llvm.org
Thu Mar 10 06:01:57 PST 2016


Thanks for looking into it! 

As  far as I understand there is no real documentation where this is explained. So we should just rely on what Clang accepts and produces.

Anastasia

-----Original Message-----
From: fariborz jahanian [mailto:fjahanian2016 at gmail.com] 
Sent: 08 March 2016 21:00
To: David Chisnall
Cc: Anastasia Stulova; nd; 'cfe-dev at lists.llvm.org' (cfe-dev at lists.llvm.org)
Subject: Re: [cfe-dev] ObjC blocks documentation


> On Mar 8, 2016, at 10:08 AM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:
> 
> This seems like an odd rationale.  For example, in C, clang happily accepts this:
IIRC, initial implementation of a stand-alone array was by capturing its address.
This was deemed confusing, and misuse of this syntax. Decision was made to disallow that syntax altogether so people can rewrite their code with array embedded in a stuct/class (which was by then supported). In which case, they are assumed to knowingly live with the performance hit. This omission can be revisited.

- Fariborz

> 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