Hi all, I've written up a draft for static and shared libraries in the C++ Language, I'm hoping to get some feedback so I can improve it. I apologize if this is not the proper format, I didn't have much time to put this together and don't really know the proper tools for doing so, since this is my first time writing a C++ draft. All feedback welcome!

Document number:  PnnnnR0
Date:  2023-mm-dd
Audience:  Library Evolution Working Group
Reply-to:  Julian Waters <tanksherman27@gmail.com>

I. Table of Contents

II. Introduction

Introduce official support and specification for compiling C++ code as static or shared libraries (distinct from executable programs) to the C++ Language, and an additional linkage type of "imported" and "exported" to the existing linkages of none, internal, and external, for use within the aforementioned shared libraries.

III. Motivation and Scope

Libraries have been an unofficial and nonstandard, yet enormous part of C++ for a long time. Code in a vast amount of codebases and repositories rely on compiling and distributing libraries to be used and linked into executable programs. Operating System support for shared libraries in particular, is virtually ubiquitous. Code compiled as a shared library has its merits, including by not limited to:

-Reduced amount of duplicated code in each binary

-Runtime loading on the fly, allowing for plugin systems and hotswapping code quickly by changing a single library

Despite the widespread adoption of such libraries by compiler vendors, operating systems, and users, they have not been officially specified. As such, many differing extensions to the C and C++ Languages have all come into play, each with different default behaviours and usages, making it difficult to write code that works on different platforms. However, it can be observed that the vast majority of them seem to operate based on one constant universal basis of symbols, internal to the library and external, meaning it is exported and can be called or accessed by an external process, giving room for well defined and standardized behaviour.

The current proposal therefore is to provide a standard way of specifying exported linkages in shared libraries, as well as well defined linkage rules in static and shared libraries, while still leaving behaviour like name mangling implementation defined.

IV. Impact On the Standard

The current change proposed here is a new addition to the C++ Language, in particular to the issue of language linkage (more specifically, a new level of linkage in addition to the already existing linkages of none, internal, and external), which is already part of the core language and syntax, and as such does not affect library components, nor do any library components depend on it (though it should be noted that library components from the standard library can formally be linked into executable programs or other shared libraries through the changes proposed here; this is already widely supported by compilers in nonstandard ways).

Although most of the current proposal simply adds entirely new functionality to the C++ Language, there is a section within the "Phases of Compilation" section that will require minimal changes should this proposal be accepted.

The current draft simply makes the common action of linking to shared libraries at runtime better defined, and provides a standard way to do so, in other words it is merely standardizing standard practices already supported by a vast amount of compilers through compiler specific extensions.

V. Design Decisions

Static libraries are treated as implementation defined, to avoid the issue of over-specifying their behaviour, since too many restrictions can hurt the feasibility of inclusion into the standard. Majority of static libraries are essentially object files bundled together into a single large archive, so the same existing linkage rules following static, no linkage, and extern apply to them.

Don't work in conjunction with modules: Such code extends outside of compilation units that modules work with, doing so would simply complicate the standardization.

Introduce the exported language linkage, which is only valid within shared libraries. Behaviourally equivalent to the extern "" language linkage, except that it specifies that the symbol it is applied to is exported from the shared library and can be used by other libraries and executable programs. Syntax: export "" <Declaration>.

Introduce the imported specifier, valid within programs and static or shared libraries. Functionally equivalent to the extern specifier, except that it is a compiler hint that the current symbol is not immediately found within any of the listed libraries but rather is to be resolved at runtime. Is not strictly required, meaning code can also use the extern specifier in place of import; This is only meant as a compiler hint for optimizations. Can be used together with extern such as import extern, since it is a compiler hint. Code that defines a symbol marked as imported in the same translation is ill-formed. It is allowed for different declarations of a symbol to be marked as imported and extern separately, but no other linkages other than extern are allowed for a symbol marked as imported. Syntax: import [extern] <Declaration> (Takes precedence over modules)

VI. Technical Specifications

  basic.start.main

A program shall contain a global function called main

->

  An executable program shall contain a global function called main

  lex.phases

All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment.

->

All external entity references are resolved. Library components, and any specified static or shared libraries, are linked to satisfy external references to entities not defined in the current translation. All such translator output is either collected into a program image or a static/shared library which contains information needed for execution in its execution environment.

VII. Acknowledgements

VIII. References