Template function that returns default constructed value - c++

I have a function that returns default constructed value of template type:
template<typename T>
T do_stuff()
{
return T();
}
I use it like this:
int main(int argc, char** argv)
{
std::string str("hello");
int a = 10;
int *p = &a;
str = do_stuff<std::string>();
a = do_stuff<int>();
p = do_stuff<int*>();
return 0;
}
After I use it I have: str is an empty string, a eqauls 0 and p is a null pointer.
I can understand why std::string variable becomes an empty string (it has default constructor that constructs an empty string).
But why an int variable becomes 0 and a pointer becomes a null pointer.
Is it default template behaviour?
I use gcc 4.6.6 under Linux Centos.

From this reference on value initialization:
If T is a class type with at least one user-provided constructor of any kind, the default constructor is called.
If T is an non-union class type without any user-provided constructors, then the object is zero-initialized and then the implicitly-declared default constructor is called (unless it's trivial)
If T is an array type, each element of the array is value-initialized
Otherwise, the object is zero-initialized.
What is happening is that the last point in the above list.

The key is in
//------vv
return T();
For example, you can test the following, which is equivalent:
int x = int();
std::cout << x;
x will always be 0 in this case. The same is applied for the pointer - it's zero-initialized, "making" it NULL.
This is value initialization, "caused" by the parenthesis.

Because T() is value initialization, which for int and pointer types (and other basic types) is zero-initialization.
Just like to value initialize an int you'd do:
int x{};
int x = int();
//not initialized:
int x; //if not at namespace scope
int x(); //method declaration

This is as defined in c++ 11 standard, section 8.5:
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
And:
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is
ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.
And:
To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the object’s first named data member 89) is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.

That is correct behaviour for the respective types, everywhere.
Primitive types are initialized differently depending on whether you explicitly request the default value (value initialization) or don't mention the initialization (default initialization).
If you construct primitive type without mentioning initialization (this is called default initialization), the value is random:
int x;
struct Y {
int x;
} x;
int *x = new int;
are all default initializations and will contain random value.
But if you mention the initializer, it becomes value initialization and the value is initialized to appropriate "zero" (0 for numbers, 0/nullptr for pointers):
int x = 0;
int x = int();
struct Y {
int x;
Y() : x() {} // the x() is important
} y;
struct Z {
int x;
} z = {};
int *x = new int();
are all value initializations and C++11 adds the following forms
int x{};
struct Y {
int x;
Y() : x{} {}
} y;
struct Z {
int x;
} z{};
int *x = new int{};
Beware of
int x(); // function, NOT A VARIABLE
it declares a function taking no arguments and returning int. This is called the "most vexing parse".

The T() is value initialization.
Use:
int x{};
int x = int();

Related

Pointer initialization in class initialization

Given
class Foo {
public:
bool *b;
Foo();
};
Foo::Foo()
:b()
{
}
int main()
{
Foo foo;
}
What does the b() do in the class initializer list? It seems to maybe initialize the pointer's value to 0.
This is value initialization; as the effect, built-in types will be zero-initialized. That means b will be initialized to 0 (the null pointer).
4) otherwise, the object is zero-initialized.
and
If T is a scalar type, the object's initial value is the integral constant zero explicitly converted to T.
and also
Zero- and value-initialization also initialize pointers to their null values.

Do uninitialized objects exist in C++?

