boostorg / boostorg/safe_numerics

usability: splitting headers into public and private, support of include-what-you-use

Open
#116 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
222
Forks
46
PR merge metrics
No merged PRs in 30d

Description

As of right now it is not clear, which headers are public and which are private. Public headers are meant for inclusion by users of the library. The only way to approximate, whether the include is public or private is to look at documentation of interesting parts or at the examples -- if it is there, it is probably meant to be included, if it's not, it probably is not meant for inclusion.

The motivating issue is usage of external tooling, such is include-what-you-use program. This program can rather accurately determine, which headers the file is missing, or which can be removed, or which can be replaced by a forward declaration, if configured correctly. All in all, it increases correctness of C++ programs, and is thus useful. A sample output of the tool is as follows:

```
[9/16] Building CXX object src/CMakeFiles/libcherryblazer.dir/canvas.cc.o
Warning: include-what-you-use reported diagnostics:

/home/runner/work/cherry_blazer/cherry_blazer/src/canvas.hh should add these lines:
#include // for uint8_t
#include // for lazy_en...
#include // for uint8_t
#include // for operator!
#include // for cast
#include // for operator<
#include // for operator-
#include // for base_value

/home/runner/work/cherry_blazer/cherry_blazer/src/canvas.hh should remove these lines:
- #include // lines 8-8
- #include // lines 9-9
- #include // lines 11-11

The full include-list for /home/runner/work/cherry_blazer/cherry_blazer/src/canvas.hh:
#include // for uint8_t
#include // for lazy_en...
#include // for uint8_t
#include // for operator!
#include // for cast
#include // for operator<
#include // for operator-
#include // for base_value
#include // for base_value
#include // for ostream
#include // for unique_ptr
#include // for string
#include "color.hh" // for Color
#include "safe_numerics_typedefs.hh" // for safe_ul...
#include "types.hh" // for u16, u8
---
```

Now, the problem here is that I used seemingly public includes -- safe_integer, safe_integer_range, automatic, but the tool doesn't know that they are the ones that should be used, and not checked_default, checked_result_operations, etc. One way to teach the tool is to use a [mapping file](https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUMappings.md), where user can specify, which symbols/includes are public, and which are private. Sample contents of a mapping file:

```
[
# Replace suggested private GTest headers with public one.
{include: ["@", "private", "", "public"]},
{include: ["@", "private", "", "public"]}
]
```

What this does is, it stops iwyu from suggesting headers that match these wildcards, rendering them private, and instead is instructed to suggest the-one-and-only gtest.h.

This approach can only go so far. A better approach is for library creators to include [pragmas](https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md) to specify, which headers export which symbols, or simply which headers are part of public interface, and which are for the library implementer.

To summarize, the problem with safe_numerics for the end user who wants to check his program for correct header inclusion is: the library does not have clear separation of public and private headers.
* Possible solution 1: create a directory called "private" or "detail" and put private headers inside, which will allow the end user to specify a wildcard in iwyu mapping file to mark them private.
* Possible solution 2: library author works through the headers and marks them with appropriate iwyu pragmas. Less favorable for the library author, since it might take a lot of time getting it right and test that it correctly behaves with default iwyu settings, but in the long run, this approach will more more correct reports from the tool, and perhaps even library developers could use iwyu themselves to analyze header situation in their project, which will also stop iwyu from flagging safe_numerics dependencies, such as tribool in the sample output above.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.