C++ Logo

std-proposals

Advanced search

Compatible API proposal

From: mohamed koubaa <koubaa.m_at_[hidden]>
Date: Thu, 7 Nov 2019 16:00:31 -0600
Hello,

My name is Mohamed Koubaa and I am a software developer that works on a
large scale desktop application. More than half of what I write is in C++
and I often think about physical layout and ABI. I hope you'll consider my
idea! This is my first post here and look forward to hearing feedback
from all of you.

Reply-to: Mohamed Koubaa <koubaa.m at gmail ~dot~ com>
Introduction

This paper discusses a set of extensions to C++ to standardize a
compatibility ABI in some parts of the standard library and type system.
It is not meant to propose an ABI for all types and language features

Motivation and Scope

C ABI compatibility is often wrongly assumed and expected by C++
developers. The language evolution often will introduce new types and
features leaving the ABI unspecified. Over time, code begins to depend on
this ABI and changes to it become infeasible or impossible. This situation
is not inherently c++ic (using Herb’s term). It is simply a historical
outcome based on where the language came from and its often shared runtime
with C.

ABI is not a problem with most other popular languages and is really
holding back the C++ ecosystem. The way other languages deal with (or
don't have to) are:

   -

   C - Compatibility is a primary concern and the C ABI is practically how
   other languages often achieve ABI
   -

   Python - See above. Python extension modules (often written using C++!)
   are ABI compatible because the CPython interface is, well, C.
   -

   JS/C#/Java - these languages use a virtual machine or interpreter so
   that the ABI design are outside of the domain of the everyday programmer
   and library author


After using C++ for some years I and others have the understanding that in
order to have truly portable C++ code, it must be distributed as source
code and built by clients. Clients need to understand the (often varied)
build systems and tests in order to use just about any useful C++ library.
This is a burden that is neither expected nor tolerated when using other
compiled languages.

Another concern with the current state of affairs is that for any
individual to be a competent software architect of large scale software
systems (perhaps excluding distributed systems and microservices) needs to
master the sharp edges around ABI compatibility.

One technique for building C++ code without dealing with ABI is called an
hourglass pattern. This means building a C layer at the interface of
binaries and writing c++ code to wrap that C interface in a user friendly
C++ API. This is sometimes done using plain C and other times done using
COM (on windows). Essentially, this is an admission that in order to have
stable ABIs one must only use a small subset of C++ types and language
features on the interface, and that subset is essentially C. In the
narrow center of the hourglass free functions for allocating and freeing
memory, as well as errno() are often used and converted back into
constructors, destructors and exceptions.

If a stable ABI is known which includes many important standard library
types, language interop can become idiomatic. For instance, a language
consuming an exported method which returns a stable_vector can wrap that in
the most appropriate language semantics. I.e. IEnumerable/IList for C# or
__len__ in python
Impact on the standard

This paper does *not* attempt to propose an ABI for the entirety of the c++
type system and library features. Instead, a portion of the standard
library (some existing, some new) will be marked as having a stable ABI,
and library authors can opt into using that portion at the binary interface
of libraries so that ABI compatibility is no longer a concern for their
clients. In spirit, this is no different than the hourglass pattern,
except that the subset of C++ which can be considered to be ABI stable is
larger than simply what is shared with C due to history. Examples of these
types are the P0709 exception and ranges which are in c++20. Examples of
library features are a new stable_allocator and a std::stable metaclass
which can be used for compile time reflection on classes to ensure that
they are indeed stable.

Other language features are explicitly not expected to be stable and
implementations of c++ can change their ABI at any time. In practice it
will likely be difficult for an implementation to do that until using
stable ABIs at binary interfaces becomes a common practice.
Technical Specifications

This proposal introduces the notion of stable, a property of a type or
feature whose ABI is defined to never change. Stable can be thought of as
a superset of is_standard_layout because ABI concerns extend beyond memory
layout. All types and language features are considered unstable unless
explicitly defined as stable. Following are the list of all stable types
and language features (there are not many):


   -

   Standard layout
   -

   P0709 exceptions
   -

   Stable_allocator
   -

   Fixed width integer types
   -

   Range
   -

   String_view
   -

   Array
   -

   Stable_vector
   -

   Stable_string


This set of types and features may grow slowly over time, much like
constexpr did since c++11, except with less urgency and with no interest in
someday covering the entire language.

std::stable_allocator

This proposal defines a std::stable_allocator which controls the behavior
of the new and delete functions and fixes them to a given version of
malloc() and free() on a given platform. For instance, the windows
platform has multiple C runtimes to choose from. Classes that have an
allocator template argument and whose clients provide stable_allocator are
such that any new and delete function that occurs in their member functions
will use the stable allocator. This will allow such a class to be
allocated in one binary unit and deleted in another without worrying about
the runtime of each unit.

std::stable metaclass

The std::stable metaclass can be used for types that which to declare
themselves as ABI stable. The class will fail to compile if any unstable
types or features are used at the interface of such a class.
Modules

This proposal does not intend to provide any relationship between modules
and the notion of stability. Modules may include all language features
which is larger in scope than stable ABI features. However, if a standard
attribute is added for visible symbols/dll export (does this exist yet?),
compilers may warn about any unstable types or features used in conjunction
with that attribute.


Thanks,
Mohamed

Received on 2019-11-07 16:03:01