Bsl - Rust 2018 and C++20, "constexpr everything", AUTOSAR compliant header-only library intended to support the development of critical systems applications

Overview

Bareflank

Description

The Bareflank Support Library (BSL) is a Rust 2018 and C++20, "constexpr everything", AUTOSAR compliant header-only library intended to support the development of critical systems applications. Although the BSL does not adhere to the Rust and C++ Standard Library specifications, it attempts to where possible, to ensure most of the APIs are as familiar as possible. Since a number of critical systems applications do not support dynamic memory or exceptions, the BSL uses neither, but is capable of supporting both if desired. Since AUTOSAR only supports C++, the Rust code was written with the same AUTOSAR rules where applicable.

With respect to testing, the BSL provides full unit testing with 100% code coverage. Futhermore, the C++ portion of the BSL is written entirely as a "constexpr", meaning APIs are unit tested both at compile-time and run-time. This allows us to ensure that the compiler's rules for constexpr and undefined behavior are leveraged to prove most of the C++ code does not invoke UB at runtime.

Quick start

GitHub release (latest by date)

Get the latest version of the BSL from GitHub:

git clone https://github.com/bareflank/bsl
mkdir bsl/build && cd bsl/build
cmake -GNinja -DCMAKE_CXX_COMPILER="clang++" ..
ninja

Enjoy:

#include <bsl/arguments.hpp>
#include <bsl/array.hpp>
#include <bsl/convert.hpp>
#include <bsl/cstr_type.hpp>
#include <bsl/debug.hpp>
#include <bsl/exit_code.hpp>
#include <bsl/safe_idx.hpp>
#include <bsl/safe_integral.hpp>
#include <bsl/unlikely.hpp>

[[nodiscard]] auto
main(bsl::int32 const argc, bsl::cstr_type const *const argv) noexcept
    -> bsl::exit_code
{
    constexpr auto num_expected_args{2_umx};
    bsl::arguments const args{argc, argv};

    if (args.size() < num_expected_args) {
        bsl::error() << "Invalid number of args" << bsl::endl << bsl::here();
        return bsl::exit_failure;
    }

    constexpr auto index_of_arg{1_umx};
    auto const val{args.at<bsl::safe_i32>(index_of_arg)};

    if (bsl::unlikely(val.is_invalid())) {
        bsl::error() << "Invalid arg" << bsl::endl << bsl::here();
        return bsl::exit_failure;
    }

    constexpr auto size_of_arr{42_umx};
    bsl::array<bsl::safe_i32, size_of_arr.get()> mut_arr{};

    for (auto &mut_elem : mut_arr) {
        mut_elem = val;
    }

    for (bsl::safe_idx mut_i{}; mut_i < mut_arr.size(); ++mut_i) {
        bsl::print() << "elem["                                    
                     << mut_i                                       
                     << "] == "                                     
                     << bsl::fmt{"#010x", *mut_arr.at_if(mut_i)}    
                     << bsl::endl;                                  
    }

    return bsl::exit_success;
}

Interested In Working For AIS?

Check out our Can You Hack It?® challenge and test your skills! Submit your score to show us what you’ve got. We have offices across the country and offer competitive pay and outstanding benefits. Join a team that is not only committed to the future of cyberspace, but to our employee’s success as well.

ais

Build Requirements

Currently, the BSL only supports the Clang/LLVM 11+ compiler. This, however, ensures the BSL can be natively compiled on Windows including support for cross-compiling. Support for other C++20 compilers can be added if needed, just let us know if that is something you need.

Windows

To compile the BSL on Windows, you must first install the following:

