La clase C++ "no se puede compartir entre código ARC y no ARC..."

Compiling Objective-C++, I get the following diagnostic:

'MyClass' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible

Similar errors come up for missing copy-constructors and destructors. It's easy enough to add the necessary methods, but often they aren't meaningful, particularly for classes that I want to make non-copyable, and I don't mix ARC and non-ARC code (not intentionally, at least).

Why am I getting this message, and can I get rid of it without writing pointless member functions for all my C++ classes?

preguntado el 24 de agosto de 12 a las 09:08

2 Respuestas

It is because ARC discourages Objective-C objects in POD structures and C++ classes due to the fact that their inclusion makes managing their memory ambiguous. You can resolve it by prefixing Objective-C members with the __unsafe_unretained qualifier, which tells ARC to keep it's sticky fingers off the class, but puts you in the awkward position of having to manage the memory of the member object yourself. Also, objects with internal linkage are not covered under the warning, so wrapping your class or struct in an unqualified namespace { } works as well. If you absolutely must use ARC in the file (or files) that happen to have Objective-C Objects as class members, you must provide the proper access operators (as the warning says), otherwise just turn ARC off and save yourself the trouble.

respondido 28 nov., 14:21

not true. ARC disallows Objective-C objects in C structs. However, they are allowed in C++ structs and classes. - nuevoacct

@newacct The tests in apple's non pod file beg to differ. They refer explicitly to C++ structs and class and provide the necessary warnings that should appear - CodaFi

You said "ARC disallows Objective-C objects in structures and C++ classes" which is false. Non-POD structures and classes can definitely contain Objective-C objects with no warning. - nuevoacct

@newacct Yes, given certain constraints (which I have outlined). Am I missing one? All I can see that's wrong with this is that I haven't included one more constraint (non-POD classes) - CodaFi

or non-POD structures (in C++, structs and classes are the same except for the default access modifier). And ARC doesn't "disallow" use in POD structures; it gives a warning. It is okay as long as you don't use it in non-ARC code. - nuevoacct

The restriction is mentioned in in this section of the ARC specification:

However, nontrivally ownership-qualified types are considered non-POD: in C++11 terms, they are not trivially default constructible, copy constructible, move constructible, copy assignable, move assignable, or destructible. It is a violation of C++’s One Definition Rule to use a class outside of ARC that, under ARC, would have a nontrivially ownership-qualified member.

The reason for it is this: In ARC, when you use an Objective-C object as a field of a C++ struct or class, ARC implicitly adds code to the default constructor, copy constructor, destructor, etc. to manage the memory for the fields. And if the struct or class doesn't have these constructors/destructors, ARC automatically adds them.

This means that if such a struct or class was considered "POD" (a C++ term meaning it has no special constructors/destructors) originally, ARC makes it non-POD by implicitly adding these special constructors/destructors. However, C++ treats POD and non-POD types differently in some places. If such an originally POD struct or class declaration was seen from both non-ARC and ARC code, then the non-ARC code might think that it is still a POD type. But this is wrong (ARC added methods to make it non-POD), and will allow the non-ARC code to do wrong things and bypass the memory management. As a result, it must be disallowed.

contestado el 22 de mayo de 13 a las 23:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.