Abstract class 'CLASSNAME' has a copy/move constructor that is not explicit.
For abstract classes, even copy/move constructors may be declared explicit,
as, by definition, abstract classes cannot be instantiated, and so objects of
such type should never be passed by value.
Could you please give an example of the problem which is solved by
adding "explicit" as suggested by noExplicitCopyMoveConstructor?
The message seems saying that the "explicit" avoids accidental pass by
value of an abstract class. But declaring a parameter with abstract class
is an error by itself, regardless the explicit-ness of its copy/move
constructor.
$ cat test.cpp
struct Abstract { virtual void f()=0;};
void x(Abstract a);
$ g++ test.cpp -fsyntax-only
test.cpp:2:17: error: cannot declare parameter 'a' to be of abstract type'Abstract'
void x(Abstract a);
^
test.cpp:1:8: note: because the following virtual functions are pure within 'Abstract':
struct Abstract { virtual void f()=0;};
^
test.cpp:1:32: note: virtual void Abstract::f()
struct Abstract { virtual void f()=0;};
^
If no user-defined copy constructors are provided for a class type
(struct, class, or union), the compiler will always declare a copy
constructor as a non-explicit inline public member of its class.
Then, if non-explicit copy/move constructor is really dangerous, I think
it is odd that the error is produced only for user declared case.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The answer is, that even constructors of abstract classes can be mistakenly used in conversion, but only in C++11 norm (or newer). Please see following code, which can be compiled in GCC with C++11 support:
Here is the problem that 5 can be casted to B type, which can be considered as dangerous. I can also pass 5 as argument to function myFunc, which can be considered as dangerous.
Best regards,
Jakub Melka
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The answer is, that even constructors of abstract classes can be
mistakenly used in conversion, but only in C++11 norm (or newer). ...
The given example shows just the danger of a non-explicit constructor.
It could be an answer for noExplicitConstructor. But it is not an answer
for my question about noExplicitCopyMoveConstructor.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The error noExplicitCopyMoveConstructor says:
https://github.com/danmar/cppcheck/blob/a5f577d179e09e436b544bcbbb6b798a47f6c8b6/lib/checkclass.cpp#L778
Could you please give an example of the problem which is solved by
adding "explicit" as suggested by noExplicitCopyMoveConstructor?
This message suggests fixes like this:
But I can't see any improvement by this change.
The message seems saying that the "explicit" avoids accidental pass by
value of an abstract class. But declaring a parameter with abstract class
is an error by itself, regardless the explicit-ness of its copy/move
constructor.
Moreover, non-explicit copy/move constructor is implicitly declared if
not declared by user.
http://en.cppreference.com/w/cpp/language/copy_constructor
Then, if non-explicit copy/move constructor is really dangerous, I think
it is odd that the error is produced only for user declared case.
Yes I agree, I can't personally see why explicit should be used. I'll forward this question..
I got answer:
Hello!
The answer is, that even constructors of abstract classes can be mistakenly used in conversion, but only in C++11 norm (or newer). Please see following code, which can be compiled in GCC with C++11 support:
Here is the problem that 5 can be casted to B type, which can be considered as dangerous. I can also pass 5 as argument to function myFunc, which can be considered as dangerous.
Best regards,
Jakub Melka
The given example shows just the danger of a non-explicit constructor.
It could be an answer for noExplicitConstructor. But it is not an answer
for my question about noExplicitCopyMoveConstructor.
So.. maybe we should only write this warning in C++11.
I will remove this noExplicitCopyMoveConstructor.
If somebody can see a good reason to have it we can readd it.
Thanks!