If all objects have at least one constructor be it default c'tor defined by the compiler or user defined then how can objects be uninitialized.
It is possible to declare objects on which no initializations are performed. These objects do exist, they have an indeterminate value, and using this value is undefined behavior (there is an exception to this rule for chars).
Such object can be created by default-intialization.
This is stated in the c++ standard, (§11.6 Initializers)[dlc.init]:
To default-initialize an object of type T means:
(7.1) — If T is a (possibly cv-qualified) class type (Clause 12), constructors are considered. The applicable
constructors are enumerated (16.3.1.3), and the best one for the initializer () is chosen through overload
resolution (16.3). The constructor thus selected is called, with an empty argument list, to initialize the
object.
(7.2) — If T is an array type, each element is default-initialized.
(7.3) — Otherwise, no initialization is performed.
Nevertheless, static objects are always zero-initialized. So any built-in with dynamic or automatic storage duration may not be initialized, even if it is a suboject;
int i; //zero-initialized
struct A{
int i;
};
struct B
{
B(){};
B(int i)
:i{i}{}
int i;
int j;
};
A a; //a.i is zero-initialized
int main()
{
int j; //not initialized
int k{}; //zero-initialized
A b; //b.i not initialized
int* p = new int; //*p not initialized
A* q = new A; //q->i not initialized
B ab; //ab.i and ab.j not initialized
B ab2{1}; //ab.j not initialized
int xx[10]; //xx's element not initialized.
int l = i; //OK l==0;
int m = j; //undefined behavior (because j is not initialized)
int n = b.i; //undefined behavior
int o = *p; //undefined behavior
int w = q->i; //undefined behavior
int ex = x[0] //undefined behavior
}
For member initialization [class.base.init] may help:
In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-
initializer-id (including the case where there is no mem-initializer-list because the constructor has no
ctor-initializer), then
— if the entity is a non-static data member that has a default member initializer (12.2) and either
(9.1.1) — the constructor’s class is a union (12.3), and no other variant member of that union is designated
by a mem-initializer-id or
(9.1.2) — the constructor’s class is not a union, and, if the entity is a member of an anonymous union, no
other member of that union is designated by a mem-initializer-id,
the entity is initialized from its default member initializer as specified in 11.6;
(9.2) — otherwise, if the entity is an anonymous union or a variant member (12.3.1), no initialization is
performed;
(9.3) — otherwise, the entity is default-initialized (11.6)
Members of a trivial anonymous union may also not be initialized.
Also one could ask if an object life-time could begin without any initialization, for exemple by using a reinterpret_cast. The answer is no: reinterpret_cast creating a trivially default-constructible object
The standard doesn't talk about existence of objects, however, there is a concept of lifetimes of objects.
Specifically, from [basic.life]†
The lifetime of an object of type T begins when:
storage with the proper alignment and size for type T is obtained, and
if the object has non-vacuous initialization, its initialization is complete
With non-vacuous initialization defined as
An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor.
We can conclude that for objects with vacuous initializations (such as ints), their lifetimes begins as soon as their storage is acquired, even if they are left uninitialized.
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
† Links are added for ease of reading, they don't appear in the standard
Use byte array:
alignas(alignof(Mat4)) uint8_t result[sizeof(Mat4)];
// ..
node->updateMatrix( ..., /*result*/ reinterprect_cast<Mat4*>(&result[0]));
The constructors of Mat4 will not trigger.

Why does "ctor() = default" change behavior when other constructors are present?

Why does
struct wrapper
{
explicit wrapper(void *);
wrapper() = default;
int v;
};
int main() { return wrapper().v; } // You should run this in Debug mode
return 0xCCCCCCCC, whereas
struct wrapper { wrapper() = default; int v; };
int main() { return wrapper().v; }
and
struct wrapper { int v; };
int main() { return wrapper().v; }
both return 0?
During value-initialization, if T is a class type without a user-provided or deleted default-constructor, then the object is zero-initialized (§8.5/8.2). This is indeed the case with wrapper.
Your first example matches the third case for zero-initialization (§8.5/6.1, emphasis mine)
— if T is a scalar type (3.9), the object is initialized to the value obtained by converting the integer literal
0 (zero) to T;
— if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class sub-object is zero-initialized and padding is initialized to zero bits;
— if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero-initialized and padding is initialized to zero bits;
— if T is an array type, each element is zero-initialized
— if T is a reference type, no initialization is performed
So in your first example, v should be zero-initialized. This looks like a bug.
In your second and third example you no longer have a user-provided constructor, but you do have a default-constructor that isn't user-provided or deleted so your example still falls into the third case for zero-initialization, which is to zero-initialize each non-static data member. VS is correct there.
This does appear to be a bug in MSVC. In all three cases wrapper has no user-provided default constructor, so initialization with wrapper() invokes:
(All citations from n3690)
(8.5/11) An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
(thanks to dyp), this will result in zero-intialization of int v
Initialization then refers us to the rule:
(8.5/8) if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked.
The zero initialization rules state:
(8.5/6) if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits
int v being a data member of wrapper is zero initialiazed itself according to:
(8.5/6) if T is a scalar type (3.9), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T
Which is not the behavior you observe.