Visual Studio is needed as it contains Windows specific libraries that are needed during compilation. Instead of using the Clang/LLVM project that natively ships with Visual Studio, we use the standard Clang/LLVM binaries provided by the LLVM project which ensures we get all of the tools including LLD, Clang Tidy and Clang Format. Also note that you must put Ninja somewhere in your path (we usually drop into CMake's bin folder).

To compile the BSL, use the following:

git clone https://github.com/bareflank/bsl
mkdir bsl/build && cd bsl/build
cmake -GNinja -DCMAKE_CXX_COMPILER="clang++" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON ..
ninja info
ninja

Ubuntu Linux

To compile the BSL on Ubuntu (20.04 or higher) you must first install the following dependencies:

sudo apt-get install -y clang cmake

To compile the BSL, use the following:

git clone https://github.com/bareflank/bsl
mkdir bsl/build && cd bsl/build
cmake -DCMAKE_CXX_COMPILER="clang++" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON ..
make info
make

Why 'constexpr everything'

The BSL implements everything as a "constexpr". Beyond the usual reasons for compile-time code, the BSL enables unit tests to be executed at compile-time. Although C++20 added an enormous amount of additional support for "constexpr", there are a number of things that are still not allowed in a "constexpr", and this is a good thing, especially if critical systems compliance is important to your use case. This includes:

  • No support for Undefined Behavior (UB)
  • No support for casts from a void* to something else, or any other attempts to change an object's type without proper lifetime management.
  • No support for memory leaks and any other memory related issues like out-of-bounds array accesses, etc.
  • No support for reinterpret_cast, goto, etc.
  • No support for the use of uninitialized variables
  • No support for global or static local variables
  • And much more

In other words, the constexpr validation checker in the compiler is in a way, the ultimate dynamic analysis tool. Tools like ASAN, UBSAN and Clang-Tidy are helpful, and should still be used, but if you ensure 100% code coverage at compile-time, most of the hard to find bugs related to undefined behavior will be eliminated. To perform compile-time unit testing, consider the following test:

[[nodiscard]] constexpr auto
tests() noexcept -> bsl::exit_code
{
    bsl::ut_scenario{"verify += adds correctly"} = []() noexcept {
        bsl::ut_given{} = []() noexcept {
            constexpr auto data1{42_umx};
            bsl::safe_umx data2{};
            bsl::ut_when{} = [&]() noexcept {
                data2 += data1;
                bsl::ut_then{} = [&]() noexcept {
                    bsl::ut_check(data2.checked() == data1);
                };
            };
        };
    };

    return bsl::ut_success();
}

To execute this test at compile-time, simply do the following:

[[nodiscard]] auto
main() noexcept -> bsl::exit_code
{
    static_assert(tests() == bsl::ut_success());
    return tests();
}

Using this pattern, all unit tests will be executed at both compile-time and at runtime, allowing you to use things like code coverage tools to ensure complete coverage of your unit tests.

If you think this is impossible in any real-world example, take a look at the Bareflank Hypervisor. This is not a simple "Hello World" application, but instead is a hypervisor microkernel, complete with paging, ASM logic, etc. With a couple small exceptions (like virtual address to physical address conversions), all of the C++ code in this repro is tested at compile-time with 100% code coverage including branch coverage.

AUTOSAR Compliance

The BSL is mostly compliant with AUTOSAR, and in a lot of ways far exceeds the AUTOSAR rules. This means the BSL is one of the few, if not the only partial C++ libraries in open source that is AUTOSAR compliant. There are some rules that are not adhered to:

  • The BSL uses C++20. Without C++20, constexpr unit testing would not be possible. AUTOSAR requires the use of C++14. The advantages of "constexpr everything" for safety far out-weight the disadvantages of needing an exception to this rule. To ensure as much compliance as possible, the BSL avoids most of the new features added with C++17 and C++20 and will wait until a new AUTOSAR/MISRA specification is available to provide proper guidance.
  • Since C++14 is not used, issues with things like auto i{}; are fixed and therefor allowed. Two's compliment as well. This does not mean that all uses of auto are allowed as a number of rules still exist around auto that have nothing to do with the ambiguity issues with auto i{}; in C++14.
  • Some user-defined literals are provided for initializing fixed-width integrals. How this is done to ensure there are no issues with initializing variables can be found in the convert.hpp header file, but the short story is, it is absolutely possible to create safe user-defined literals if raw literals are used (instead of their cooked counterparts). Raw literals require the code to manually parse the literal's tokens and thanks to C++20's extensive support for constexpr, this is all possible at compile-time.
  • In some rare situations the BSL does not use an explicit single argument constructor to ensure compatibility with the C++ standard library where it makes sense. In these cases, a deleted single argument template function is provided which ensures that implicit conversions are still not possible, mitigating this issue. In fact, implicit conversions of any kind are not allowed by our custom version of the Clang-Tidy static analysis engine, including implicit conversions of integral types.
  • There are some rules that simply cannot be adhered to when implementing the C++ standard library features. For example, the BSL must perform pointer arithmetic using the subscript operator when implementing bsl::array. It must also include some non-C++ headers like stdint.h to implement cstdint.hpp as required by the spec.
  • C++ exceptions are not used by the BSL, but they are supported (meaning you can use C++ exceptions with the BSL if you choose). This is due to the fact that a lot of embedded, IoT and kernel/hypervisor applications for the BSL cannot support C++ exceptions due to the need for an unwinder, which is only really provided for Windows, Linux and macOS.

Resources

Join the chat

The Bareflank Support Library provides a ton of useful resources to learn how to use the library including:

If you have any questions, bugs, or feature requests, please feel free to ask on any of the following:

If you would like to help:

Testing

Build Status codecov

The Bareflank Support Library leverages the following tools to ensure the highest possible code quality. Each pull request undergoes the following rigorous testing and review:

  • Static Analysis: Clang Tidy
  • Dynamic Analysis: Google's ASAN and UBSAN
  • Code Coverage: Code Coverage with CodeCov
  • Coding Standards: AUTOSAR C++14 and C++ Core Guidelines
  • Style: Clang Format
  • Documentation: Doxygen
Comments
  • cmake: Add bf_check_dependency

    cmake: Add bf_check_dependency

    This patch makes the following changes:

    • cmake: Add a bf_check_dependency(name git_tag) macro intended to be used by dependees of this project.
    • CI: Trigger CI on any branch on push and prevent markdown-only updates to trigger CI.

    bf_check_dependency(name git_tag) checks that a dependency overridden with FETCHCONTENT_SOURCE_DIR_<NAME> is pointing to the expected git tag and warns if it isn't.

    Here is an example of its usage from MicroV (and hypervisor) showing bright yellow warning lines: dep_warning

    opened by chp-io 1
  • Minor fixes to support the hypervisor and IWYU support

    Minor fixes to support the hypervisor and IWYU support

    This patch

    • Fixes some issues identified by trying to use the BSL with the hypervisor repo.
    • Adds support for include-what-you-use and fixes a number of include file issues that were identified
    opened by rianquinn 1
  • Improvements to integer support and adds initial Rust support

    Improvements to integer support and adds initial Rust support

    This patch provides the following:

    • Provides some house keeping name changes to reduce verbosity and name collisions
    • Adds a checked() bit to the safe integrals, providing a means to detect when a safe integral is not being checked after arithmetic is performed.
    • Adds a safe_idx for working with indexes
    • Adds contact support with assert, expects and ensures.
    • Adds initial support for Rust including full unit tests. There is more to do here still before it will compile but it is close.
    opened by rianquinn 1
  • Changes to support the development of the hypervisor microkernel

    Changes to support the development of the hypervisor microkernel

    This patch contains various changes that were identified as issues during the development of the hypervisor microkernel. Most of these changes are either some minor missing features, or minor mods to existing logic to ensure it compiles/executes in a more usable way.

    opened by rianquinn 1
  • Changes to support the development of the hypervisor microkernel

    Changes to support the development of the hypervisor microkernel

    This patch contains various changes that were identified as issues during the development of the hypervisor microkernel. Most of these changes are either some minor missing features, or minor mods to existing logic to ensure it compiles/executes in a more usable way.

    opened by rianquinn 1
  • Fix issues identified by Clang Tidy

    Fix issues identified by Clang Tidy

    Now that we have a bunch of checks in Clang Tidy for checking for AUTOSAR compliance, these checks found a number of issues with our implementation of the BSL. This patch addresses a number of these issues, but is really just the start of a much larger effort to get this code more into compliance as we better define how we want to address AUTOSAR and ASIL compliance.

    opened by rianquinn 1
  • Add the ability to increment a bsl::arguments

    Add the ability to increment a bsl::arguments

    The bsl::arguments needs some additional APIs for working with it that make it easy to parse arguments. Specifically, as each argument is handled, we need the ability to move to the next argument, while still being able to use something like .front() which this PR adds.

    opened by rianquinn 1
  • Fix integration issues with the hypervisor

    Fix integration issues with the hypervisor

    FetchContent changes the meaning of the CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR, so that scripts and targets need to make sure they are taking this into account

    opened by rianquinn 1
  • Example test in readme.md doesn't really test addition

    Example test in readme.md doesn't really test addition

    The example code in README.md aims to test the += operator of safe_umx, but because it adds 42 to 0, it would also pass if the operator was (incorrectly) implemented as an assignment instead of an addition (as zero is the identity element of addition).

    The fix would be to initialize data2 to a non-zero value.

    https://github.com/Bareflank/bsl/blob/6509cfff948fa34b98585512d7be33a36e2f9522/README.md?plain=1#L139-L144

    opened by Kristine1975 0
  • support for macOS Monterey 12.1 and XCode 13.2.1

    support for macOS Monterey 12.1 and XCode 13.2.1

    Hi,

    My mac has llvm/clang 12 (and I know your README says that only clang 11 is supported).

    I have made some small changes to the CMake file to support "Darwin" (Apple macOS), but I have not managed to compile.

    error.log

    What would be needed to make the BSL build on this platform?

    Regards.

    opened by fgenolini 0
Releases(v1.0.0)
Owner
Bareflank
Bareflank
gsl-lite – A single-file header-only version of ISO C++ Guidelines Support Library (GSL) for C++98, C++11, and later

gsl-lite: Guidelines Support Library for C++98, C++11 up metadata build packages try online gsl-lite is an implementation of the C++ Core Guidelines S

gsl-lite 753 Sep 13, 2022
Single-header header-only C++11 / C++14 / C++17 library for easily managing set of auto-generated type-safe flags.

Single-header header-only C++11 / C++14 / C++17 library for easily managing set of auto-generated type-safe flags. Quick start #include <bitflags/bitf

Marin Peko 72 Aug 24, 2022
jkds is a modern header-only C++20 library that complements the standard library.

jkds is a modern header-only C++20 library that complements the standard library. It provides generic atypical data structures, ergonomic functional programming abstractions, and then some.

Alberto Schiabel 5 May 24, 2022
expected lite - Expected objects in C++11 and later in a single-file header-only library

expected lite: expected objects for C++11 and later expected lite is a single-file header-only library for objects that either represent a valid value

Martin Moene 231 Sep 19, 2022
optional lite - A C++17-like optional, a nullable object for C++98, C++11 and later in a single-file header-only library

optional lite: A single-file header-only version of a C++17-like optional, a nullable object for C++98, C++11 and later Contents Example usage In a nu

Martin Moene 348 Aug 10, 2022
span lite - A C++20-like span for C++98, C++11 and later in a single-file header-only library

span lite: A single-file header-only version of a C++20-like span for C++98, C++11 and later Contents Example usage In a nutshell License Dependencies

Martin Moene 404 Sep 21, 2022
string_view lite - A C++17-like string_view for C++98, C++11 and later in a single-file header-only library

string_view lite: A single-file header-only version of a C++17-like string_view for C++98, C++11 and later Contents Example usage In a nutshell Licens

Martin Moene 332 Sep 23, 2022
variant lite - A C++17-like variant, a type-safe union for C++98, C++11 and later in a single-file header-only library

variant lite: A single-file header-only version of a C++17-like variant, a type-safe union for C++98, C++11 and later Contents Example usage In a nuts

Martin Moene 214 Sep 22, 2022
Modern C++ generic header-only template library.

nytl A lightweight and generic header-only template library for C++17. Includes various utility of all kind that i needed across multiple projects: Ex

Jan 94 Sep 15, 2022
A header-only, unobtrusive, almighty alternative to the C++ switch statement that looks just like the original.

uberswitch A header-only, unobtrusive, almighty alternative to the C++ switch statement that looks just like the original. Sample usage (incomplete -

Fabio 82 Sep 7, 2022
GNU Scientific Library with CMake build support and AMPL bindings

GSL - GNU Scientific Library This is GSL, the GNU Scientific Library, a collection of numerical routines for scientific computing. GSL is free softwar

AMPL 415 Sep 20, 2022
Guidelines Support Library

GSL: Guidelines Support Library The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the C++ Core Guideline

Microsoft 5.1k Sep 25, 2022
Guidelines Support Library

GSL: Guidelines Support Library The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the C++ Core Guideline

Microsoft 5.1k Sep 25, 2022
Library that simplify to find header for class from STL library.

Library that simplify to find header for class from STL library. Instead of searching header for some class you can just include header with the class name.

null 6 Jun 7, 2022
C++11/14/17 std::optional with functional-style extensions and reference support

optional Single header implementation of std::optional with functional-style extensions and support for references. Clang + GCC: MSVC: std::optional i

Sy Brand 672 Sep 16, 2022
C++ STL in the Windows Kernel with C++ Exception Support

C++ STL in Windows Drivers This project uses MSVC C++ STL in a Windows Kernel Driver. In this solution jxystl.lib is implemented as a kernel-tuned, po

Johnny Shaw 265 Sep 17, 2022
Improved and configurable drop-in replacement to std::function that supports move only types, multiple overloads and more

fu2::function an improved drop-in replacement to std::function Provides improved implementations of std::function: copyable fu2::function move-only fu

Denis Blank 399 Sep 19, 2022
A collection of std-like single-header C++ libraries

itlib: iboB's Template Libraries A collection of small single-header C++ libraries similar to or extending the C++ standard library. See below for a l

Borislav Stanimirov 79 Sep 21, 2022
Libft is an individual project at 42 that requires us to re-create some standard C library functions including some additional ones that can be used later to build a library of useful functions for the rest of the program.

?? Index What is Libft? List of Functions Technologies ✨ What is Libft? Libft is an individual project at 42 that requires us to re-create some standa

Paulo Rafael Ramalho 7 Jan 17, 2022