QScopedPointer, boost :: scoped_ptr - why complain about incomplete types?

I have a c-Structure that I want to embed in a cpp class without poisoning my global namespace, so I don't want to include a c-header.

This is why I want to use a smart scope pointer ( QScopedPointer or boost::scoped_ptr ) with the declared structure name forward.

What I don't understand is the implementation of both of these pointers that are not compiled:

pushing:

error C2027: using undefined type 'xxx'

 template<class T> inline void checked_delete(T * x) { // intentionally complex - simplification causes regressions typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; // < here (void) sizeof(type_must_be_complete); delete x; } 

and the same in Qt:

error C2027: using undefined type 'xxx'

 template <typename T> struct QScopedPointerDeleter { static inline void cleanup(T *pointer) { // Enforce a complete type. // If you get a compile error here, read the section on forward declared // classes in the QScopedPointer documentation. typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; // < here (void) sizeof(IsIncompleteType); delete pointer; } }; 

The specified documentation did not help me. he says that the destructor of the forward declared class does not have to be inline and should be available at every possible instance of clearing the scope pointer. But my c-structure has no destructor.

I have 2 questions:

  • Why is this check at all? Because it does not seem to know the size for the delete call.
  • How to deal with this?
+5
source share
3 answers
  • The type of object that is stored in the smart pointer must be known at the place where the smart pointer is destroyed, so you can name the proper destructor of the stored object
  • Does your class (the one that contains the smart pointer) have a destructor? If not, add it to the cpp file. Otherwise, the compiler tries to add it when it sees the class definition, and cannot do it, because the smart pointer destructor is trying to access an unknown type.
+9
source

my c-Structure does not have a destructor.

Firstly, no . Your structure actually has a destructor - an implicitly declared destructor .


In any case, release it.

 delete pointer; 

When compiling this code, we must call the *pointer destructor. However, if *pointer is an incomplete type, we cannot know the destructor to call. In this case, the standard [expr.delete] says that it invokes undefined behavior.

If the deleted object has an incomplete class type at the delete point, and the full class has a nontrivial destructor or release function, the behavior is undefined.

As you can see, if your structure does not have a non-trivial destructor or a class-specific operator delete function, this is not UB. However, you can probably add a destructor to your structure - you will . If you do this without correcting this moment, it will truly be a mistake. (The compiler should not report this, it's just UB, not an illegal code.) Therefore, it is not considered good practice.

Because of this, removing incomplete types is something we should avoid. To avoid this, we use this trick.

 typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; // < here (void) sizeof(type_must_be_complete); 

Since sizeof(T) is illegal code if T is an incomplete type, so it can reduce compilation time before your program gets crazy due to UB.

I highly recommend you just turn it on, despite the slower smoothing speed; Although your structure is trivial and does not have an operator delete , you can add them without committing, which causes UB.

+6
source

Perhaps this link will help you understand this: http://www.bnikolic.co.uk/blog/cpp-checked-delete.html

scoped_ptr requires a fully defined type, used as a template parameter, because of the boost / checked_delete.hpp header.

Personally, I prefer std :: unique_ptr for this kind of thing (for example, hiding the implementation when the Init () method used for some constructs is private), but boost does not have unique pointers.

Sometimes you can use boost :: shared_ptr if it's convenient, depending on what you need, as it does not express these errors.

0
source

Source: https://habr.com/ru/post/1202413/


All Articles