I\'ve Googled this and read many posts, but there are so many different answers that all make logical sense that I was wondering if an expert on the topic could demystify th
Constructors aren't called like other functions, so they don't return like other functions. They execute as a side-effect of certain constructs (cast, new
, variable definition, ctor-initializer-list, pass-by-value, return-by-value).
Constructors are perhaps a bad name for it. It is practically an initializer for pre-constructed objects. Easiest way to illustrate this is a pseudo-example for the equivalent construct without using the C++ constructors.
With constructors
struct X {
int a;
X() {
a = -5;
}
};
int main() {
X* x1 = new X(); // X created as a "reference object".
X x2; // X created as a "value object" on the stack.
return x1->a - x2.a;
}
Without constructors
struct X {
int a;
void initialize() {
a = -5;
}
static X* create() {
X* res = (X*)malloc(sizeof(X));
res->initialize();
return res;
}
};
int main() {
X* x1 = X::create(); // New constructed heap-allocated X
X x2; // Stack-allocated X
x2.initialize(); // Manually initialized
return x1->a - x2.a;
}
Now, if you imagine that X::initialize
in the second example were to be made to return, say a bool
indicating success or failure, you would have a problem. In main()
, the inattentive programmer might end up with an X
that isn't properly initialized, leading to undefined behavior (usually a hard-to debug crash that might not be discovered before production).
This is one of the core reasons why constructors are made special. The only two ways to exit a constructor, is through normal completion, or through an exception, which must then be handled by the caller (or passed on up the stack). In any case, you prevent ending up with uninitialized objects.
As a side-note, uninitialized objects are one of the more common causes of bugs in C, which does not have anything to help the programmer like this.
That constructors lack a return type -- not even void
-- means that you can't call a constructor from your C++ code. And that's the point. Calling a constructor doesn't make sense. Making it illegal to call a constructor eliminates the very possibility of this type of user error.
Edit
barnes is right in that the ultimate reason you can't call constructors is that they have no name. (And even this ignores that you can call a constructor indirectly via placement new.)
Trying again:
You can't call constructors from your C++ code because constructors don't have a name. Making constructors not have a return type emphasizes to the programmer that constructors are a very different kind of function than other functions. What a constructor actually does return, if it returns anything, is up to the vendor.
but I believe that all functions have to return something, no?
No. What does it mean to return a value from a function? Well, the ABI for an implementation will specify that for some return type a function will set certain registers, or some memory at some offset from the stack pointer, to the value that is 'returned' by the function.
Obviously registers and memory exist and contain data after a constructor or void function is called, but the language says those functions don't return anything, and so the ABI doesn't specify which registers or memory to look in to find a return value. The code can't set a return value and calling code can get any return value.
So no, functions don't have to return anything.
Constructors implicitly return an instance of the class itself. It will be contradicting if it were designed to return something and the programmer returned something completely different other than the class itself. Basically the syntax would be confusing.
The constructor constructs in-place, it has no need to return anything.
I believe that all functions have to return something
void
?