4 ms·
I don't think that helps? If, as is kind of the point of RAII, your constructors do some initialization and that initialization may fail, then: If you have a
by xen0 3y ago
I don't think that helps?
If, as is kind of the point of RAII, your constructors do some initialization and that initialization may fail, then:
If you have a single object that may fail to construct then maintaining it in scope for the catch block doesn't make sense; it's not initialized.
If you have several, then you still can't maintain them in scope, because you don't know which ones are actually valid.
Yes there are other patterns that wouldn't have this issue (acquiring resources outside of the constructor), but then you can just declare your objects outside of the try-catch block.
- specialist 3y agoI misspoke. Ignoring the syntax for a moment, I want scoping to behave like this pseudo-code. So that the catch and finally blocks are lexically nested within the parent try block. try { OutputStream out = ... ... // Must be at end of try block catch ExceptionA, Exception B { ... } catch Exception C { ... } finally { ... } } // end of try Maybe even allow catch and finally to allow single expression in addition to blocks. Just like with if/then/else.
- nemetroid 3y agoIf constructing "out" fails but one of the catch-blocks tries to use "out", what should happen?
- grumbel 3y agoPython is an example of a language that works like this. When the constructor throws, 'out' remains not defined, but you can just do 'out = ...' in the catch block and define one with a fallback value. So all the code after the error handing would just see a working 'out' variable. This works due to all variables being bound to the function scope, not to the code block, in Python.
- nemetroid 3y agoIn Python, sure, but I struggle to see a way to make it make sense in C++.
- xen0 3y agoPython can do that because: * it's not an error to have an unbound name in scope; just referencing it at runtime is an error. * there is a reasonable default; anything can be set to None This doesn't hold in C++. If your class throws during its initialization, you can't really do much (even default initialization of members may not work). Reassignment may not be possible if it was declared const. And there's still the issue of 'which objects successfully initialized'?
- xen0 3y agoRight, but if constructing OutputStream throws ExceptionA, you shouldn't have it in scope; it's not something you can use.
- specialist 3y agoAgreed. I'll make that more clear next time. I omitted catch's parens, which makes it less clear. I just want 'out' visible to both catch and finally.