<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P3639R0: The _BitInt Debate</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in § N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Outdated warning for old specs
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

/******************************************************************************/
/*                                    Body                                    */
/******************************************************************************/

	html {
	}

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;			  /* limit line length to 50em for readability   */
		margin: 0 auto;				/* center text within page                    */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag    */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em; }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small; }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 3;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;	/* Inherit the font family. */
		line-height: 1.2;		/* Keep wrapped headings compact */
		hyphens: manual;		/* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		color: var(--heading-text);
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#profile-and-date {
		/* #profile-and-date is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	border-left: 0.5em solid #DEF;
	border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	 padding: .5em;
	 border: thin solid #ddd;
	 border: thin solid var(--algo-border);
	 border-radius: .5em;
	 margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	 margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	 margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	margin-left: -2em;
	}
	dl.switch {
	padding-left: 2em;
	}
	dl.switch > dt {
	text-indent: -1.5em;
	margin-top: 1em;
	}
	dl.switch > dt + dt {
	margin-top: 0;
	}
	dl.switch > dt::before {
	content: '\21AA';
	padding: 0 0.5em 0 0;
	display: inline-block;
	width: 1em;
	text-align: right;
	line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: inherit;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

	/* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-color: var(--a-active-underline);
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

	/* For autogen numbers, add
	  .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,	.sidefigure img,	figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
		height: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em;
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em; }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > summary > .marker
	{
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	  or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #e0cb52;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	  or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52e052;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary {
		color: hsl(120, 70%, 30%);
		color: var(--noteheading-text);
	}
	/* Add .note::before { content: "Note "; } for autogen label,
	  or use class="marker" to mark up the label in source. */

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 2em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
		border-bottom: 1px solid var(--defrow-border);
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def td.footnote {
		padding-top: 0.6em;
	}
	table.def td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		<table class="data"> highlights structural relationships in a table
		when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		Use class="complex data" for particularly complicated tables --
		(This will draw more lines: busier, but clearer.)

		Use class="long" on table cells with paragraph-like contents
		(This will adjust text alignment accordingly.)
		Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-color: var(--datacell-border);
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		border-top: 1px solid var(--datacell-border);
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		border: 1px solid var(--datacell-border);
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
		vertical-align: baseline;
		text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
	}
	.toc {
		line-height: 1.1em;
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li			{ font-weight: bold;   }
	.toc > li li		 { font-weight: normal; }
	.toc > li li li	  { font-size:   95%;	}
	.toc > li li li li	{ font-size:   90%;	}
	.toc > li li li li li { font-size:   85%;	}

	/* @supports not (display:grid) { */
		.toc > li			{ margin: 1.5rem 0;	}
		.toc > li li		 { margin: 0.3rem 0;	}
		.toc > li li li	  { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}
		.toc > li li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.toc li {
			clear: both;
		}

		:not(li) > .toc			 { margin-left:  5rem; }
		.toc .secno				 { margin-left: -5rem; }
		.toc > li li li .secno	  { margin-left: -7rem; }
		.toc > li li li li .secno	{ margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc			 { margin-left:  4rem; }
			.toc .secno				 { margin-left: -4rem; }
			.toc > li li li			 { margin-left:  1rem; }
			.toc > li li li .secno	  { margin-left: -5rem; }
			.toc > li li li li .secno	{ margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc			 { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno				 { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li			 { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno	  { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno	{ margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			  comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
			border-bottom: 3px solid transparent;
			margin-bottom: -3px;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom-color: #054572;
			border-bottom-color: var(--toclink-underline);
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index	  { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li	{ margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em; }
	ul.index dl	{ margin-top: 0; }
	ul.index dt	{ margin: .2em 0 .2em 20px;}
	ul.index dd	{ margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li a + span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			* http://lea.verou.me/2012/04/background-attachment-local/
			*
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
						top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
						top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style>
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version 4416b18d5, updated Tue Jan 2 15:52:39 2024 -0800" name="generator">
  <link href="https://eisenwave.github.io/cpp-proposals/bitint.html" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="a647e103ab5f7772fe4353b9f8fcfd04df4316ae" name="revision">
<style>
@media (prefers-color-scheme: dark) {
  c-[mb], c-[mi], c-[mh] {
    color: #d59393 !important;
  }
}

th, td, table {
    border: 1px solid var(--text);
}

th, td {
    border-left-width: 0;
    border-right-width: 0;
}
</style>
<style>/* Boilerplate: style-autolinks */
.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}
</style>
<style>/* Boilerplate: style-colors */
/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
</style>
<style>/* Boilerplate: style-counters */
body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}
</style>
<style>/* Boilerplate: style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* Boilerplate: style-md-lists */
/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}
</style>
<style>/* Boilerplate: style-selflinks */
:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* Boilerplate: style-syntax-highlighting */
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: rgba(0, 0, 0, .03); }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P3639R0<br>The <code class="highlight"><c- b>_BitInt</c-></code> Debate</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2025-02-20">2025-02-20</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://eisenwave.github.io/cpp-proposals/bitint.html">https://eisenwave.github.io/cpp-proposals/bitint.html</a>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:janschultke@gmail.com">Jan Schultke</a>
     <dt>Audience:
     <dd>SG6, EWG, LEWG
     <dt>Project:
     <dd>ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
     <dt>Source:
     <dd><a href="https://github.com/Eisenwave/cpp-proposals/blob/master/src/bitint.bs">eisenwave/cpp-proposals</a>
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>An N-bit integer type similar to C’s <code class="highlight"><c- b>_BitInt</c-></code> would provide utility
and give ABI compatibility to C++.
However, should this be a fundamental type or a library type?</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#introduction"><span class="secno">1</span> <span class="content">Introduction</span></a>
    <li>
     <a href="#motivation"><span class="secno">2</span> <span class="content">Motivation</span></a>
     <ol class="toc">
      <li><a href="#computation-beyond-64-bits"><span class="secno">2.1</span> <span class="content">Computation beyond 64 bits</span></a>
      <li><a href="#c-abi-compatibility"><span class="secno">2.2</span> <span class="content">C-ABI compatibility</span></a>
     </ol>
    <li><a href="#scope"><span class="secno">3</span> <span class="content">Scope</span></a>
    <li>
     <a href="#design"><span class="secno">4</span> <span class="content">Design</span></a>
     <ol class="toc">
      <li><a href="#design-introduction"><span class="secno">4.1</span> <span class="content">Introduction</span></a>
      <li><a href="#full-compatibility"><span class="secno">4.2</span> <span class="content">Pro-fundamental: Full compatibility with C constructs</span></a>
      <li><a href="#unsigned-bit-int"><span class="secno">4.3</span> <span class="content">Pro-fundamental: <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-></code></span></a>
      <li><a href="#fundamental-and-class-coexist"><span class="secno">4.4</span> <span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> and <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> don’t coexist nicely</span></a>
      <li><a href="#fundamental-type-needs-to-exist"><span class="secno">4.5</span> <span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> needs to exist in C anyway</span></a>
      <li><a href="#lightweight-compilation"><span class="secno">4.6</span> <span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> is fast to compile</span></a>
      <li><a href="#optimizations"><span class="secno">4.7</span> <span class="content">Pro-fundamental: A pure library implementation is only a temporary solution</span></a>
      <li><a href="#overload-resolution-flexibility"><span class="secno">4.8</span> <span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> offers overload resolution flexibility</span></a>
      <li><a href="#special-deduction-powers"><span class="secno">4.9</span> <span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> could have special deduction powers</span></a>
      <li><a href="#bitint-is-not-portable"><span class="secno">4.10</span> <span class="content">Pro-library: <code class="highlight"><c- b>_BitInt</c-></code> is not portable, but <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> can be</span></a>
      <li><a href="#ill-conceived-integer-features"><span class="secno">4.11</span> <span class="content">Pro-library: <code class="highlight"><c- b>_BitInt</c-></code> inherits many ill-conceived integer features</span></a>
      <li><a href="#implementation-effort"><span class="secno">4.12</span> <span class="content">Pro-library: <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> is easier to implement</span></a>
      <li><a href="#time-frame"><span class="secno">4.13</span> <span class="content">Pro-library: We’ll likely get a portable <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> faster</span></a>
      <li><a href="#teachability"><span class="secno">4.14</span> <span class="content">Pro-library: <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> is easier to teach</span></a>
      <li><a href="#wording-impact"><span class="secno">4.15</span> <span class="content">Pro-library: <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> has much less wording impact and has fewer gotchas</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="introduction"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#introduction"></a></h2>
   <p><a data-link-type="biblio" href="#biblio-n2763" title="Adding a Fundamental Type for N-bit integers">[N2763]</a> introduced the <code class="highlight"><c- b>_BitInt</c-></code> set of types to the C23 standard,
and <a data-link-type="biblio" href="#biblio-n2775" title="Literal suffixes for bit-precise integers">[N2775]</a> further enhanced this feature with literal suffixes. 
For example, this feature may be used as follows:</p>
<pre class="language-cpp highlight"><c- c1>// 8-bit unsigned integer initialized with value 255.</c->
<c- c1>// The literal suffix wb is unnecessary in this case.</c->
<c- b>unsigned</c-> <c- nf>_BitInt</c-><c- p>(</c-><c- mi>8</c-><c- p>)</c-> <c- n>x</c-> <c- o>=</c-> <c- mh>0xFF</c-><c- n>wb</c-><c- p>;</c->
</pre>
   <p>In short, the behavior of these <em>bit-precise integers</em> is as follows:</p>
   <ul>
    <li data-md>
     <p>No integer promotion to <code class="highlight"><c- b>int</c-></code> takes place.</p>
    <li data-md>
     <p>Mixed-signedness comparisons, implicit conversions,
and other permissive feature are supported.</p>
    <li data-md>
     <p>They have lower conversion rank than standard integers,
so an operation between <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>8</c-><c- p>)</c-></code> and <code class="highlight"><c- b>int</c-></code> yields <code class="highlight"><c- b>int</c-></code>,
as does an operation with <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> where <code class="highlight"><c- n>N</c-></code> is the width of <code class="highlight"><c- b>int</c-></code>.
They only have greater conversion rank when their width is greater.</p>
   </ul>
   <p>These semantics make it clear that
bit-precise integers are complementary to the standard integers,
not a replacement,
and not an attempt at fixing all the semantics
that users consider overly permissive about standard integers.</p>
   <p>I propose that C++ should also have an N-bit integer type, possibly as a library type.
This is similarly an attempt at enhancing the language, not at replacing the standard integers.
The C++ types should be ABI-compatible with <code class="highlight"><c- b>_BitInt</c-></code> in C.
Unfortunately, one question blocks any concrete steps:</p>
   <blockquote>
    <p>Should C++ have a fundamental <code class="highlight"><c- b>_BitInt</c-></code> type (possibly exposed via alias template),
or should it have a library type (class template)?</p>
   </blockquote>
   <p>The sole purpose of this proposal is to reach consensus on a direction.</p>
   <h2 class="heading settled" data-level="2" id="motivation"><span class="secno">2. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="computation-beyond-64-bits"><span class="secno">2.1. </span><span class="content">Computation beyond 64 bits</span><a class="self-link" href="#computation-beyond-64-bits"></a></h3>
   <p>On of my previous proposals (<a data-link-type="biblio" href="#biblio-p3140r0" title="std::int_least128_t">[P3140R0]</a>) provides a sea of motivation for
128-bit integers alone. <a data-link-type="biblio" href="#biblio-p3140r0" title="std::int_least128_t">[P3140R0]</a> consistently got the following feedback (from LEWGI and outside):</p>
   <ul>
    <li data-md>
     <p>Yes, 128-bit computation is useful!</p>
    <li data-md>
     <p>What about more than 128 bits?</p>
   </ul>
   <p>Some use cases extend beyond 128 bits, such as 4096-bit (or more)
computation for RSA and other cryptographic algorithms.</p>
   <p>The original <a data-link-type="biblio" href="#biblio-n2763" title="Adding a Fundamental Type for N-bit integers">[N2763]</a> C proposal and C++11 proposals which previously proposed this feature
(<a data-link-type="biblio" href="#biblio-n1692" title="A Proposal to add the Infinite Precision Integer to the C++ Standard Library">[N1692]</a> and <a data-link-type="biblio" href="#biblio-n1744" title="Big Integer Library Proposal for C++0x">[N1744]</a>) contain further motivation. <a data-link-type="biblio" href="#biblio-n4038" title="Proposal for Unbounded-Precision Integer Types">[N4038]</a> also proposed a "big integer", although a dynamically-sized one. <a data-link-type="biblio" href="#biblio-p1889r1" title="C++ Numerics Work In Progress">[P1889R1]</a> (TS) also contained a <code class="highlight"><c- n>wide_integer</c-></code> class template.</p>
   <p>N-bit integers seems to have been suggested and worked on <em>many</em> times in the past decades;
they simply weren’t prioritized by the authors and by WG21 so as to make it into the standard.
I strongly doubt that the usefulness of integer arithmetic beyond 64 bits is contentious,
so it won’t be discussed further here.</p>
   <h3 class="heading settled" data-level="2.2" id="c-abi-compatibility"><span class="secno">2.2. </span><span class="content">C-ABI compatibility</span><a class="self-link" href="#c-abi-compatibility"></a></h3>
   <p>C++ currently has no portable way to call a C function such as:</p>
<pre class="language-c highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-> <c- n>plus</c-><c- p>(</c-><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-> <c- n>x</c-><c- p>,</c-> <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-> <c- n>y</c-><c- p>);</c-> <c- c1>// for any N</c->
</pre>
   <p>We need to call C functions that use <code class="highlight"><c- b>_BitInt</c-></code> <em>somehow</em>.
This could be accomplished either with a fundamental type that has identical ABI,
or with a class type in the style of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>complex</c-></code> or <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-></code> that has identical ABI
despite being a class type.</p>
   <p>This compatibility problem is not a hypothetical concern either; it is an urgent problem.
There are already targets with <code class="highlight"><c- b>_BitInt</c-></code>, supported by major compilers,
and used by C developers:</p>
   <table>
    <tbody>
     <tr>
      <th>Compiler
      <th><code class="highlight"><c- n>BITINT_MAXWIDTH</c-></code>
      <th>Targets
      <th>Languages
     <tr>
      <td>clang 16+
      <td><code class="highlight"><c- mi>8388608</c-></code>
      <td>all
      <td>C &amp; C++
     <tr>
     <tr>
      <td>GCC 14+
      <td><code class="highlight"><c- mi>65535</c-></code>
      <td>64-bit only
      <td>C
     <tr>
     <tr>
      <td>MSVC 19.38
      <td>❌
      <td>❌
      <td>❌
   </table>
   <h2 class="heading settled" data-level="3" id="scope"><span class="secno">3. </span><span class="content">Scope</span><a class="self-link" href="#scope"></a></h2>
   <p>I only propose <em>fixed-width</em>, <em>N-bit</em>, <em>signed and unsigned</em> integers.</p>
   <p>I do not propose dynamically sized, "infinite precision" integers.
Such integers</p>
   <ul>
    <li data-md>
     <p>would not be motivated by C compatibility,</p>
    <li data-md>
     <p>would require discussing allocator-awareness, small object optimizations, and other complex issues, and</p>
    <li data-md>
     <p>they obviously should be done as library types anyway.</p>
   </ul>
   <p>Therefore, they are outside the scope of this proposal.</p>
   <h2 class="heading settled" data-level="4" id="design"><span class="secno">4. </span><span class="content">Design</span><a class="self-link" href="#design"></a></h2>
   <h3 class="heading settled" data-level="4.1" id="design-introduction"><span class="secno">4.1. </span><span class="content">Introduction</span><a class="self-link" href="#design-introduction"></a></h3>
   <p>At this point, there are two plausible implementations:</p>
   <table>
    <tbody>
     <tr>
      <th>Fundamental type
      <th>Library type
     <tr>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- b>size_t</c-> <c- n>N</c-><c- o>></c->
<c- k>using</c-> <c- n>bit_int_t</c-> <c- o>=</c-> <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>);</c->





<c- k>template</c-> <c- o>&lt;</c-><c- b>size_t</c-> <c- n>N</c-><c- o>></c->
<c- k>using</c-> <c- n>bit_uint_t</c-> <c- o>=</c-> <c- b>unsigned</c-> <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>);</c->
</pre>
      <td>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- b>size_t</c-> <c- n>N</c-><c- o>></c->
<c- k>class</c-> <c- nc>bit_int</c-> <c- p>{</c->
  <c- k>private</c-><c- o>:</c->
    <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-> <c- n>_M_value</c-><c- p>;</c->
  <c- k>public</c-><c- o>:</c->
    <c- c1>// constructors, operator overloads, ...</c->
<c- p>};</c->

<c- c1>// analogous for bit_uint wrapping unsigned _BitInt</c->
</pre>
   </table>
   <p class="note" role="note"><span class="marker">Note:</span> These implementations are already valid C++ code
when using the Clang <code class="highlight"><c- b>_BitInt</c-></code> compiler extension.
Without such an extension, a library type can still be implemented in software,
similar to <a href="https://www.boost.org/doc/libs/1_86_0/libs/multiprecision/doc/html/index.html">Boost.Multiprecision</a>'s <code class="highlight"><c- n>cpp_int</c-></code>.</p>
   <p>In terms of ABI and performance (after inlining),
these two approaches should yield the same results.</p>
   <p>It may also be possible to allow the <code class="highlight"><c- n>bit_int_t</c-></code> alias template to alias a
class template, but this inevitably results in implementation divergence.
For example, during overload resolution, <code class="highlight"><c- n>bit_int_t</c-></code> in some implementations would have
user-defined conversion sequences and standard conversion sequences in others.
This is a minefield for users; it really needs to <em>always</em> be fundamental or <em>always</em> a class.</p>
   <p>Also, we could expose the <code class="highlight"><c- b>_BitInt</c-></code> keyword directly, but this would contradict all
previous design:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>_Atomic</c-></code> in C is <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-></code> in C++</p>
    <li data-md>
     <p><code class="highlight"><c- n>_Float128</c-></code> in C is <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>float128_t</c-></code> in C++</p>
    <li data-md>
     <p><code class="highlight"><c- n>complex</c-></code> in C is <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>complex</c-></code> in C++</p>
    <li data-md>
     <p>...</p>
   </ul>
   <p>However, it would be appropriate to define <code class="highlight"><c- b>_BitInt</c-></code> and <code class="highlight"><c- n>_BitUint</c-></code> compatibility macros,
similar to the <code class="highlight"><c- n>_Atomic</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code> C++ macro for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code>:</p>
<pre class="language-cpp highlight"><c- cp>#ifdef __cplusplus</c->
    <c- cp>#define _BitInt(...) std::bit_int&lt;__VA_ARGs__></c->
    <c- cp>#define _BitUint(...) std::bit_uint&lt;__VA_ARGs__></c->
<c- cp>#elifdef __STDC__</c->
    <c- c1>// _BitInt is a keyword, so define only _BitUint</c->
    <c- cp>#define _BitUint(...) typeof(unsigned _BitInt(...))</c->
<c- cp>#else</c->
    <c- cp>#error "owo what's this language?"</c->
<c- cp>#endif</c->
</pre>
   <p>With these secondary concerns out of the way,
we can discuss the big question: fundamental type or library type?</p>
   <p><strong>Disclaimer:</strong> the author has no strong preference.</p>
   <h3 class="heading settled" data-level="4.2" id="full-compatibility"><span class="secno">4.2. </span><span class="content">Pro-fundamental: Full compatibility with C constructs</span><a class="self-link" href="#full-compatibility"></a></h3>
   <p>C permits the use of <code class="highlight"><c- b>_BitInt</c-></code> in situations where a C++ library type couldn’t be used,
including <code class="highlight"><c- k>switch</c-></code>es and bit-fields:</p>
<pre class="language-c highlight"><c- c1>// OK: using an unsigned _BitInt(1) in a switch</c->
<c- k>switch</c-> <c- p>(</c-><c- mi>0u</c-><c- n>wb</c-><c- p>)</c-> <c- c1>// ...</c->
</pre>
<pre class="language-c highlight"><c- k>struct</c-> <c- nc>S</c-> <c- p>{</c->
    <c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-> <c- n>x</c-> <c- o>:</c-> <c- mi>10</c-><c- p>;</c-> <c- c1>// OK, bit-field</c->
<c- p>};</c->
</pre>
   <p>A C++ library type would be less powerful by default,
and <code class="highlight"><c- n>S</c-></code> could not be portably used from C++.</p>
   <p><strong>❌ Counterpoint:</strong> Conditionally-supported exemptions could be made which allow the use of <code class="highlight"><c- n>bit_int</c-></code> in those cases, despite being a class type.
If <code class="highlight"><c- n>bit_int</c-></code> is just a wrapper for <code class="highlight"><c- b>_BitInt</c-></code>, that may be possible,
but obviously not if it’s purely library-implemented.</p>
   <h3 class="heading settled" data-level="4.3" id="unsigned-bit-int"><span class="secno">4.3. </span><span class="content">Pro-fundamental: <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-></code></span><a class="self-link" href="#unsigned-bit-int"></a></h3>
   <p>If there was a <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> and <code class="highlight"><c- b>_BitInt</c-></code> compatibility macro for interop with C,
then <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-></code> obviously wouldn’t work because it expands to <code class="highlight"><c- b>unsigned</c-> <c- n>bit_int</c-></code>.</p>
   <p>Unless we make <code class="highlight"><c- b>unsigned</c-> <c- k>class</c-> <c- nc>bit_int</c-></code> valid (which would be highly unusual for C++),
both C and C++ uses are forced to use the <code class="highlight"><c- n>_BitUint</c-></code> macro for unsigned types.
This seems like needless bullying of C users, who can use <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-></code> just fine.</p>
   <p>With a <code class="highlight"><c- b>_BitInt</c-></code> fundamental type, we could simply define <code class="highlight"><c- b>_BitInt</c-></code> and <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-></code> in C++,
and offer users <code class="highlight"><c- n>bit_int_t</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bit_uint_t</c-></code> alias templates for a nicer spelling.</p>
   <p class="note" role="note"><span class="marker">Note:</span> This problem does not arise for <code class="highlight"><c- n>_Atomic</c-></code> because we can simply say <code class="highlight"><c- n>_Atomic</c-><c- p>(</c-><c- b>unsigned</c-><c- p>)</c-></code>,
which is valid in C with no macros, and expands to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-><c- o>&lt;</c-><c- b>unsigned</c-><c- o>></c-></code> in C++.
It also doesn’t arise for <code class="highlight"><c- n>_Float128</c-></code> or <code class="highlight"><c- n>complex</c-></code> because there are no unsigned floating-point types;
the issue is entirely limited to <code class="highlight"><c- b>_BitInt</c-></code>.</p>
   <h3 class="heading settled" data-level="4.4" id="fundamental-and-class-coexist"><span class="secno">4.4. </span><span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> and <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> don’t coexist nicely</span><a class="self-link" href="#fundamental-and-class-coexist"></a></h3>
   <p>When <code class="highlight"><c- n>bit_int</c-></code>is a class template,
the idiomatic implementation (see above) is to wrap a <code class="highlight"><c- b>_BitInt</c-></code> in that template.
We can expect that in some implementations, both <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> and <code class="highlight"><c- b>_BitInt</c-></code> exist.
Clang already provides <code class="highlight"><c- b>_BitInt</c-></code> in C++ mode.</p>
   <p>This actually leads to some major problems, such as:</p>
<pre class="language-c highlight"><c- c1>// api.h (C/C++ interoperable header)</c->
<c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-> <c- n>gimme_bit_int</c-><c- p>(</c-><c- b>void</c-><c- p>);</c->
</pre>
   <p>With the <code class="highlight"><c- b>_BitInt</c-></code> compatibility macro mentioned previously, include order matters:</p>
<pre class="language-cpp highlight"><c- cp>#include</c-> &lt;cstdint><c- c1> // OK: contains _BitInt compatibility macro</c->
<c- cp>#include</c-> "api.h"<c- c1>   // OK: gimme_bit_int returns class bit_int</c->
</pre>
   <p>OR</p>
<pre class="language-cpp highlight"><c- cp>#include</c-> "api.h"<c- c1>   // OMG: gimme_bit_int returns a non-standard compiler extension</c->
<c- cp>#include</c-> &lt;cstdint><c- c1> // OMG: compatibility macro now makes it impossible to call gimme_bit_int</c->
</pre>
   <p>There is no obvious way to fix this problem:</p>
   <ul>
    <li data-md>
     <p>Predefining <code class="highlight"><c- b>_BitInt</c-></code> in C++ to mean <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> would not be viable because some users
would like a way to access the underlying type in the compiler, not just the wrapper class.</p>
    <li data-md>
     <p>We could define <em>yet another</em> <code class="highlight"><c- n>_CppBitInt</c-></code> macro that expands to either <code class="highlight"><c- b>_BitInt</c-></code> in C, or <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> in C++, but this is much more annoying for C users.</p>
   </ul>
   <p class="note" role="note"><span class="marker">Note:</span> This issue arises less for <code class="highlight"><c- n>_Atomic</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code> because <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> is usually a wrapper class for <code class="highlight"><c- n>T</c-></code>.
There’s no urgent need for <code class="highlight"><c- n>_Atomic</c-></code> as a builtin type to exist.</p>
   <p>On the other hand, if <code class="highlight"><c- n>bit_int_t</c-></code> is merely an alias,
the compiler can simply never define the compatibility macro,
and <code class="highlight"><c- b>_BitInt</c-></code> has the same meaning everywhere, regardless of include order.</p>
   <p><strong>❌ Counterpoint:</strong> If <code class="highlight"><c- o>&lt;</c-><c- n>stdint</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code> defined the compatibility macro,
the user could have fixed this problem by including that header in <code class="highlight"><c- n>api</c-><c- p>.</c-><c- n>h</c-></code>.</p>
   <h3 class="heading settled" data-level="4.5" id="fundamental-type-needs-to-exist"><span class="secno">4.5. </span><span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> needs to exist in C anyway</span><a class="self-link" href="#fundamental-type-needs-to-exist"></a></h3>
   <p>Any postmodern C++ compiler is also a C compiler.
While GCC has a separate frontend for C and C++, the general machinery behind <code class="highlight"><c- b>_BitInt</c-></code> exists already, assuming that C23 is supported.
Therefore, we are almost "throwing away" what’s there already by not guaranteeing that <code class="highlight"><c- b>_BitInt</c-></code> is a library type.</p>
   <p>Furthermore, a library type would deviate at least somewhat from the semantics of <code class="highlight"><c- b>_BitInt</c-></code> in C,
making code between the languages less interchangeable.</p>
   <p><strong>❌ Counterpoint:</strong> See <a href="#bitint-is-not-portable">§ 4.10 Pro-library: _BitInt is not portable, but class bit_int can be</a>.
The minimum <code class="highlight"><c- b>_BitInt</c-></code> support in C23 is highly limited.
We should think about the features we want to provide to C++ developers,
and the guarantees of the C feature are insufficient for that.
Furthermore, it’s unclear when (or if ever) MSVC will support <code class="highlight"><c- b>_BitInt</c-></code>.</p>
   <h3 class="heading settled" data-level="4.6" id="lightweight-compilation"><span class="secno">4.6. </span><span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> is fast to compile</span><a class="self-link" href="#lightweight-compilation"></a></h3>
   <p>A fundamental type would incur very little cost during constant evaluation,
and would not require any template machinery.
This may substantially improve compilation speed as compared to a library type.</p>
   <p><strong>❌ Counterpoint:</strong> Similar to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code>,
if <code class="highlight"><c- n>bit_int</c-></code> is merely a wrapper for a compiler extension type,
this cost may be relatively low.</p>
   <h3 class="heading settled" data-level="4.7" id="optimizations"><span class="secno">4.7. </span><span class="content">Pro-fundamental: A pure library implementation is only a temporary solution</span><a class="self-link" href="#optimizations"></a></h3>
   <p>With current compiler technology,
certain optimizations are only realistic for fundamental types.
For example, an integer division with constant divisor like <code class="highlight"><c- n>x</c-> <c- o>/</c-> <c- mi>10</c-></code> can be turned into a
fixed-point multiplication with <code class="highlight"><c- mi>10</c-></code><sup>-1</sup>:</p>
<pre class="language-asm highlight"><c- c1>; unsigned div10(unsigned x) { return x / 10; }</c->
<c- nf>div10</c-><c- p>(</c-><c- no>unsigned</c-> <c- no>int</c-><c- p>):</c->
        <c- nf>mov</c->     <c- no>ecx</c-><c- p>,</c-> <c- no>edi</c->
        <c- nf>mov</c->     <c- no>eax</c-><c- p>,</c-> <c- mi>3435973837</c->
        <c- nf>imul</c->    <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->         <c- c1>; multiplication with inverse of 10, shifted 35 bits to left</c->
        <c- nf>shr</c->     <c- no>rax</c-><c- p>,</c-> <c- mi>35</c->          <c- c1>; right-shift by 35 bits to correct</c->
        <c- nf>ret</c->
</pre>
   <p class="note" role="note"><span class="marker">Note:</span> Compilers transform like this
because integer division is one of the most expensive arithmetic operations;
it may take over 100 cycles on some architectures. <code class="highlight"><c- k>operator</c-><c- o>/</c-></code> is also tremendously more complicated to implement than <code class="highlight"><c- k>operator</c-><c- o>*</c-></code> in multi-precision libraries.</p>
   <p>That optimization is possible for fundamental types,
but a library-implemented division with <code class="highlight"><c- n>bit_int</c-><c- o>&lt;</c-><c- mi>4096</c-><c- o>></c-></code> could result in hundreds or thousands of IR instructions being emitted,
which the compiler cannot realistically interpret as an integer division.</p>
   <p>A pure library implementation is not transparent to the compiler in the same way that <code class="highlight"><c- b>_BitInt</c-></code> is,
and prohibits many such optimizations. <strong>If we know already that such an implementation is suboptimal and should be replaced eventually,
why make it an option in the first place?</strong> In other words, if <code class="highlight"><c- b>_BitInt</c-></code> <em>must</em> be present for acceptable qualify of implementation,
any portability/ease-of-implementation argument in favor of <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> is refuted.</p>
   <p>At best, <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> would be more portable,
but may optimize dramatically worse when not implemented via intrinsics.
Furthermore, implementers are not interested in having <em>both</em> a library implementation and
builtin implementation.
If one obsoletes the other, that is simply twice the work.</p>
   <p><strong>❌ Counterpoint:</strong> Not every use case requires these optimizations,
and not every use case requires integer division.
Multi-precision libraries have existed long before <code class="highlight"><c- b>_BitInt</c-></code>,
and many clever code transformations can be performed by the user manually.</p>
   <h3 class="heading settled" data-level="4.8" id="overload-resolution-flexibility"><span class="secno">4.8. </span><span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> offers overload resolution flexibility</span><a class="self-link" href="#overload-resolution-flexibility"></a></h3>
   <p>With a library type, it may be difficult to achieve certain behavior in overload resolution.
For example, people have expressed interest in writing overload sets like:</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>f</c-><c- p>(</c-><c- n>bit_int_t</c-><c- o>&lt;</c-><c- mi>32</c-><c- o>></c-><c- p>);</c-> <c- c1>// alias for _BitInt(32)</c->
<c- b>void</c-> <c- nf>f</c-><c- p>(</c-><c- n>bit_int_t</c-><c- o>&lt;</c-><c- mi>16</c-><c- o>></c-><c- p>);</c->
<c- c1>// ...</c->
</pre>
   <p>When called with <code class="highlight"><c- n>bit_int_t</c-><c- o>&lt;</c-><c- mi>20</c-><c- o>></c-></code>, this could prefer to call <code class="highlight"><c- n>f</c-><c- p>(</c-><c- n>bit_int_t</c-><c- o>&lt;</c-><c- mi>32</c-><c- o>></c-><c- p>)</c-></code> because
the conversion is lossless.
With class types, this is difficult/impossible to achieve because user-defined conversion sequences
generally rank the same.</p>
   <p><strong>❌ Counterpoint:</strong> While useful, this idea is novel, and it’s not obvious that we want/expect this.
For example, calling a function with <code class="highlight"><c- b>long</c-></code> does not prefer lossless conversions to <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> over lossy conversions to <code class="highlight"><c- b>int</c-></code>. <code class="highlight"><c- n>bit_int_t</c-></code> is all about being explicit with integer widths,
and highly flexible implicit conversions "don’t fit the theme".</p>
   <h3 class="heading settled" data-level="4.9" id="special-deduction-powers"><span class="secno">4.9. </span><span class="content">Pro-fundamental: <code class="highlight"><c- b>_BitInt</c-></code> could have special deduction powers</span><a class="self-link" href="#special-deduction-powers"></a></h3>
   <p>Multiple committee members have expressed interest in the following construct:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- b>size_t</c-> <c- n>N</c-><c- o>></c->
<c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>bit_int_t</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-><c- p>);</c->

<c- n>foo</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- c1>// OK, calls foo&lt;32> on most platforms</c->
</pre>
   <p>This is obviously impossible with a class template,
but could be permitted with special deduction rules for <code class="highlight"><c- n>bit_int_t</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-></code> when passing a standard integer.
C++ users may perceive this as a case that should <em>intuitively</em> work,
even if it usually doesn’t (similar issues with <code class="highlight"><c- n>optional</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code>).</p>
   <p>Such deduction is also quite useful because</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>foo</c-></code> can accept any signed standard integer and any bit-precise integer,</p>
    <li data-md>
     <p>there are fewer instantiations of <code class="highlight"><c- n>foo</c-></code> if we convert <code class="highlight"><c- b>int</c-></code> to <code class="highlight"><c- n>bit_int_t</c-><c- o>&lt;</c-><c- mi>32</c-><c- o>></c-></code> at the call site, and</p>
    <li data-md>
     <p>it gives <code class="highlight"><c- n>foo</c-></code> quick access to the width, <code class="highlight"><c- n>N</c-></code>, even when <code class="highlight"><c- b>int</c-></code> was passed.</p>
   </ul>
   <p><strong>❌ Counterpoint:</strong> The problem is much more general, and the usual workaround is to rely on CTAD.
For example, if <code class="highlight"><c- n>bit_int</c-></code> was a class template, we could write:</p>
<pre class="language-cpp highlight"><c- n>bit_int</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- o>-></c-> <c- n>bit_int</c-><c- o>&lt;</c-><c- mi>32</c-><c- o>></c-><c- p>;</c-> <c- c1>// deduction guide</c->
<c- c1>// ...</c->
<c- n>foo</c-><c- p>(</c-><c- n>bit_int</c-><c- p>(</c-><c- mi>0</c-><c- p>));</c-> <c- c1>// OK, passes bit_int&lt;32> to foo, and foo deduces as usual</c->
</pre>
   <p>Similar workarounds are common for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>optional</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>span</c-></code>, etc.
Rather than carving out a special case in the deduction rules,
it would be desirable to solve this in general,
which is proposed in <a data-link-type="biblio" href="#biblio-p2998r0" title="CTAD for function parameter types">[P2998R0]</a>.
With that proposal, the motivating example would also work for <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code>.</p>
   <h3 class="heading settled" data-level="4.10" id="bitint-is-not-portable"><span class="secno">4.10. </span><span class="content">Pro-library: <code class="highlight"><c- b>_BitInt</c-></code> is not portable, but <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> can be</span><a class="self-link" href="#bitint-is-not-portable"></a></h3>
   <p>One of the greatest downsides of <code class="highlight"><c- b>_BitInt</c-></code> is that it’s effectively an optional type.
This stems from the fact that only widths of at least <code class="highlight"><c- n>LLONG_WIDTH</c-></code> are guaranteed.</p>
   <p>The purpose of <code class="highlight"><c- n>bit_int</c-></code> is primarily to provide portable multi-precision to C++ developers.
If we are not guaranteed a <code class="highlight"><c- n>BITINT_MAXWIDTH</c-></code> more than 64 bits,
then <code class="highlight"><c- b>_BitInt</c-></code> miserably fails this goal.</p>
   <p>It is also unlikely that this limit could be bumped on the C++ side.
Back when I proposed <a data-link-type="biblio" href="#biblio-p3104r0" title="Bit permutations">[P3104R0]</a> at LEWG, and in prior discussion,
it was often put into question whether 128-bit types should be mandatory.
There were major implementer concerns regarding this,
and I was advised to make the type freestanding-optional.
A fundamental <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code> suffers from the same issue and would receive the same criticism.</p>
   <p>On the contrary, if <code class="highlight"><c- n>bit_int</c-></code> is allowed to be library-implemented,
these concerns vanish,
and the type can be freestanding-mandatory with a very high maximum width.
After all, the library implementation is basically a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code> with some operator overloads.</p>
   <p><strong>❌ Counterpoint:</strong> This concern is mostly theoretical.
There’s little motivation for an implementation to only provide <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>64</c-><c- p>)</c-></code>.
In practice, GCC and Clang already provide <code class="highlight"><c- b>_BitInt</c-></code> with very large width (<a href="#c-abi-compatibility">§ 2.2 C-ABI compatibility</a>),
although GCC does not yet make this type available on 32-bit targets.</p>
   <h3 class="heading settled" data-level="4.11" id="ill-conceived-integer-features"><span class="secno">4.11. </span><span class="content">Pro-library: <code class="highlight"><c- b>_BitInt</c-></code> inherits many ill-conceived integer features</span><a class="self-link" href="#ill-conceived-integer-features"></a></h3>
   <p><code class="highlight"><c- b>_BitInt</c-></code> in C inherits many ill-conceived, extremely permissive features
from other standard integers.
For example, with <code class="highlight"><c- b>_BitInt</c-></code>,</p>
   <ul>
    <li data-md>
     <p>mixed-signedness implicit conversions can take place, such as in <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>5</c-><c- p>)</c-> <c- o>+</c-> <c- b>unsigned</c-></code>,</p>
    <li data-md>
     <p>mixed-signedness comparisons are also possible, and</p>
    <li data-md>
     <p>narrowing conversions from e.g. <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-></code> to <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>8</c-><c- p>)</c-></code> are permitted.</p>
   </ul>
   <p>A particular pitfall is that <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> with <code class="highlight"><c- n>N</c-> <c- o>&lt;=</c-> <c- n>INT_WIDTH</c-></code> has lower conversion rank