Default value of a function pointer in C++

What is the default value of a function pointer in C++? (Apparently it can't be NULL, so what is it?)
How is this program supposed to behave and why?
struct S { void (*f)(); };
int main()
{
S s = S();
s.f(); // What is the value of s.f?
}
First any pointer can be null. It is the one universal truth about pointers. That said, yours will be null, but not necessarily for the reasons you may think;
C++11 § 8.5,p10
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
This is important because your declaration includes this :
S s = S();
By the definition of value initialization:
C++11 § 8.5,p7
To value-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
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.
if T is an array type, then each element is value-initialized;
otherwise, the object is zero-initialized.
Which brings us to what it means for your object-type to be zero-initialized:
C++11 § 8.5,p5
To zero-initialize an object or reference of type T means:
if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T (103)
if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero- initialized and padding is initialized to zero bits;
if T is an array type, each element is zero-initialized;
if T is a reference type, no initialization is performed.
103) As specified in 4.10, converting an integral constant expression whose value is 0 to a pointer type results in a null pointer value.
The latter is the reason you're pointer is null. It will not be guaranteed-so by the standard given the same code, but changing the declaration of s to this:
S s;
Given a declaration like the above, a different path is taken through the standard:
C++11 § 8.5,p11
If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2.
Which then begs the last question, what is default initialization:
C++11 § 8.5,p6
To default-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
if T is an array type, each element is default-initialized;
otherwise, no initialization is performed.
In your case the object s is zero-initialized which means the function pointer is NULL.
struct S { void (*f)(); };
int main()
{
S s = S();
if ( s.f == NULL)
std::cout << "s.f is NULL" << std::endl;
}
Output:
s.f is NULL
Online demo.
A function pointer can be NULL and you may assign NULL to it. Have a look here for instance:
#include <iostream>
using namespace std;
struct S { void (*f)(); };
int main()
{
S s = S();
s.f = NULL;
return 0;
}
I believe the way you call the constructor of the structure(with ()), f will be NULL.
Function pointer can be NULL, this way you can indicate that they don't point to anything!
In C++ (and C), pointers (regardless of type) do not have a default value per se; they take what ever happens to be in memory at the time. However, they do have a default initialised value of NULL.
Default Initialisation
When you don't explicitly define a constructor, C++ will call the default initialiser on each member variable, which will initialise pointers to 0. However, if you define a constructor, but do not set the value for a pointer, it does not have a default value. The behaviour is the same for integers, floats and doubles.
Aside
int main()
{
S s = S();
s.f(); // <-- This is calling `f`, not getting the pointer value.
}

How can i use member initialization list to initialize an array?

class A {
public:
A();
private:
char a[5];
int* ptr;
};
A::A() : a(0), ptr(0) { }
Is this right?
The only sensible thing you can do with a C-array in C++03 is value-initialize it (in C++11 and beyond it can be list-initialized).
From the C++03 standard, §8.5/7:
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
And from §8.5/5:
To value-initialize an object of type T means:
if T is a class type with a user-declared constructor, then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
if T is an array type, then each element is value-initialized;
otherwise, the object is zero-initialized
To zero-initialize an object of type T means:
if T is a scalar type, the object is set to the value of 0 (zero) converted to T;
if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
if T is a union type, the object’s first named data member) is zero-initialized;
if T is an array type, each element is zero-initialized;
if T is a reference type, no initialization is performed.
So, if your constructor definition is changed to
A::A() : a(), ptr() { }
then you are guaranteed that post-construction, all 5 elements of A::a will have the value '\0' and A::ptr will be null.
Afraid not; C++ doesn't support initialising arrays like this.
You'll just have to assign to its members in A's constructor body, or you can use value-initialisation if you don't really care what the values are:
struct A {
int x[5];
A() : x();
};
C++0x does let you give all the values, though:
struct A {
int x[5];
A() : x{1,2,3,4,5} {}
};
Note, though, that because arrays are not class-objects, you won't be able to do this:
struct A {
int x[5];
A(std::initializer_list<int[5]>& i) // or whatever the T should be
: x{i} // or x(i)
{}
}
A a({1,2,3,4,5)};