Contracts — What Came Before

Introduction

Prior to the formation of SG21 there were a number of different potential
solutions proposed for contract based programming in the language. With the
formation of SG21, a large number of use cases that any future contract
solution might need to satisfy have been presented and polled on (see
P1995
for the use cases and the initial poll results).

In order to better understand these use cases, a number of people expressed
questions about how those use cases might be met with standard C++20 with no
language based contracts, and how each of the prior language proposals might
satisfy these use cases. We hope this exposition helps in understanding the
use cases better, and helps to leverage the work that has gone before into
determining our future direction for language based contracts.

Methodology

There are 4 primary language variations that we wish to evaluate for their
merits at satisfying the SG21 use cases:

N4842 - the current C++ working draft - is the closest appropximation
currently available of what wil be the C++20 standard, and
is (barring something incredibly surprising happening) going to ship with no
explicit contract checking facilities in the language or standard library
itself. Many groups around the world have implemented contract checking
libraries themselves (and come to the committee to attempt to build on those
experiences to get those features into the language) and those libraries are
still just as usable for contract checking in C++ today as they have always
been. We will reference the BDE libraries (https://github.com/Bloomberg/bde/,
specifically bsls_assert and bsls_review, which can be found in
https://github.com/bloomberg/bde/tree/master/groups/bsl/bsls)
for examples of what can be done with no new language support.

N4820 - The C++ draft prior to the Summer 2019 WG21 meeting in Cologne - was
the last draft that had the initially accepted contract checking facility.
As with all of the other facilities we will discuss here, this proposal allowed
for annotating contracts as boolean predicates within an attribute-like syntax
that could be attached to functions as preconditions or postconditions, and
put inside functions as assertions. Three basic contract levels were
allowed - default, audit, and axiom - with all levels either checked at
runtime or introducing undefined behavior if not checked and violated.

P1429 - This paper primarily focuses on redefining the contract behavior of
N4820 in terms of named semantics, and allowing for setting of the various
contract levels (default, audit, and axiom) to specific behaviors (in lieu of
the combination of build level and continuation mode available in N4820).

P1607 - This paper proposed removing the contract levels entirely and only
allowing the setting of specific semantics, with the intent to provide more
general build time control using macros until consensus could be reached on
how that control should be presented. This option, with no build levels
and just four literal semantics, reached consensus in EWG on July 15th 2019,
prior to the removal of contracts entirely from the draft.

Rather than enumerate all possible variations that could be chosen, we will
focus on comparing P1429 with no literal semantics and P1607 with no contract
levels.

For each of these variations, we will assign a value in the range 0-100 for
each use case with roughly the following meanings:

0 - Explicilty prohibitted or fundamnetally impossible.

25 - Feasible with great extra effort or in a highly limitted fashion, no
useful support for this use case.

50 - Limitted support, with possible caveats that would prevent real
satisfaction of this use case.

75 - Supported sufficiently to be used in a realistic situation.

100 - Fully supported with no major caveats.

The goal of these numbers is to give a rough feeling for worth. In the future,
we expect to see use cases given some weight (based partly on importance to the
community and partly on distinctness from other use cases), and then combined
with these numbers to give each solution a total value that can be used to
understand how effecitvely is satisfies the needs of the community.

Note that the long term goal here is not to give a number to say "you must vote
for this since it has a higher number" but rather to provide a value that
can be used to see "this solution measurably improves support for use cases that
I personally might not consider important but that others do see as a
priority".

Additionally, a number of features could conceivably be built in a compatible way
on top of any of these proposals using a system built with preprocessor macros
(and such macros are the only viable way to build a system with no language
support). Because of this, some scores are split into two numbers, the first
being a judgement on how well the proposal satisfies the use case "out of the box",
the second being how the proposal can be used with a macro facility above it to
meet the specified use case.

Use Cases

Annotate my program anywhere in the code with my current understanding of its
structure or execution

25

90

90

90

Without a specific contract checking facility there are still ways to annotate
a program with information about program contracts, but those are limited to
either comments (with no validation or normative effect), the classic C assert
macro, or larger nonstandard macro-based facilities
(with no consistency in representation across different implementations).
Typical usage would be within a function writing something like this:

void sqrt(double n) {
assert(n >= 0.0);
BSLS_ASSERT(n >= 0.0);
}

All of the contract proposals that were considered introduced the same syntax
for expressing an expectation that a certain boolean predicate was true at
specified points in a program. These satisfy most common use cases in the wild
for contract predicates, although being only boolean predicates makes them
fall short of being able to capture many more involved or not runtime checkable
aspects of a function contract. These include the ability to express this
within a function body as assertions like this:

double sqrt(double n) {
[[ assert : n >= 0.0 ]]
// ..
}

More notably, annotations of expectations about execution could be added on
function declarations as well -- something not possible with a solely language based
solution -- like this:

Express a spectrum of importance of my annotations, from "critical" (eg. bring
the system down) to "minor" (eg. lead to a slower fallback)

40

0

0

0
/40

While BDE's bsls_assert does not provide confidence as something that can be
used to control contract behavior, it is not hard to envision that such a thing
could be built into a macro-based solution.

Build-level-only solutions do not capture this at all (where N4820 and P1429
presented default, audit, and axiom as the only extra annotations that
could be put on a contract, and those were intended to capture cost of checking
not confidence).

P1607's literal semantics do not provide this directly, but here again one
could envision combining a macro-based solution to choose literal semantics
that would capture confidence or importance and compute behavior based on that.

Express a spectrum of expected cost at compile or runtime of my annotations,
from "unrunnable" to "expensive" to "cheap"

40

80

80

0
/50

A macro-based solution would again be able to be built to use an expression
of the cost of checking to determine how a contract will be treated, and BDE
does exactly this with the following variations on how a contract can be
checked:

Similar to the case for confidence and importance, any system that was built
on top of literal semantics for P1607 with macros would be able to choose to
capture cost as part of that control of contract behavior.

Ensure annotations do not substantially change the meaning of my program
whether enabled or disabled

100

0

50

50

The primary meaning of this use case is that there should be a way to
use the contract facility (on or off) without undefined behavior. This
does not preclude the ability to introduce undefined behavior - but it
needs to be optional. N4820 fails to provide this. A macro-based facility,
barring bugs, should be able to easily provide this. P1429 and P1607
provide the ignore semantic with no violation-introduced undefiend behavior.

Both P1429 and P1607 did not fix the fact that any side effects in a predicate are
treated as undefined behavior. Note that P1670R0
was scheduled for Cologne which had one proposal for an attempt to address that.

Have the effect of annotations on execution be user controllable (based on
whatever aspects, if any, are available).

65

50

55

25
/70

A macro-based solution can be built to use command line and in-code annotations
to determine contract behavior. P1607 and a macro-only facility would both
be able to provide any form of behavior control that users might wish to build, with
more consistency to the behaviors that different options might give with P1607.

N4820 and P1429 contract control is much more limited, primarily being only
doable at the build level of granularity.

Be able to easily change my confidence, importance, or other properties of my
annotations over time

40

25

50

25
/75

The build-level supporting options (N4820 and P1429) allow changing the one
attribute they expose (cost). The macro-based solutions would have to build
support for this, but can clearly put that in the sou rce code and thus make
editing the attributes of an annotation easy to edit.

An important thing to note is that safely changing annotation properties in
released software is equivalent to introducing that contract freshly in any
deployments that ignored the old 'level' and check the new 'level'. The ability
to introduce the check at the new 'level' with a continuing semantic is
essential to safely adding any checks to already deployed software. N4820 and P1429
both only allow the control of continuation at a very high level, thus forcing a
user to turn continuation on for all existing checks in order to safely add checks
that continue. P1607 provides the granularity to change this decision on a
per-contract basis.

Have annotation keywords or names with intuitive, clear, and unambiguous
meanings

10

50

50

60

Given that it provides no new keywords for contracts, readability is going to be
entirely dependent on what macro based facility is being used with N4842.

For N4820 and P1429, the clarity of 'default' is fairly opaque, and a huge
amount of reflector discussion and contention has revolved around the meaning and
use of axiom, so they fair poorly here.

P1607 removes the contentious keywords, but introduces new bespoke keywords
that while clear are not necessarily intuitive to all, along with needing to
build any other controls on top of those with macros, so it seems only slightly
better in this regard.

Have my contract specification to be visually primary, and secondary
information (syntax, hints, roles, levels, etc.) to not be distracting

15

10

10

10

All of the attribute-based solutions put the meta-information first before the
expression, counter to what this use case is asking for. A macro-based solution
could choose to prioritize information differently, but would also be
restricted in how the information gets passed into the macro.

Entirely macro-based facilities would need to be ubiquitous enough for tooling
vendors to choose to support them explicitly, along with those tooling vendors
needing to work around the difficulties of managing pre-preprocessor based
analysis.

Obviously not very much can be done with the base language without macros.

P1607 would require macros to support any form of global controls, so it gets
the lowest rating for this use case, while P4820 would be usable for basic
applications without macros, and P1429 would be slightly more flexible without
needing to resort to macros.

Define and check invariants over all entry and exit points from a coroutine (to
its awaiter or promise)

0

0

0

0

All of the solutions would work perfectly fine within the body of a coroutine.
Coroutine handling of contracts on inputs, outputs, and states when resuming
a coroutine had not had any discussions or support planned in the proposals
as they existed, so none of the proposals support coroutines any better than
a purely macro-based solution.

Have runtime able to launch a debugger from an annotation if necessary

25

40

40

40

As much as any C++ program is able to do something like signal that a debugger
should be opened, a macro based solution could invoke the platform-specific
functions that would enable that (such as __debugbreak() or raise(SIGTRAP)).
All of the prior solutions also provided a consistent place to put such a function
call by allowing for setting a custom violation handler, and due to that being
globally consistent we rate them slightly higher.

This is still not a standardized facility, so no solution completely satisfies
this use case within the standard itself.

Those solutions that would use macros to do global control (N4842 and P1607)
would be able to reference _NDEBUG or similar macros usually associated with
"debug" and "release" builds as input to how they configure contracts. The
standard, and the build levels specified in N4820 and P1429, are however
completely disconnected from one another.

None of the contract specifications as a language feature would have been
palatable to the C standards committee, since they all require being able to
attach meaning to an attribute, as well as make use of new identifiers with
special meaning (which are unfriendly to standardize in the macro-heavy C
world.)

A pure C++ macro based contract solution would, however, possibly be
implementable in a fashion that is equally usable from C code.

With no C interoperability easily possible, and the violation handler specified
in terms of an opaque class type (std::contract_violation), implementing
that violation handler i C would not have been feasible.

It is, however, likely that any C-based contract solution would be able to
bridge to and from the C++ contract violation handler, since there is no
particularly complex functionality in the violation handler or the violation
object itself.

Make all contract semantics optional (so as not to change WG14-N2385 6.7.11 p2)

50

25

25

0

P1607's explicit semantics require that they behave in a specific way when
asked for. Similarly, there is an expectation with N4820 and P1429 that build
levels can be set to something other than off, but they do allow global control
to do that (so at least one potential program behavior would be buildable
without needing to make contract annotations do anything).

Obviously a macro-based solution would be able to provide this kind of feature.

A pure macro-based facility exposes no contracts to callers, regardless of what
language the callers are calling from. The language-based facilities would not
have readily supported standardizing by WG14.

Declare class invariants that all of my public functions need to maintain

0

0

0

0

Neither a macro based facility or the language proposals allowed for specifying
at a class level invariants that would be automatically checked (barring
manually adding class invariants as pre and post conditions on every single
function.)

Make reference to the before and after values of global state (eg., global
>= old(global) + 1) in post-conditions

40

0

0

0

A macro based facility can similarly expose macros to control the enablement of
arbitrary code at arbitrary scopes, and so enables storing values between calling
time and return time manually.

The language-based facilities allow for referencing inputs and outputs, with
the caveat that inputs were only referencable in outputs if they were not
changed. The language-based facilities explicitly prevented any form of making
additional code execute if contracts were enabled, and thus removed the ability
to store data between the start and end of a function call.

Be able to use a predicate that cannot have a complete definition, because it
is inexpressible in the language

0

0

75

75

There is no current in-language way to express predicates that will not be
executed at runtime.

N4820 had unchecked contracts leave their evaluation as unspecified, thus making
any predicate that has UB or has side effects potentially evaluated
(specifically, the wording said "it is unspecified if the predicate of an
unchecked contract is evaluated".)

P1429 and P1607's assume semantic, however, attempted to capture the original
intent of the contract proposals and make unchecked contracts not be evaluated,
thus enabling the use of predicates that are not themselves safe to ever
evaluate.

Annotate assertions inside function bodies that indirectly test preconditions
(such as malformed data discovered while performing the algorithm) should be
reported to the caller as precondition failures

0

0

0

0

Macros within a function are unable to readily gather information about what
called the function, thus making it infeasible to identify calling code in a
precondition violation in a wholely macro-based facility.

N4820 made it possible to change that for [[pre]] annotations on a function
declaration, allowing for the reported source line to be the calling location
if the implementation is willing and able to do so. There was, however, still
no facility to explicitly point at a caller being the source of a problem
when the problem gets detected within the body of a function (or, for instance,
when delegating to another function without duplicating that function's
preconditions explicitly).

For every member or friend function in my class, run my unit test framework
with checking enabled for every assertion at the point where it is written, and
check every postcondition at every non-exceptional exit, and test my class
invariants on entry and exit from this type's code

0

0

0

0

This level of control is not providable for macros or the language proposals.

Express contracts on callbacks such as std::function, function pointers, or
references to functions, lambdas, or function objects

0

0

0

0

This would require contracts be part of a function type. Macros are not even
part of a function declaration, let alone its type, and the previous language
proposals did not choose to make contracts part of a function type either.

Only be required to manage a small, common set of build/link configurations

75

40

25

75

Policies on how many different builds are managed and deployed are entirely
up to users when the facility's controls are all done through macros (either
entirely in N4842 or on top of literal semantics in P1607).

N4820 includes 5 distinct build configurations that might be desired by clients
of a library, and P1429 increases that number to 32, though most are only
interesting in special cases and it is likely that individual vendors would find
a small set that are of actual interest to their clients.

The build levels are global, with conditional (and potentially no) support for
using mixed build levels across different libraries. Macro based solutions are
viable as long as any individual contract always has the same meaning in different
translation units (without ODR violations).

Be able to override how library violations are handled in the combined software
to point into my handling code

50

90

90

90

All of the facilities support checking contracts at runtime and being informed
of details of the violation. The language proposals included a pluggable
violation handler, although compiler vendors were allowed to not make that
customizable.

A pure macro-based facility suffers from needing to do this for all of the
contract facilities that might be defined and used within a given fully
assembled program.

Selectively enable checking for a translation unit or module and all (non
transitive) types and functions within

5

0

0

5

Different forms of build and runtime control could be built into the macro-based
facilities with varying levels of difficulty. N4820 and P1429 provided only a
global level of control, limiting greatly the ability to control contract enablement
at finer granularities. Implementing some of these forms of granularity in
the preprocessor might, however, be very complicated.

Macros and the language proposals had minimal concepts of "build time checking",
but they do all enable a global ability to turn off such checking. That same
global ability can be used to turn off runtime checking.

Accept responsibility for a malformed program that might result from eventually
false information given by my annotations

25

50

75

75

A macro based facility would be able to enable optimizations, but that is likely
going to have limited direct support from most compilers. (Generally, this would
leverage either __unreachable() or __assume().)

N4820 made optimizations enabled for ALL unchecked contracts, while P1429 and P1607
gave mechanisms to opt into that in varying ways.

Control the tradeoff between need for client recompilation and contract condition visibility

Insulate contract conditions with the function definition, or insulate only the
definition while putting contract conditions on a redeclaration - visible to
static analysis tools in all TUs.

25

50

50

50

Macro based contract checks will always be in the function body and thus
fully insulated from clients.

The contract annotations of the language proposals could be equivalently put
in function bodies with [[assert]] or on the declarations, thus giving some
control over insulation. The ability to have them visible to clients through
a redeclaration but not visible on the initial declaration was not, however,
in the initial proposals (but was proposed but not seen by EWG in
P1320R1.)

Any contract facility that allows control without source code manipulation will
require some build time control, either through compiler flags or macros, though
all should have been usable with some default behavior if no explicit choices
were made at build time.

Express assertions in a way that does not rely on C macros (i.e., there is no
valid technical reason for a programmer not to use the new way, including
space, time, tooling, and usability/complexity reasons, compared to C's assert
macro)

0

50

50

50

Contract checks without a language facility are not feasibly doable without macros.

All of the language proposals require macros in some form or other to satisfy
many of the use cases in this document, but still provide a basic contract
checking facility with no macros used at all.

Specify preconditions/postconditions/assertions/invariants that express my
expectations about the expected valid state of my program in the form of
compilable boolean expressions, that can be checked statically or dynamically
(as opposed to disjointed state where these features are factored into bits)

0

75

75

75

Obviously the language does not have this now, and the language proposals all
attempted to provide this.

Without a language feature contract descriptions are library-specific and not
uniform. With it, the only non-uniformity comes in when libraries build
extra infrastructure on top of the language-provided facility.

A library and a language-based facility will, however, be able to provide
a user understandable details of why a contract violation might have made a
program abort or fail to compile.

Be able to write and modify contracts quickly without heavy boiler plate or up
front cost

0

75

75

75

The general use of contracts once they are a language feature is quick to get
started on. Without a language feature, getting started requires acquiring or
implementing a library to provide the feature.

Assert against conditions I am aware of but not finished handling fully

20

0

0

75

Without a language-based facility the only way to enter a not-yet-implemented
contract is as a comment, which is of limited utility.

P1607's ignore and assume semantics both allow for referencing undefined functions,
and thus enable writing a planned contract while preserving writing the
implementation of that check for a future sprint. N4820 provides no way
to get that semantic for a contract annotation, and while P1429's assume semantic
would, there is no way in code to write such a contract.

A macro-based library could provide this distinction. None of the language
proposals include this, and importantly all of them allow for a contract to
be assumed and thus subvert any future "safety checks" that attempt to handle
out-of-contract behavior more elegantly.

N4820 provides no way to turn checking off locally without bringing in assumption.
P1429 at least provides a way to build an application without assumption of checks,
and macro-based solutions on top of P1607 or a fully-macro based solution would be
able to allow for this kind of distinction with some effort.

A disparate set of macro-based libraries makes it hard to turn on all checking.

N4820 and P1429 allow for this to be done very easily with build modes. P1607
allows for code to subvert this kind of control by providing explicit semantics
for a particular contract that cannot be externally altered.

Signify subset of individual annotations to be consumed by a specific instance
of verification tool

25

0

0

25

It can be argued that the primary intention of axiom was to only provide information
to static analysis tools, so both of the proposals that include that have that here, even though
the wording itself added in undefined behavior to that level, and made no mention of this purpose.

A macro-based facility could integrate with a static analysis tool for this purpose,
but would require tools to choose to support it.

All of the proposals included a conditionally supported custom violation handler
which could be used to test that checks are actually checked at runtime in a unit
test (at least, for noexcept functions). A macro-based facility can accomplish
this as well (and this is the foundation of all negative testing in BDE, see
bsls_asserttest.h
for an example of how that might be implemented).

Importantly, the lack of by-default runtime changing of violation handler behavior
means that a custom violation handler must be written to get the full functionality
needed - when testing that a check is violated, you want the violation handler to
throw so you can recover to do more tests, while when testing anything else you
want a hard error because a bug has been found by your testing.

Have a way to run handler on all combinations of available build modes

25

0

0

0

The proposal in N4820 and all of its descendants prohibited any way to
directly invoke the violation handler. A macro-based facility can expose this
with relative ease (and, for example, BDE does with the macro BSLS_ASSERT_INVOKE).

Only P1429 allows removing any use of an assume-like semantic from contracts.
A macro-based facility can choose to provide that (using various forms of
non-portable or semi-portable implementations). N4820 provides no way to
turn off contract checks without them introducing undefined behavior.

P1607 Allows for this, but also allows for the explicit use of the assume
semantic when desired, which does not allow for altering how it behaves.

The only viable option with the language proposals would be a custom violation
handler that access a diligently updated thread-local recovery path when there
is a violation. There is no innate support for this built into the facilities.

Be able to run checks in a production environment that are considered "cheap"
compared to the expected cost of entering an invalid state

25

75

75

50

N4820 and P1429 both explicitly consider cost as the primary metadata that can
be put on a contract annotation (via a level of default or audit). This
doesn't allow for any more granularity in that expression of cost, but it is

Ensure checks will never be __assume'd/__builtin_assume'd by the compiler as if
they were facts injected into the program (otherwise, if such an assumption
ever failed, I would be running a different program that is not equivalent to
the one I wrote; assumptions can expand the set of possible executions by
injecting facts not otherwise knowable to the compiler)

0

0

50

0

Only P1429 provides the a way to configure contract annotations to never
be assumed.

Be unable to insert code paths (eg. violation handlers) at run time (eg. build
time only)

0

90

90

90

None of the contract facilities allow any runtime alteration of the violation
handler.

Note importantly that an application may choose to install a custom violation
handler that delegates to something that is runtime controllable, so this
restriction is circumventable if the compiler allows for setting a custom
violation handler.

None of the proposals or the language itself support direct integration with a
static analysis tool. Explicit literal semantics, however, could be injected
into code by such a tool to generate computed contract behavior - runtime checking,
optimizations, or otherwise.

Proofs of soundness are certainly aided by stating contract annotations and
asking for validation of those annotations. Tooling will need to catch up
to leverage this and do such proving.

Many such proofs rely on being able to state additional facts that are not easy
to codify as boolean checks, and those are often needed to thoroughly prove
even much simpler predicates, so none of the proposed solutions are complete
for this purpose.

In principle contract checks could be carried forwarded and recorded in binaries
to allow for post-compile verification. It seems unlikely that a non-builtin
facility would be standardized in binary files in such a way.

Basic defensive programming is directly expressable through any of the proposed
contract facilities. Without a language feature, custom libraries must be used
and that is not portable.

Advanced features of contract lifecycle are more difficult to teach when not
directly supported, and none of the proposals provide a complete solution for
that behavior (see P1332 for a broad discussion of
what sorts of lifecycle considerations impact contract use), while only
P1607 provides a way to do so at all at a non-global granularity.

Support the ability for advanced uses of contracts to be distributed across
many different courses in a C++-focused computer science curriculum.

0

50

50

75
/50

N4820 and P1429 provide the least advanced features, but all of the proposals
allow for basic contract use to be done (default level contract annotations)
without any knowledge of the more advanced options that might be available.

Maximize implementation freedom by limiting what is strictly required by the
standard

0

40

40

75

The explicit specification of build modes seems to be seen as highly restrictive
by compiler vendors, and the less specific the standard is about that
aspect of the facility the more this user base seems to be satisfied.

N4820 had many open questions about its specification where it had diverged
from the original contract proposals. The semantic presentation in P1429 and
P1607 sought to be very precise about what was expected of program behavior
for any given contract.

Control whether checks are run based on where they are being called from

0

0

0

0

A macro based facility could build this form of subsetting with a great deal of
effort, though callsite based checking does not seem feasible in any macro based
facility. N4820 and P1429 provide no fine grained control of checks.

The global controls of N4820 and P1429 limit the ability to enforce only those
checks that are trusted, and provide no natural way to mix some continuing contracts with
some non-continuing contracts. (P1429 would allow this by assigning different
semantics to audit and default level contracts, but that would conflict with the
intended distinction between those levels based on cost of checking.)

All of the proposals with a global pluggable violation handler allow this
form of customization, though it is not required by any that a compiler actually
allow the customization of the violation handler.

Be able to narrow individual contract so it fails in testing not in production

25

0

0

50

A P1607 contract can have a macro to control individual semantics and go through
a lifecycle where it is checked or enforced in testing but left ignored in production.
Without global control, this cannot be done with N4820 or P1429.

Remove all but the most important diagnostic overhead from the final binary

25

0

0

0

None of the proposals allow for total removal of logging information from
the generated code, while a macro based facility could support that option.

It would conceivable be possible for link time optimization to recognize that
a violation handler made no use of source information/did no logging and then
it would be able to remove that source information as well, but this would have
significant compile time overhead on a system.

Be able to use contract-like syntax on past or present runtime checkable
language features such as switches, pattern matching, etc. or what might happen
on signed integer overflow, etc. This might allow configuration of trapping,
logging, or assuming in other areas of language UB.

0

0

0

0

None of the proposed solutions began integration with the rest of the standard,
though they would have facilitated it in various ways.

Conclusion

This is a lot of information to digest, so it might help to be able to get
some overview numbers on how the different proposals relate to one another.
There are endless ways to do this, and we make no attempt to be complete in
this analysis, but we will present some approaches that might be
useful.

Simply adding up what percentage of the total value each proposal satisfies
produces the following results:

Proposal

Score

Score W/Macros

N4842

0.000%

22.041%

N4820

31.454%

31.454%

P1429

37.908%

37.908%

P1607

42.321%

43.087%

An alternative is to integrate the results of the initial polls that were
reported in P1995R0, using those to weight
the scores provided above (i.e., the values in the "Score" column in that
paper):

Proposal

Score

Score W/Macros

N4842

0.000%

24.683%

N4820

38.306%

38.306%

P1429

44.703%

44.703%

P1607

48.847%

49.527%

Similarly, we could instead only consider the scores for use cases that had a
score in P1995R0 above a certain threshhold, such as everything with a score over
1.0:

Proposal

Score

Score W/Macros

N4842

0.000%

28.419%

N4820

48.156%

48.156%

P1429

54.359%

54.359%

P1607

57.940%

58.634%

Note that these are not intended to produce a complete measure of those proposals,
but simply as an example of how they might be compared. These totals are not
a good measure of which proposal is intrinsicly better, but the changes to these
totals from any individual proposal should be considered relevant when trying
to understand how all users might benefit from any perticular change.