than <code class="highlight"><c- b>int</c-></code>, so <code class="highlight"><c- n>x</c-> <c- o>+</c-> <c- mi>1</c-></code> changes signedness,
and <code class="highlight"><c- n>x</c-> <c- o>*</c-> <c- b>int</c-><c- p>(</c-><c- d>/* large value */</c-><c- p>)</c-></code> may overflow despite <code class="highlight"><c- n>x</c-></code> being an unsigned bit-precise integer.</p>
   <p>With C++26’s focus on safety, it is highly questionable whether this behavior should be carried
over into C++.
A library type could simply start a safer design from scratch,
and only provide desirable overloads for <code class="highlight"><c- k>operator</c-><c- o>+</c-></code> etc.</p>
   <p><strong>❌ Counterpoint:</strong> Such misuses could be inherited from C,
but diagnosed with Profiles, assuming those will be in C++29.
Furthermore, <code class="highlight"><c- b>_BitInt</c-></code> in C++ could be restricted
so that some of this behavior is disallowed (ill-formed).</p>
   <h3 class="heading settled" data-level="4.12" id="implementation-effort"><span class="secno">4.12. </span><span class="content">Pro-library: <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> is easier to implement</span><a class="self-link" href="#implementation-effort"></a></h3>
   <p>There are already numerous implementations of multi-precision integers for C++,
such as Boost.Multiprecision.
These have been tried and tested over many years, and can be integrated into the standard library.
If a pure library implementation is permitted,
the burden is lowered from having to implement N-bit operation codegen in a compiler,
to implementing the underlying <code class="highlight"><c- n>__builtin_add_overflow</c-></code> et al. intrinsics used in the
standard library (or other library), for a given architecture.</p>
   <p>Standardizing <code class="highlight"><c- b>_BitInt</c-></code> as a fundamental type also forces the implementation to set an ABI
for this type in stone.
Doing so is of much greater consequence than deciding on an ABI for <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code>, where,
if push comes to shove, an ABI break is more plausible than for a fundamental C type.</p>
   <p>Even the frontend implementation requires some effort, such as</p>
   <ul>
    <li data-md>
     <p>parsing <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> and <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> with appropriate diagnostics,</p>
    <li data-md>
     <p>template argument deduction of <code class="highlight"><c- n>N</c-></code> from <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code>,</p>
    <li data-md>
     <p>new rules for overload resolution, conversion ranks, etc.,</p>
    <li data-md>
     <p>...</p>
   </ul>
   <p><strong>❌ Counterpoint:</strong> The implementation effort is non-trivial regardless,
especially if the implementation has to be of high quality/performance.
Even a library implementation needs to exploit architectural knowledge in the form of
intrinsics or inline assembly.</p>
   <h3 class="heading settled" data-level="4.13" id="time-frame"><span class="secno">4.13. </span><span class="content">Pro-library: We’ll likely get a portable <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> faster</span><a class="self-link" href="#time-frame"></a></h3>
   <p>At this point, it is unclear when (or if ever) Microsoft will implement <code class="highlight"><c- b>_BitInt</c-></code>.
It is not even clear whether 128-bit integer integers are planned,
let alone 4096-bit support or higher.
Barely any C23 core features are supported at this time.
On the contrary, the MSVC STL is largely on par with other standard libraries regarding
postmodern C++ support.</p>
   <p>Ultimately, we want C++ developers to receive a portable feature soon,
and requiring a fundamental type gets us this feature much later or never,
depending on how MSVC and possible future compilers prioritize <code class="highlight"><c- b>_BitInt</c-></code>.</p>
   <p>Note that a pure library implementation of <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> can be replaced with a wrapper for
a built-in <code class="highlight"><c- b>_BitInt</c-></code> type at a later date, convenient for implementations.
The option to have a pure library implementation gets the foot in the door.</p>
   <p><strong>❌ Counterpoint:</strong> This point becomes less significant once all compilers support <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> with large <code class="highlight"><c- n>N</c-></code>.
Maybe this makes for a less timeless design.</p>
   <h3 class="heading settled" data-level="4.14" id="teachability"><span class="secno">4.14. </span><span class="content">Pro-library: <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> is easier to teach</span><a class="self-link" href="#teachability"></a></h3>
   <p>Generally speaking, new fundamental types introduce much more complexity for C++ users than
library types.
For example, <code class="highlight"><c- b>_BitInt</c-></code> is not subject to integer promotion, but subject to integer conversion.
Assuming we carry this over into C++, this has surprising consequences such as:</p>
<pre class="language-cpp highlight"><c- c1>// Currently valid overload set which covers all existing signed standard integers.</c->
<c- b>void</c-> <c- nf>awoo</c-><c- p>(</c-><c- b>int</c-><c- p>);</c->
<c- b>void</c-> <c- nf>awoo</c-><c- p>(</c-><c- b>long</c-><c- p>);</c->
<c- b>void</c-> <c- nf>awoo</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-><c- p>);</c->
</pre>
   <p><code class="highlight"><c- n>awoo</c-></code> can be called with any existing signed standard integer,
but the overload set is insufficient for <code class="highlight"><c- b>_BitInt</c-></code> because none of these functions are a best match.</p>
   <p>On the contrary, With a <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code>, this behavior would be glaringly obvious,
and such a class type would presumably not have a user-defined conversion function to integers
anyway.
In practice, users can simply look at cppreference and find all the constructors, operator
overloads, and quickly understand how <code class="highlight"><c- n>bit_int</c-></code> works.</p>
   <p><strong>❌ Counterpoint:</strong> This point is somewhat subjective and speculative.
Either way, there will be new sets of types in the language, and new users will have to learn
about them if they want to use them.</p>
   <h3 class="heading settled" data-level="4.15" id="wording-impact"><span class="secno">4.15. </span><span class="content">Pro-library: <code class="highlight"><c- k>class</c-> <c- nc>bit_int</c-></code> has much less wording impact and has fewer gotchas</span><a class="self-link" href="#wording-impact"></a></h3>
   <p>Merely introducing a new class type to the language has no impact on the core wording
whatsoever, and is absolutely guaranteed not to introduce wording bugs and subtle ABI breaks.</p>
   <p>To name one potential issue, <code class="highlight"><i><c- n>IOTA</c-><c- o>-</c-><c- n>DIFF</c-><c- o>-</c-><c- n>T</c-></i><c- p>(</c-><c- n>W</c-><c- p>)</c-></code> for <code class="highlight"><c- n>W</c-> <c- o>=</c-> <c- b>long</c-> <c- b>long</c-></code> is defined as
(<a href="https://eel.is/c++draft/range.iota.view#1.2">[range.iota.view]</a>):</p>
   <blockquote>
    <p>a signed integer type of width greater than the width of <strong>W</strong> if such a type exists.</p>
   </blockquote>
   <p>If we consider <code class="highlight"><c- b>_BitInt</c-></code> to be a signed integer type (why wouldn’t it be?),
this breaks ABI because we are redefining a <code class="highlight"><c- n>difference_type</c-></code>.
This bug is very similar to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code>, which has prevented the implementation from
providing extended 128-bit integers without an ABI break.</p>
   <p>This <code class="highlight"><c- n>iota_view</c-></code> issue can be mitigated by requesting that only <em>standard</em> signed integers
are considered in that bullet, not <em>all</em> signed integers.
However, it demonstrates that adding an entirely new set of fundamental integer types
comes with great wording impact.</p>
   <p>Is resolving all these problems a good use of committee time?
Adding a new class to the standard library <em>just works</em>.</p>
   <p><strong>❌ Counterpoint:</strong> This is putting the cart before the horse.
While committee time is a valuable resource, wording impact should not dictate design.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don't scroll to compensate for the ToC if we're above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don't know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn't exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn't standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don't have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we're at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can't find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-n1692">[N1692]
   <dd>M.J. Kronenburg. <a href="https://wg21.link/n1692"><cite>A Proposal to add the Infinite Precision Integer to the C++ Standard Library</cite></a>. 1 July 2004. URL: <a href="https://wg21.link/n1692">https://wg21.link/n1692</a>
   <dt id="biblio-n1744">[N1744]
   <dd>Michiel Salters. <a href="https://wg21.link/n1744"><cite>Big Integer Library Proposal for C++0x</cite></a>. 13 January 2005. URL: <a href="https://wg21.link/n1744">https://wg21.link/n1744</a>
   <dt id="biblio-n2763">[N2763]
   <dd>Aaron Ballman; et al. <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf"><cite>Adding a Fundamental Type for N-bit integers</cite></a>. URL: <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf">https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf</a>
   <dt id="biblio-n2775">[N2775]
   <dd>Aaron Ballman; Melanie Blower. <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf"><cite>Literal suffixes for bit-precise integers</cite></a>. URL: <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf">https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf</a>
   <dt id="biblio-n4038">[N4038]
   <dd>Pete Becker. <a href="https://wg21.link/n4038"><cite>Proposal for Unbounded-Precision Integer Types</cite></a>. 23 May 2014. URL: <a href="https://wg21.link/n4038">https://wg21.link/n4038</a>
   <dt id="biblio-p1889r1">[P1889R1]
   <dd>Alexander Zaitsev, Antony Polukhin. <a href="https://wg21.link/p1889r1"><cite>C++ Numerics Work In Progress</cite></a>. 27 December 2019. URL: <a href="https://wg21.link/p1889r1">https://wg21.link/p1889r1</a>
   <dt id="biblio-p2998r0">[P2998R0]
   <dd>James Touton. <a href="https://wg21.link/p2998r0"><cite>CTAD for function parameter types</cite></a>. 15 October 2024. URL: <a href="https://wg21.link/p2998r0">https://wg21.link/p2998r0</a>
   <dt id="biblio-p3104r0">[P3104R0]
   <dd>Jan Schultke. <a href="https://wg21.link/p3104r0"><cite>Bit permutations</cite></a>. 26 January 2024. URL: <a href="https://wg21.link/p3104r0">https://wg21.link/p3104r0</a>
   <dt id="biblio-p3140r0">[P3140R0]
   <dd>Jan Schultke. <a href="https://wg21.link/p3140r0"><cite>std::int_least128_t</cite></a>. 14 February 2024. URL: <a href="https://wg21.link/p3140r0">https://wg21.link/p3140r0</a>
  </dl>