# Whether you believe the library should be accepted into Boost
No. Not until some of the major issues are addressed.
# Your name
David Sankel
# Your knowledge of the problem domain
I've had to wrap C APIs on multiple occasions.
# What is your evaluation of the library's:
## Design
The design of the `out_ptr` type is reasonable as a shorthand for calling
certain C APIs.
In my experience a use case for `in_out_ptr` has never come up. Given the
subtleties of its correct (and likely rare) usage, I'd be in favor of
leaving this out of the library altogether. Especially given that the
semantics of when 'release()' is called are not specified.
I agree with the other comments that the customization point is not
minimally complete. Ideally a customization point would not require one to
replicate all the functionality of the class I'm customizing and, instead,
only require a few general purpose functions that that interface can make
use of.
## Implementation
There are two implementations of `out_ptr`. The one called "clever" invokes
undefined behavior as a means to squeeze out some extra performance. I do
not think the performance overhead of using this library with the "non
clever" implementation justifies the potential portability and and other
risks associated with depending on undefined behavior working a particular
way.
It looks like "clever" mode was #ifdef'ed out, but removing it as cruft
would improve maintainability of the implementation and remove the
complexity of having an additional `core_out_ptr_t` class.
The provided implementation works for smart pointers that follow
conventions like the standard, but has some additional logic if the types
happen to be `std::shared_ptr` or `boost::shared_ptr`. This hard coded
special casing won't work with, say, a company specific shared pointer
implementation. This relates to my earlier comment that the customization
point should be simplified.
## Documentation
The recommendation in the "caveats and caution" to not use out_ptr outside
if/else conditionals goes a bit far in my opinion. It is common practice to
make function calls that emit failure with return codes in conditionals, as
in:
```
if (SQLITE_OK !=
sqlite3_open("test.db",
boost::out_ptr::out_ptr(database, sqlite3_close))) {
std::cout << "Problem opening the file";
}
```
For these cases it is safe to use `out_ptr` so I'd suggest rewording the
recommendation to allow calls like this.
"Almost all well-designed C APIs will set the user-provided output pointer
argument to NULL/nullptr upon invalid parameters". This is a very difficult
claim to make (what's the sample size?). I'd suggest changing "Almost all"
to "Many". I don't understand what the issue is here with APIs not setting
the out parameter on failure (which IMO is good practice especially as it
relates to strong exception safety guarantees). These APIs have return
codes that need to be inspected anyway.
The reference documentation reads like a specification rather than what I
would typically consider reference documentation. I'd expect to see it
written with an intended audience of a casual user with examples and an
organization that would be helpful for this reader (e.g.: purpose,
description, examples, details)
## Tests
The tests look reasonable and comprehensive although there seems to be some
`#if 0` conditions that could either be cruft or perhaps the intent is the
developer would manually change those to verify compilation failure.
The tests are using the 'catch' library which is intended to be a
submodule. Is there a precedence for using a third party library like this?
For folks using Boost it could be painful to get another dependency
approved to run all the Boost tests. It would be preferable IMO to use
Boost.Test or something self contained.
## Usefulness
I attempted to use the library with g++ 8.3.0 and clang 8.0.0. My example
code is below:
```C++
#include
On Thu, Jun 27, 2019 at 9:07 AM David Sankel via Boost < boost@lists.boost.org> wrote: [snip]
## Tests
[snip]
The tests are using the 'catch' library which is intended to be a submodule. Is there a precedence for using a third party library like this? For folks using Boost it could be painful to get another dependency approved to run all the Boost tests. It would be preferable IMO to use Boost.Test or something self contained.
This part is on me. I told JeanHeyd that he must convert the tests to use Boost.Test, but also told him he should wait until and if out_ptr is accepted to Boost before doing so. Zach
czw., 27 cze 2019 o 17:56 Zach Laine via Boost
On Thu, Jun 27, 2019 at 9:07 AM David Sankel via Boost < boost@lists.boost.org> wrote: [snip]
## Tests
[snip]
The tests are using the 'catch' library which is intended to be a submodule. Is there a precedence for using a third party library like this? For folks using Boost it could be painful to get another dependency approved to run all the Boost tests. It would be preferable IMO to use Boost.Test or something self contained.
This part is on me. I told JeanHeyd that he must convert the tests to use Boost.Test, but also told him he should wait until and if out_ptr is accepted to Boost before doing so.
Or lightweight_test: https://www.boost.org/doc/libs/1_70_0/libs/core/doc/html/core/lightweight_te... Regards, &rzej;
Dear David Sankel, Thank you for the review. I fixed up the documentation in the places you requested. (It's on the post-review branch.) I did not use Boost.Test for the reason Zach pointed out: testing infrastructure (and CI, and etc.) was to be ported upon a successful review. The current set up is for ease of use and benchmarking / test deployment outside of the typical boost infrastructure (to allow contributions and reviews to be done easier): it will be replaced with the Boost-based infrastructure later. I turned off the cleverness in both out_ptr and inout_ptr by default. It now takes defines to turn on the aliasing optimization (documented in the post-review branch, here: https://github.com/ThePhD/out_ptr/blob/feature/boost.review/docs/out_ptr/con...). This answers both your and many other's concerns about the aliasing, as well as some of Peter Dimov's specific concerns about how the aliasing is done. I do not believe inout_ptr to be an abstraction so bereft of value: it has already seen successful use and is an important wrapper for many delete-and-allocate/reallocating C APIs, and one of my first users used it for their code. I do not have a design for a new customization point: this is the one I settled on after extensive research into various different areas. I do not think I should change it: but the need for simplicity is important. I could offer a facade to make it easier to implement the boilerplate and avoid concerning a user with storage directly, but struct specialization is still the most flexible and can cover more use cases effectively. Sincerely, JeanHeyd Meneide
Am 27.06.19 um 16:06 schrieb David Sankel via Boost:
It looks like "clever" mode was #ifdef'ed out, but removing it as cruft would improve maintainability of the implementation and remove the complexity of having an additional `core_out_ptr_t` class. Very much in favor of this especially after discussion in https://github.com/ThePhD/out_ptr/issues/19: TLDR: "clever" contains a potential double-free and fix seems to be not considered (or postboned) as it is "off by default" Therefore having an unsafe, buggy class inside the library should not be allowed. The provided implementation works for smart pointers that follow conventions like the standard, but has some additional logic if the types happen to be `std::shared_ptr` or `boost::shared_ptr`. This hard coded special casing won't work with, say, a company specific shared pointer implementation. This relates to my earlier comment that the customization point should be simplified. Great point. I'd suggest to provide 1 implementation and let customization points handle these "special cases". This will be a great test on how to implement those using the "official" customization points and whether the API is sufficient.
Dear David Sankel, I had forgotten to address this other point of the review: On Thu, Jun 27, 2019 at 10:08 AM David Sankel via Boost < boost@lists.boost.org> wrote:
The provided implementation works for smart pointers that follow conventions like the standard, but has some additional logic if the types happen to be `std::shared_ptr` or `boost::shared_ptr`. This hard coded special casing won't work with, say, a company specific shared pointer implementation. This relates to my earlier comment that the customization point should be simplified.
It would never work with your company's shared pointer, unless your
company happens to employ a shared pointer that contains a `.release()`
method that takes no arguments. I would find it incredibly surprisingly if
someone's shared pointer had a .release() method on it, given the decades
of nomenclature we have had around Boost and Standard smart pointers. And
even then, ensuring that such does not happen requires very little code in
the case that your shared pointer does have a .release() method:
namespace boost { namespace out_ptr {
template
participants (5)
-
Alexander Grund
-
Andrzej Krzemienski
-
David Sankel
-
JeanHeyd Meneide
-
Zach Laine