Take C++ constructors for example, we know they don't return values. Why did Bjarne Stroustrup in the beginning decide not to allow constructor returning 'false' to indicate it fails, so that the run time system can destruct its constructed members just like throwing an exception? What are the concerns that make OO language designers decide not to do so? The new operator can therefore return nullptr if it see constructor returns false. For static objects (in .data/.bss area or on .stack) the compiler generated construction code can still detect and signal, abort or exit accordingly.Consider the following two coding paradigms, using dynamic allocation as an example:objp = new object; // constructor returns 'false', 'new' returns 'nullptr'.if (objp != nullptr) {    do_something(objp);} else {    error_handling();}compare to:try {    objp = new object; // object throw exception when construction failed    do_something(objp);} catch (const typedException &e) {    error_handling();}If we need to encode the reason of construction failure, the latter using exception is of course more helpful as we can't use 'objp' to pass any information once construction failed. But if the reason is simple (say 'out of memory'), or when skipping error handling does no harm (do_something() might just do decorating), do we really need to involve exception handling in such simple cases? How about allowing both paradigms exist in C++?(Another example is, for small embedded C++ compilers if they don't support exceptions, they can still support construction fail handling in this way.)Well, maybe my comparison is misleading, I am not against structural exception handling, on the contrary, I LOVE exceptions especially for big systems. But when it comes to small embedded systems where both code and data space are scarce, I think twice.The exception handling frames are things similar to setjmp() and longjmp() which are quite expensive in both execution time and memory use; while the (objp==nullptr) comparison takes only a comparison and a jump. Not to mention some of the compilers don't even support exception handling. In those cases, construction fail can only be dealt with other methods. That reminds me in the old days Turbo Pascal 5.5 OOP can call Fail on construction fail, and the newly allocated object will be null. What about other languages? Does all OOP languages use exception on construction fail cases?Actually, at the time I learnt C++ there is no exception handling available at all (Turbo C++ 3.0/Borland C++ 3.1). Before that I learnt Turbo Pascal 5.5 which supported Fail on dynamic construction fail. But when I move to C++ at that time this make me a bit upset since there is no way to test construction fail without defining an Init() function that actually do the inits. Since then I wondered, why can't constructors return values? Now I think maybe returning a value from constructor will make the language inconsistent. If we return a value from a constructor and the runtime system test it, this kind of behavior is a lot different from a normal function call since our code can test it. Maybe this kind of inconsistency is not a good idea when designing a programming language? What do you think?In the early days of C++ there was no exception handling, yet Bjarne Stroustrup still didn't let constructors to return error conditions. Same did the other OO languages at that time (correct me if I am wrong). Therefore, using exception handling was not their original intention to take care of constructor fails. Then why? I think I found the answer, please refer to my own answer here. Thanks.
Why don't constructor return bool to indicate its success or failure without having to throw an exception?
java;object oriented;c++;objective c
I think I found the answer for my own question.So far the public voted answer from @Erik was biased toward another direction debating the value of exception handling which I never doubted about. That doesn't answer this question which is about the philosophical reasoning why designers of OOP languages don't let constructor return error conditions in the first place?In the beginning, there was no exception handlingIn the early days of C++ compilers there was no SEH support. The problem of construction fail was not taken cared of at that time, except for Turbo Pascal 5.5 which at least provide a basic Fail procedure call to notify the system that object construction failed. The TP5.5 run time system then gracefully reverse the construction sequence, destructing any newly constructed objects within that scope. There was no similar design in C++ at that time. However, there are other ways to handle construction fail, @Robert Harvey, @Daniel Earwicker and others posted feasible solutions to deal with it without using exceptions.Nowadays we can say the exception handling approach is so far the best, but it's a result of C++ language evolution over the years. Thus this current causal result cannot be used to infer the past reason: why, in the beginning, don't they allow constructors to return error codes for the construction code to check? Is there any philosophical considerations? AnswerSo far looks like the conceptual inconsistency between function return value and constructor return value, that I mentioned in the end of my question, and the consequential language changes, to be the answer. ReasoningIf we allow constructors to return error codes only for object construction code (e.g. the new operator in C++, or any construction code that calls constructor) to read, it will easily be confused with function return values which is for our code to read. Especially when objects are constructed statically not using 'new' operator. @Jerry Coffin's answer enlighten me the consequence of this kind of confusion, his answer treated constructor return value as function return value.Let's prove it by contradiction, see what will happen to the C++ language by assuming constructor do return error condition.First, let's allow constructor to return bool to indicate its success or failure:MyInteger a=5; // so does 'MyInteger b{2}' or 'MyInteger c(3)'If things go well, MyInteger constructor will return 'true' which is integer '1' to let the construction code know it works. This is not to say we are letting 'a' to be '1', 'a' is still '5'. We return 'true' just to let the construction code know that the constructor MyInteger(int v) did not fail. From assembly's point of view, the compiler generated initialization code for 'a' will call the constructor MyInteger(5), and test its return value (bool true, i.e. '1'). This value '1' has nothing to do with the actual value '5' assigned to 'a'. It's obvious in assembly, but from high level language's point of view it's confusing, especially for beginners. It's not like normal function return values. This conceptual inconsistency also means it's error-prone. Next, let's make it more complicated by allowing error codes to be returned by a constructor. Imagine a pseudo constructor for MyInteger:int MyInteger::MyInteger(int v) {   if (memory allocation fail)      return 1;   else if (failure_reason_one)      return 2;   ...   else // everything works      return 0;}Consider a simple declaration:MyInteger a = 1;Once 'a' is successfully assigned to '1', this means 'a' is successfully constructed and the constructor call MyInteger(1) returns '0'. But if we're running out of memory when constructing 'a', the constructor call MyInteger(1) will return '1' instead; wouldn't programmers tend to do so:if (a == 1)    error( Out of memory );else {   ...}Wrong! Constructor return value is for the construction code only! In assembly we can see it calls the constructor MyInteger() and test its return value, but this is invisible to our program so we can't use that value this way. The language might therefore in turn be forced to support C-like error code, a per-thread static class member variable, like the following:if (a.errcode == 1) // errcode is a static class member variable    error( Out of memory );else { // Now we really have 'a' successfully assigned to 1    assert( a == 1 );}This kind of conceptual inconsistency of return seems not a good design for a programming language. We might again in turn need to add a new keyword like failreturn or errorcode for constructor returns or other, but, this still lead to some degrees of confusion. The language itself will have to be changed a lot due to constructor return value, which is not worth it.Conclusion, using exception handling mechanism can prevent all possible confusions of this kind. Even for languages without exception handling, returning error conditions from constructor is not a good idea.