In the duplicate there is no answer to the points 1 and 4 of my question at least. And they are the most important. I can delete the other points but I ask not to close the whole question.
1. In code below obj1 is created normally. But if I try to uncomment obj2's and obj3's creations the compilation (-std=c++11, g++ 4.9.2) will fail. Why is it so? I thought that initialization should be performed identically regardless of whether an objct's memory was allocated on stack or on heap.
struct C
{
int c;
C() = delete;
};
int main()
{
C obj1 { };
C *obj2 = (C *) malloc(sizeof(C));
//new ((void *) obj2) C{ };
//C* obj3 = new C{ };
return 0;
}
2. I tried to figure out which of the two kinds of behaviour (obj1-case or obj2,obj3-cases) is correct according to standard. In standard it's said (#3242 and #3337, 8.5.4):
List-initialization of an object or reference of type T is defined as follows:
— If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
Okay. So I go to value-initialization definition (#3242 and #3337, 8.5.0):
if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
According to (#3242, 12.1)
A default constructor is trivial if it is neither user-provided nor deleted and if: . . .
and so deleted default constructor is non-trivial and, thus, the code C obj1 { }; should fail to compile.
But according to (#3337, 12.1)
A default constructor is trivial if it is not user-provided and if: . . .
and so deleted default constructor is trivial the code C obj1 { }; should succeed to compile.
Where is the truth?
3. But there is more. In the next version of standard it's said (#3367, 8.5.4):
List-initialization of an object or reference of type T is defined as follows:
— If T is an aggregate, aggregate initialization is performed
— Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
As I understand C is an aggregate. But here I have a problem: I failed to find info how an aggregate with a deleted defult constructor is created. There is no such info in 8.5.1 Aggregates. But according to this
When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause . . . (#3367, 8.5.1)
I can suppose that constructors [compiler-generated in aggregates' case] are just ignored during aggregate-initialization. So I can suppose that the deleted default constructor is also simply ignored and so C obj { }; should be compiled successfully though for me it's weird to create an object with deleted default constructor. Still if I understand right, according to this version of standard obj1-case is okay and it's wrong that obj2,obj3-cases fail to compile. Am I right?
4. And the logical question is, anyway, which standard version #3242/#3337 or #3367 should I rely on? Version #3367 was made in 2012, so later than 2011, and I don't know if it can be called c++11. Which version is considered real c++11-standard? I compiled the code example above using g++ 4.9.2. What standard variant does the compiler use, how can I know? Because versions #3337 or #3367 differ much.
For example, in #3367 the definition of value-initialization was changed dramatically:
To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a default constructor that is user-provided or deleted, then the object is default-initialized;
5. And the new value-initialization definition is strange, in my opinion, as I can't think up any case when we could create and value-initialize an object with deleted default constructor. I mean, for example, if I make int c member of C-class private and, thus, C-class stops being an aggregate the expression
C obj1 { };
will be value-initialization (not aggregate-initialization as it was before) [#3367, 8.5.4 "List-initialization"] and will definitely fail to compile. Could you explain the moment about deleted constructors in the new value-initialization definition?
I understand that there is much text here. If you answered some I would be so so so grateful.