Search code examples
c++visual-c++c++11copy-constructordeleted-functions

Finding where a deleted function is referenced


IDE - Visual Studio Express 2013 for Desktop

C++11

Problem - I have a class which is apparently being copied (using copy constructor). If I declare the copy constructor like this:

MyClass(const MyClass&) = delete;

It complains about a reference to a deleted function. I have gone over my entire code twice now and cannot find where an instance of the class would be copied.

Is there any way to find where the reference comes from?

I have tried defining the copy constructor, with a breakpoint in it, but it is never hit.

Update

Sorry it actually does show where the reference is - in some allocator in the STL. I managed to track it down to a std::vector::emplace_back() call - which must cause a copy. I will investigate this.

Update 2

I'm such a dumbass - I had a vector of MyClass...


Solution

  • Perhaps you have encountered the following compiler bug:

    http://connect.microsoft.com/VisualStudio/feedback/details/889420/issue-with-delete

    It says that the IDE (IntelliSense) complains while the compiler does not, which would explain why you have not posted any compiler error message and why you could actually execute a compiled program with breakpoints in the first place.

    The bug itself is easy to reproduce:

    struct Example
    {
      Example() {}
      Example(Example const &) = delete;
    };
    
    Example f()
    {
      return Example();
    }
    
    int main()
    {
      Example e = f();
    }
    

    Compiled with VC 2013 like this:

    cl /nologo /EHsc /W4 /Za stackoverflow.cpp
    

    No error, no warning.

    Now if you go to http://www.compileonline.com/compile_cpp11_online.php instead and compile the very same code with GCC 4.7.2, there are the expected compiler errors:

    main.cpp: In function ‘Example f()’:
    main.cpp:9:18: error: use of deleted function ‘Example::Example(const Example&)’
       return Example();
                      ^
    main.cpp:4:3: error: declared here
       Example(Example const &) = delete;
       ^
    main.cpp: In function ‘int main()’:
    main.cpp:14:17: error: use of deleted function ‘Example::Example(const Example&)’
       Example e = f();
                     ^
    main.cpp:4:3: error: declared here
       Example(Example const &) = delete;
       ^
    

    So, you actually have two problems:

    1. Your compiler has a bug. This can only be solved by upgrading to a newer version if/when one is available.

    2. Your code invokes the copy constructor for a class which does not allow copying.

    The second problem can be solved by considering the rules for when C++ copies an object "indirectly" -- or requires a copy constructor to be present even if the actual copying is optimised away. Inspect the code again looking for the following cases:

    • Pass by value. void f(MyClass obj);.
    • Return by value. MyClass f();.
    • Throwing. throw MyClass();

    The first one is easily fixed:

    void f(MyClass const &obj);

    The others require a more thorough redesign, because returning or throwing directly contradicts the idea of preventing copies.