It looks like part of the discussion accidentally went into a private conversation. So, here we are back. 2017-05-25 22:39 GMT+02:00 Vicente J. Botet Escriba < vicente.botet@wanadoo.fr>:
Le 25/05/2017 à 18:40, Andrzej Krzemienski a écrit :
2017-05-25 17:32 GMT+02:00 Vicente J. Botet Escriba < vicente.botet@wanadoo.fr>:
Le 25/05/2017 à 13:18, Andrzej Krzemienski via Boost a écrit :
2017-05-25 9:44 GMT+02:00 Vicente J. Botet Escriba via Boost < boost@lists.boost.org>:
We have now the possibility for uninitialized variables, but static analysis tools will help here.
So, more specifically, I understand that you propose the following:
- Default constructor works: no T or no E is construced (similar what outcome<> does)
I was not aware of this. Do you know that from this reference documentation?
constexpr outcome () noexcept(is_nothrow_default_constructible) Default constructor.
Well, I just assumed that since outcome<> has this empty state, it is exactly for the purpose of giving semantics to the default constructor. But now that you have asked, I looked at the docs. They say nothing about what happens in the default constructor. I tried to look in the code, but was confused with these policies. So, I just run a small test program, and yes: default constructor creates an empty state.
Niall, please could you add an issue in order to document default constructors (if it doesn't already exists).
This is already logged in https://github.com/ned14/boost.outcome/issues/26
Sorrty, I couldn't interpret it as you. But, if it is the case, yes, as outcome does.
- You can assing to and and destroy such an objetc (similar what outcome<> does)
I don't catch what you mean here. Are you referring to the conversion between expected with convertible value type and error types?
No, I am saying that the following should work: outcome<T> o; // default-constructed o = some_outcome<T>(); // this should be safe to execute
This works already with expected even if it doesn't defaults to empty.
Ok, and you expect it to continue to work.
- You will probably need to add an observer function that checks for
this singular state, like `is_singular()`. If not for anything else it would be used for assisting the static analysis tools. (again, similar what outcome<> does)
No. There will be no such observer. This is essential. There is no visible empty state. Or do you consider that chrono::duration should tell you if it was initialized or not? The user know if it is initialized or not, but there is no tool to check it. This could be against safe programming, but we are here in C++ and we should provide first the raw tools and then build on top of them when we want more.
- other observer functions (has_value(), value(), has_error(), error()) cause UB when `is_singular() == true. (this is the only difference from outcome<>)
Not the only one. outcome fixes its error types. I'm proposing an extension to the current expected so that it can take care of the Outcome use cases and needs.
Did I understand your intentions correctly?
Not completly. I don't want an observer that tells me, attention you have not initialized your variable, or you have moved from. This is essential.
Very daring. It would be easier to accept if you could show a tool that is capable of statically analying this kind of "used unintialized" bug for `expected`.
Static analysis to check if uninitialized variables are used (read) works very well already . I don't remember if it si with clang-tidy that I have seen this kind of warnings.
Ok. Now I am thinking, another thing you can do, is to internally store
something like varient