Compiler generated methods - c++

When declaring a class/struct/union the compiler will generate the default methods (rule of three). This also will happen when = default'ing these methods.
How do the default methods exactly look like?

For each of these methods, the compiler defines default inline methods that call the default methods of each attribute of the object. (so a pointer won't be initialized neither any built-in type).

For example let consider the default constructor. According to the C++ Standard
An implicitly-declared default constructor is an inline public member
of its class.
and
The implicitly-defined default constructor performs the set of
initializations of the class that would be performed by a user-written
default constructor for that class with no ctor-initializer (12.6.2)
and an empty compound-statement.
So it looks like
struct A
{
A() {}
};
except that it is not explicitly declared and defined.
About copy constructor you can read at my personal forum
http://cpp.forum24.ru/?1-1-0-00000021-000-0-0-1388485669
Though it is written in Russian but you can translate it for example using google service translate.

Those method will do the minimum necessary to initialize the class.
Default construtor - do nothing with simple members but call the constructors of more complex members (class/struct) as well as call the ctor of its super class.
Copy constructor will perform a shallow copy (memcpy).

Related

Unforgettable Factory: Doesn't work with default constructible objects

I am referring to this excellent blog post regarding the "Unforgettable Factory Registration Pattern": http://www.nirfriedman.com/2018/04/29/unforgettable-factory/
I've noticed that this stops working when the self-registering types are default constructible. In the example provided by the code, the self-registering types (Animal base class) defines a constructor with an int parameter. If I slightly modify the code to make Animal become default constructible, the data map in the factory remains empty and objects of type Cat and Dog can no longer be constructed through the factory.
As far as I understand the issue lies in the fact that the Animal class no longer calls the registerT function. However, I fail to understand why that is and what modification(s) are necessary to make it work with default constructible classes.
Can somebody shed some light on this?
Useful:
Modified example: http://coliru.stacked-crooked.com/a/55fe8edc094c88a8
Original example: http://coliru.stacked-crooked.com/a/11473a649e402831
The int argument is a red herring. When changing the argument list you modified
Dog(int x) : m_x(x) {}
to be
Dog() = default;
From a user-provided constructor, to a defaulted one.
In effect, this means the compiler (I checked Clang and GCC) doesn't emit a function definition for Dog::Dog(), so it doesn't odr-use Animal::Registrar<Dog>::Registrar<Dog>(), which means its definition isn't instantiated (member function bodies only are only instantiated when odr-used). And so we never odr-use its registered static data member.
If the constructor is defaulted, then we never actually end up registering the factory function into the map. And indeed, after it becomes user-provided again, things start to work.
I am however unable to understand why that makes a difference. The user-provided constructor is still an inline member function. And inline function definitions are tied to odr-usage too. But perhaps that should be the subject of another question.

C++ implicit definition of special functions

In the current version of the C++ draft (september 2019), paragraph [class.default.ctor]/4 states:
A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) to create an object of its class type ([intro.object]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration. [...]. Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members shall have been implicitly defined. [ Note: An implicitly-declared default constructor has an exception specification ([except.spec]). An explicitly-defaulted definition might have an implicit exception specification, see [dcl.fct.def]. — end note ]
[class.dtor]/11 specifies a similar restriction for default destructors.
What does the highlighted sentence mean? Is it a restriction on the program or on the implementation (compiler)?
The first sentence of the quoted paragraph states when a defaulted default constructor is implicitly defined (e.g. when it is odr-used). If the highlighted sentence is a restriction on the program, then the following example should be ill-formed, because at (1) the defaulted default constructor of B is odr-used, therefore it is implicitly defined. However, at this point, the defaulted default constructor of A has not been implicitly defined, therefore the restriction in the highlighted sentence is not respected. This is because I believe that the defaulted default constructor of A is odr-used only after the defaulted default constructor of B is defined. Is this assumption wrong?
struct A {};
struct B : A {};
int main()
{
B b; // (1)
}
Thank you.
I agree with the OP that the drafting is sloppy, but I believe that the intent is clear:
When the implementation implicitly defines B's default constructor, if A's default constructor hasn't been implicitly defined yet in this translation unit, then the compiler should generate the implicit definition of A's default constructor first.
In response to the OP's concern that this creates an additional point where an implicit definition might be generated (besides what is stated in the first sentence of the quoted paragraph), sure, that's one possible way to interpret it. Another way to interpret it is that the compiler starts defining A's default constructor while it's in the middle of defining B's default constructor (because B's default constructor calls A's default constructor "to create an object of its class type", thus requiring A's default constructor to be implicitly defined) and that the former must be completed before the latter. In other words, the first sentence of the quoted paragraph refers to when the generation of the implicit definition begins, and the bolded sentence refers to when it is completed. I think these two interpretations are equivalent, so it's not necessary to choose between them.

What does :className() mean in a constructor for className?

I see some code in a codebase I'm working on that looks like:
ZfooName::ZfooName(int magoo)
: ZfooName()
{
fGoo = magoo;
}
I'm assuming this is a C++11 feature, since it breaks in VS2012, but what does it mean?
This is a new feature in C++11. It's called a delegating constructor.
The constructor calls the default constructor first (the constructor that is being delegated to). After the default constructor returns, the body of the delegating constructor is executed.
See http://www.stroustrup.com/C++11FAQ.html#delegating-ctor and https://en.cppreference.com/w/cpp/language/initializer_list#Delegating_constructor for additional information.

Testing if class is copy constructable using libtooling

I would like to use libtooling to test whether the defined by a CXXRecordDecl is copy constructable.
I have already tried :
hasCopyConstructorWithConstParam()
hasTrivialCopyConstructor() || hasNonTrivialCopyConstructor()
Unfortunately, both of those expressions return true if the class's copy constructor is implicitly deleted. This can occur if the class inherits from a non-copyable class or has a member variable that is non-copyable.
The logic to test whether a class is copy constructable is non-trivial and must be exist somewhere in clang. How can I test if a class is copy constructable with libtooling?
Turn comment into answer:
You can retrieve the constructor with CXXRecordDecl::ctor_begin
and check CXXConstructorDecl::isDeleted().

Why does IntelliSense show a constructor I didn't write?

What does it mean by the suggestion give by the IDE? (using VS 2010)
There is no constructor of baseClass_2 which takes the suggested parameter(const baseClass_2 &). So, why this is showing up?
Implicitly defined copy constructor.
There are special member functions which get defined by default when you not explicitly declare / define them:
Default constructor
Copy constructor
Destructor
Note that the default constructor will not get defined when you provide any other constructor besides the copy constructor.
The constructor is the copy constructor and it is declared and defined implicitly.