1

With high risk of duplicate,

In C++, if you have custom destructor, you probably need to write own copy constructor and copy assignment operator.

In C++11 you also probably need to do move constructor and move assignment operator.

Why compiler auto-generates all these methods, if there is a custom destructor?

Note:

Question does not ask what are conditions of auto-generating all these methods.

Question is why is decided those methods to be auto-generated even d-tor is added.

I can post several examples of broken code because of generating those methods, such this one:

class FileDescriptorGuard{
    int fd;
    
public:
    FileDescriptorGuard(int const fd) : fd(fd){}
    
    ~FileDescriptorGuard(){
        ::close(fd);
    }
};

Here disaster will happen when object is copied or moved.

Community
  • 1
  • 1
Nick
  • 9,962
  • 4
  • 42
  • 80
  • 6
    That behavior has been deprecated since C++11. Hasn't been removed because it would break too much existing code. And the compiler *does not* implicitly declare move special members if you define a destructor. – Praetorian Apr 22 '16 at 17:22
  • 1
    I do not think my question is duplicate to the one NathanOliver specified. I know the conditions, but question is quite different – Nick Apr 22 '16 at 17:25
  • Then what is the question? The rules state when a special member function is declared. As you can see from the rules the creation of the copy constructor does not take into consideration a custom defined destructor. – NathanOliver Apr 22 '16 at 17:28
  • 1
    @Nick: If the only question you have is why the spec says so, then the question is based on opinion and therefore should be closed for that reason. – Nicol Bolas Apr 22 '16 at 17:29
  • So do you want us to reopen to close it as opinion based? – NathanOliver Apr 22 '16 at 17:36
  • @user2079303 - yes, this is the question. But I guess answer is simpler, even I do not know it. – Nick Apr 22 '16 at 17:36
  • 1
    @user2079303: There are plenty of people in this community with sufficient expertise and authority to answer such questions, or to refer to written material previously produced by such authorities. – Lightness Races in Orbit Apr 29 '16 at 15:40
  • @LightnessRacesinOrbit I had the initial reaction that this type of question would tend to generate speculative answers, but fair enough. You're right, I retract my comment. Indeed, on second thought I would like to see citations to written material concerning this question. – eerorika Apr 29 '16 at 15:49
  • @user2079303: It basically comes down to fortune: the C++ standardisation process requires strong motivations for any changes, and these motivations are formally documented. So they can be objectively cited. This isn't the case for all technologies, so I can see scenarios where you'd be absolutely right.... and where a language aspect wasn't actually introduced by a "change" that's sometimes true for C++ too. – Lightness Races in Orbit Apr 29 '16 at 15:54

1 Answers1

4

After I did some research with lots of help from Sergey Zubkov, it seems "Praetorian" give part of the answer.

In C++11, copy c-tors are generated for backwards compatibility.

Move c-tors are NOT generated, because this is feature introduced in C++11.

However, if you are using clang with -Wdeprecated, a warning is issued. Here is an example program:

class FileDescriptorGuard;

int main(){
    FileDescriptorGuard x(5);
    FileDescriptorGuard y = x;
}

Here is the compiler output:

$ clang -Wdeprecated -std=c++11  x.cc -lstdc++ 
x.cc:9:5: warning: definition of implicit copy constructor for 'FileDescriptorGuard' is deprecated because it has a user-declared
      destructor [-Wdeprecated]
    ~FileDescriptorGuard(){
    ^
x.cc:16:26: note: implicit copy constructor for 'FileDescriptorGuard' first required here
        FileDescriptorGuard y = x;
                                ^
1 warning generated.

If you are using gcc, there is no such warning.

Nick
  • 9,962
  • 4
  • 42
  • 80