Boost logo

Boost :

Subject: Re: [boost] [outcome] non-interface-related concerns
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-26 21:02:31


2017-05-26 17:07 GMT+02:00 Niall Douglas via Boost <boost_at_[hidden]>:

> On 26/05/2017 15:14, Andrzej Krzemienski via Boost wrote:
> > The discussion mostly revolves around the design of the interface of
> > `outcome::expected` and even `std::expected`. My questions here are about
> > the way this library will be distributed to users. And I am uncomfortable
> > with the situation. I am not necessarily saying it is wrong, but I do not
> > understand what is going on here.
> >
> > 1. The current GitHub repository consists of sub-repos. Do you (Niall)
> plan
> > to have it like this when the library is accepted? Is it relevant?
>
> A lot of the opposition to git subrepos appears to stem from lack of
> awareness of how they and git work. Some are opposed to boost-lite
> substituting for Boost, but as I have mentioned a fair few times now, I
> am following precedent for C++ 14 mandatory libraries here which doesn't
> have a hard dependency on monolithic Boost, and whether the internal
> platform abstraction layer is in a subrepo or not isn't hugely important
> for the end user.
>

Out of curiosity, what precedent is it?

>
> I mean, they just #include and go. If that works, does any of the rest
> of it matter?
>

As a matter of fact, my questions were motivated by the fact that I
#included but it didn't work. But apparrently, I incorrectly attributed the
problem to sub-modules.

>
> > 2. This macro BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE, it
> > controls whether I use this "preprocessed" file versus if I use... what?
> > Normal header files? What is gained by this preprocessed file? Not having
> > to include more than one header, or something else? Can I get different
> > results when compiling with and without this macro?
>
> The partially preprocessed edition is auto generated per commit. It
> saves the compiler from doing all the recursive #includes per compiland.
> It reduces compile times for end users a lot, I measured about half a
> second per compiland. Say for a project of 200 compilands, that's 10
> seconds.
>

Are you saying the gain stems form includingg 1 versus N files?

>
> Several other Boost libraries also pre-preprocess header files into the
> source tree and when you #include that library, you are including the
> pre-preprocessed edition, not the original source code. It's pretty
> conventional for libraries doing a lot preprocessor work to use this
> technique to reduce the compile time impact on end users.
>

Could you tell me which libraries?

Also, if the contents are identical, what do I need the non-preprocessed
version for?

> > 3. I am recommended to use this macro BOOST_OUTCOME_V1_NAMESPACE. I am
> told
> > it has something to do with ABI stability? Can you elaborate on how this
> > guarantees ABI stability. Or is its purpose different?
>
> It's described in the docs at
> https://ned14.github.io/boost.outcome/md_doc_md_02-tutorial_
> a.html#expected_example
> where it says:
>
> // Traditional: use SOME version Boost.Outcome visible to the
> compiler/linker
> namespace outcome = boost::outcome;
>
> // Better: use EXACTLY the Boost.Outcome visible in the current
> translation unit
> namespace outcome = BOOST_OUTCOME_V1_NAMESPACE;
>
>
> Imagine a future world where we supply two incompatible versions of
> Outcome:
>
> 1. namespace boost { namespace outcome { namespace v1 { ... } } }
>
> 2. namespace boost { namespace outcome { inline namespace v2 { ... } } }
>
> If you write:
>
> namespace outcome = boost::outcome;
>
> You are going to get the v2 namespace as that's the inlined latest
> version. Your code may now break because you wrote your code for v1.
>
> If you write instead:
>
> namespace outcome = BOOST_OUTCOME_V1_NAMESPACE;
>
> Then your code gets the v1 namespace it was written against.
>
> This design allows some code to use v1 and other code to use v2 in the
> same translation unit. This prevents dependency includes messing things
> up for other dependency includes.
>

Ok, let me change your explanation a bit. Going back to your exable, I have
two version namespaces:

```
namespace boost { namespace outcome { namespace v1 { ... } } }
namespace boost { namespace outcome { inline namespace v2 { ... } } }
```
Now, if I want to use outcome from v1, I can type:

```
namespace outcome = boost::outcome::v1;
```

And I didn't use any macro. I guess my question is, why do you need a macro
for it?

> > I have a certain problem with understanding this philosophy. A couple of
> > days back, I reported the compilation failure in MinGW. I can see that
> the
> > issue (https://github.com/ned14/boost.outcome/issues/36) is reorted as
> > fixed in branch 'develop'. I would like to confirm that the bug is
> fixed. I
> > checkout branch develop. There is no branch develop for the sub-repos, so
> > what am I supposed to checkout, master, or some particular commit? I went
> > with master.
>
> This is not the correct usage of git.
>
> In git to check out branch develop and the exact corresponding editions
> of subrepos for develop branch you would do:
>
> git checkout develop
> git submodule update --recursive
>

Thanks. I was missing that.

>
> This is 100% standard git when checking out a new branch. Nothing to do
> with Outcome.
>
> > I do not understand a lot of CMake, but since it is a header-only
> library,
> > I assume that I can just #include the file "include/boost/outcome.hpp",
> and
> > my programs (compiled manually) should compile.
>
> Correct.
>
> > But the only change in the commit that was supposed to fix the bug, was
> in
> > a .cmake file, so I cannot see how it would help fix a header only
> library.
>
> You must have missed the missing #include I added.
>

Yes, I did: `<string.h>`

>
> > Also, would the fix be visible in a "precompiled" header, or normal
> > headres, or both?
>
> The missing #include appears in the partially preprocessed edition as
> you would expect.
>
> The cmake changes were to fix other issues. I was forcing stack
> protector on if GCC was detected. Stack protector is not supported by
> mingw, so I no longer enable it for mingw only. I also added the ability
> to force disable clang-tidy as the mingw-w64 clang-tidy segfaults
> currently.
>
> > I am not complaining about this particular fix. I would like to know how
> in
> > this system of mcros, sub-modules and preprocessed headers, I can figure
> > out what changes will be observed in my program, when I see a particular
> > change in git sub-repo.
>
> Github usefully displays the exact changes, including in any subrepos.
> The display for the mingw bug fix can be found at:
>
> https://github.com/ned14/boost.outcome/commit/
> 62d9bed841af5b2dfd85f17aa17a3876d966cb74
>
> You'll see immediately at the top the files changed in any subrepos.
> Clicking on any of them will display a colour coded diff of before to
> after.
>

Yes, I get that. Ok, now I understand why I got confused. I think the fix
simply did not remove all errors on my version of MinGW.

Regards,
&rzej;


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk