Boost logo

Boost :

Subject: Re: [boost] [outcome] non-interface-related concerns
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-26 15:07:05


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.

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

> 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.

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.

> 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.

> 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

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.

> 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.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

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