<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2022-08-08" />
  <title>Make assert() macro user friendly for C and C++</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.csl-block{margin-left: 1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      .sourceCode { overflow: visible; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
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;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Make assert() macro user
friendly for C and C++</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2264R4 (WG21)/ (was N2829, N2621) (WG14)</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2022-08-08</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      WG21 - Library Evolution ( WG14 adopted for C23 )<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Peter Sommerlad<br>&lt;<a href="mailto:peter.cpp@sommerlad.ch" class="email">peter.cpp@sommerlad.ch</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#history" id="toc-history"><span class="toc-section-number">1</span> History<span></span></a>
<ul>
<li><a href="#r4-revision" id="toc-r4-revision"><span class="toc-section-number">1.1</span> R4 revision<span></span></a></li>
<li><a href="#r3-revision" id="toc-r3-revision"><span class="toc-section-number">1.2</span> R3 revision<span></span></a></li>
<li><a href="#r2-revision" id="toc-r2-revision"><span class="toc-section-number">1.3</span> R2 revision<span></span></a></li>
<li><a href="#r1-revision" id="toc-r1-revision"><span class="toc-section-number">1.4</span> R1 revision<span></span></a></li>
<li><a href="#r0-initial-revision" id="toc-r0-initial-revision"><span class="toc-section-number">1.5</span> R0 initial
revision<span></span></a></li>
</ul></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction<span></span></a></li>
<li><a href="#remedy" id="toc-remedy"><span class="toc-section-number">3</span> Remedy<span></span></a></li>
<li><a href="#impact-on-existing-code" id="toc-impact-on-existing-code"><span class="toc-section-number">4</span> Impact on existing
code<span></span></a></li>
<li><a href="#potential-liabilities-of-the-proposed-change" id="toc-potential-liabilities-of-the-proposed-change"><span class="toc-section-number">5</span> Potential liabilities of the
proposed change<span></span></a>
<ul>
<li><a href="#ndebug-will-allow-assert-without-any-arguments" id="toc-ndebug-will-allow-assert-without-any-arguments"><span class="toc-section-number">5.1</span> NDEBUG will allow <code class="sourceCode cpp"><span class="ot">assert</span><span class="op">()</span></code>
without any arguments<span></span></a></li>
<li><a href="#contracts-will-make-the-50-year-old-assert-macro-obsolete-and-to-not-suffer-from-the-macro-parsing-issue." id="toc-contracts-will-make-the-50-year-old-assert-macro-obsolete-and-to-not-suffer-from-the-macro-parsing-issue."><span class="toc-section-number">5.2</span> “Contracts will make the 50 year
old assert macro obsolete and to not suffer from the macro parsing
issue.”<span></span></a></li>
<li><a href="#using-the-comma-operator-can-be-misapplied-to-an-always-true-assert-if-its-arguments-are-formed-as-for-static_assertconditionreason.-this-will-make-wrong-code-compile-that-today-doesnt." id="toc-using-the-comma-operator-can-be-misapplied-to-an-always-true-assert-if-its-arguments-are-formed-as-for-static_assertconditionreason.-this-will-make-wrong-code-compile-that-today-doesnt."><span class="toc-section-number">5.3</span> <em>“Using the comma operator can
be misapplied to an always true assert, if its arguments are formed as
for
<code class="sourceCode default">static_assert(condition,reason)</code>.
This will make wrong code compile that today
doesn’t.”</em><span></span></a></li>
<li><a href="#teachability-is-not-improved-because-we-can-teach-use-extra-parentheses-today." id="toc-teachability-is-not-improved-because-we-can-teach-use-extra-parentheses-today."><span class="toc-section-number">5.4</span> “Teachability is not improved,
because we can teach use extra parentheses today.”<span></span></a></li>
<li><a href="#will-changing-static_assertconditionreason-to-assertconditionreason-compile-and-silently-make-the-assert-never-fire.-see-2-above" id="toc-will-changing-static_assertconditionreason-to-assertconditionreason-compile-and-silently-make-the-assert-never-fire.-see-2-above"><span class="toc-section-number">5.5</span> Will changing <code class="sourceCode default">static_assert(condition,&quot;reason&quot;)</code>
to <code class="sourceCode default">assert(condition,&quot;reason&quot;)</code>
compile and silently make the assert never fire. (see 2
above)<span></span></a></li>
<li><a href="#do-you-have-implementation-experience" id="toc-do-you-have-implementation-experience"><span class="toc-section-number">5.6</span> Do you have implementation
experience?<span></span></a></li>
<li><a href="#why-dont-you-use-bool__va_args__-to-prevent-comma-operator-usage" id="toc-why-dont-you-use-bool__va_args__-to-prevent-comma-operator-usage"><span class="toc-section-number">5.7</span> Why don’t you use
<code class="sourceCode default">bool(__VA_ARGS__)</code> to prevent
comma operator usage?<span></span></a></li>
<li><a href="#why-dont-you-use-assertarg__va_args__-to-prevent-zero-arguments-for-the-ndebug-case" id="toc-why-dont-you-use-assertarg__va_args__-to-prevent-zero-arguments-for-the-ndebug-case"><span class="toc-section-number">5.8</span> Why don’t you use
<code class="sourceCode default">assert(arg,__VA_ARGS__)</code> to
prevent zero arguments for the NDEBUG case?<span></span></a></li>
<li><a href="#to-be-discussed" id="toc-to-be-discussed"><span class="toc-section-number">5.9</span> To be
discussed<span></span></a></li>
</ul></li>
<li><a href="#wording-for-c" id="toc-wording-for-c"><span class="toc-section-number">6</span> Wording for C++<span></span></a>
<ul>
<li><a href="#the-assert-macro-assertions.assert" id="toc-the-assert-macro-assertions.assert"><span class="toc-section-number">6.0.1</span> 19.3.2 The
<code class="sourceCode default">assert</code> macro
[assertions.assert]<span></span></a></li>
</ul></li>
<li><a href="#wording-for-c-if-c-is-changed" id="toc-wording-for-c-if-c-is-changed"><span class="toc-section-number">7</span> Wording for C++ if C is
changed<span></span></a>
<ul>
<li><a href="#the-assert-macro-assertions.assert-1" id="toc-the-assert-macro-assertions.assert-1"><span class="toc-section-number">7.0.1</span> 19.3.2 The
<code class="sourceCode default">assert</code> macro
[assertions.assert]<span></span></a></li>
</ul></li>
<li><a href="#wording-for-c-1" id="toc-wording-for-c-1"><span class="toc-section-number">8</span> Wording for C<span></span></a>
<ul>
<li><a href="#program-diagnostics" id="toc-program-diagnostics"><span class="toc-section-number">8.0.1</span> 7.2.1 Program
diagnostics<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements" id="toc-acknowledgements"><span class="toc-section-number">9</span>
Acknowledgements<span></span></a></li>
<li><a href="#example-implementation-bsd-license-on-macos" id="toc-example-implementation-bsd-license-on-macos"><span class="toc-section-number">10</span> Example implementation (BSD license
on MacOS)<span></span></a>
<ul>
<li><a href="#c-test-cases" id="toc-c-test-cases"><span class="toc-section-number">10.1</span> C test
cases<span></span></a></li>
<li><a href="#c-test-cases-1" id="toc-c-test-cases-1"><span class="toc-section-number">10.2</span> C++ test
cases<span></span></a></li>
</ul></li>
</ul>
</div>
<h1 data-number="1" id="history"><span class="header-section-number">1</span> History<a href="#history" class="self-link"></a></h1>
<h2 data-number="1.1" id="r4-revision"><span class="header-section-number">1.1</span> R4 revision<a href="#r4-revision" class="self-link"></a></h2>
<p>Corrected document ID within document. Changes wrt WG14 Adoption (see
WG14 N2941 and N3047).</p>
<h2 data-number="1.2" id="r3-revision"><span class="header-section-number">1.2</span> R3 revision<a href="#r3-revision" class="self-link"></a></h2>
<ul>
<li>provide corrected <code class="sourceCode default">assert.h</code>
from usage experience as system header on Macos Mojave. Compiled many
homebrew bundles successfully with it (this is how I found my
bugs).</li>
<li>provide test case code showing C and C++ use with arguments that
contain commas.</li>
<li>resurrect minimal C++ wording change, to show what needs to be done,
if WG14 adopts proposed changes to
<code class="sourceCode default">assert.h</code></li>
</ul>
<h2 data-number="1.3" id="r2-revision"><span class="header-section-number">1.3</span> R2 revision<a href="#r2-revision" class="self-link"></a></h2>
<ul>
<li>add this history</li>
<li>provide a new C document number</li>
<li>added a to-be-discussed in section 5</li>
</ul>
<h2 data-number="1.4" id="r1-revision"><span class="header-section-number">1.4</span> R1 revision<a href="#r1-revision" class="self-link"></a></h2>
<ul>
<li>added implementation experiment with local system header</li>
<li>provide C++-only wording to decouple C from C++ progress</li>
<li>provide discussion/replies to discussion in working groups in
section 5</li>
</ul>
<h2 data-number="1.5" id="r0-initial-revision"><span class="header-section-number">1.5</span> R0 initial revision<a href="#r0-initial-revision" class="self-link"></a></h2>
<p>was discussed by WG21 SG22 (C/C++ liason), WG21 LEWG and WG14</p>
<h1 data-number="2" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>The <code class="sourceCode default">assert()</code> macro, being a
macro, is not very beginner friendly in C++, because the preprocessor
only uses parenthesis for pairing and none of the other structuring
syntax of C++, such as template angle brackets, or curly braces. This
makes it user unfriendly in a C++ context, requiring an extra pair of
parentheses, if the expression used, incorporates a comma.</p>
<p>Shafik Yaghmour presented the following C++ code in one of his
Twitter quizzes <a href="https://twitter.com/shafikyaghmour/status/1329952764068126722"><code class="sourceCode default">tweet</code></a>
demonstrating the weakness.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;cassert&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;type_traits&gt;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> Int<span class="op">=</span><span class="dt">int</span>;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a> <span class="ot">assert</span><span class="op">(</span>std<span class="op">::</span>is_same<span class="op">&lt;</span><span class="dt">int</span>,Int<span class="op">&gt;::</span>value<span class="op">)</span>; <span class="co">// a surprisig compile error</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>One of the twitter <a href="https://twitter.com/_Static_assert/status/1332368539991347200?ref_src=twsrc%5Etfw"><code class="sourceCode default">responses (by @_Static_assert)</code></a>
to the tweet mentioned above, even provided a definition of the assert
macro that actually is a primitive implementation of what I propose in
this paper:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp"> </span><span class="op">((</span><span class="ot">__VA_ARGS__</span><span class="op">)?(</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">:</span>std<span class="op">::</span>abort<span class="op">())</span></span></code></pre></div>
<p>In C one needs to be a bit more sophisticated to trigger such a
compile error, but nevertheless the C syntax allows for such expression
that include commas that are not protected from the preprocessor by
parentheses as given by Shafik’s <a href="https://godbolt.org/z/4Wqd66"><code class="sourceCode default">godbolt example</code></a></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;assert.h&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dt">int</span><span class="op">[</span><span class="dv">2</span><span class="op">]){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}[</span><span class="dv">0</span><span class="op">])</span>; <span class="co">// compile error</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> A <span class="op">{</span><span class="dt">int</span> x,y;<span class="op">}</span>;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="kw">struct</span> A<span class="op">){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}.</span>x<span class="op">)</span>; <span class="co">// compile error</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The current C standard does not even sanction such a compile error to
my knowledge, when <code class="sourceCode default">NDEBUG</code> is not
defined, since it specifies the assert macro to be able to take an
expression of <em>scalar type</em> which the above non-compiling
examples with a comma, I think, are (int in both cases). The C++
standard and working paper refer to C’s definition of the
<code class="sourceCode default">assert</code> macro in that
respect.</p>
<h1 data-number="3" id="remedy"><span class="header-section-number">3</span> Remedy<a href="#remedy" class="self-link"></a></h1>
<p>This deficit in the single argument macro assert() seems to be very
easy to mitigate by providing a
<code class="sourceCode default">__VA_ARGS__</code> version of the macro
using ellipsis (<code class="sourceCode default">...</code>) as the
parameter.</p>
<p>There exist the option to specify the assert macro with an extra name
parameter and then the ellipsis. However, I do think this not only
complicates its implementation it also complicates its wording, as well
as this feature allowing a single argument macro call is not available
for C++ versions pre C++20. If the
<code class="sourceCode default">assert</code> macro is called without
any arguments this will lead to a compile error as it does today. The
only difference might be the issued compiler diagnostic</p>
<p>A DIY version can be defined that provides the additional parenthesis
needed for the <code class="sourceCode default">assert()</code> macro of
today:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define Assert</span><span class="op">(...)</span><span class="pp"> </span><span class="ot">assert</span><span class="op">((</span><span class="ot">__VA_ARGS__</span><span class="op">))</span></span></code></pre></div>
<p>However, that would be required to be defined and used throughout a
project and such is less user friendly than have the standard facility
provide such flexibility.</p>
<p>Note: the following <em>feature</em> was removed, due to discussions
of the R0/N2621 version of this paper. And a mechanism is enforced to
detect misuse of the comma operator.</p>
<p><del>In addition the variable argument macro version of assert would
allow additional diagnostics text, by using the comma operator, such as
in</del></p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="st">&quot;this cannot be true&quot;</span>, <span class="op">-</span><span class="fl">0.0</span><span class="op">)</span>;</span></code></pre></div>
<p><del>which would otherwise also be required to use an extra pair of
parentheses.</del></p>
<p>However, such additional diagnostic strings are better spelled using
the <code class="sourceCode default">&amp;&amp;</code> conjugation
(thanks to Martin Hořeňovský )</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">assert</span><span class="op">(</span>idx <span class="op">&lt;</span> vec<span class="op">.</span>size<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="st">&quot;idx is out of range&quot;</span><span class="op">)</span>;</span></code></pre></div>
<p>The proposed solution prevents the use of the comma operator on
top-level, to avoid accidentally creating always true assertions like
the following:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>x <span class="op">&gt;</span> <span class="dv">0</span> , <span class="st">&quot;x was not greater than zero&quot;</span><span class="op">)</span>;</span></code></pre></div>
<p>Those assertions can result from converting a <code class="sourceCode cpp"><span class="kw">static_assert</span></code> to a
regular assert.</p>
<h1 data-number="4" id="impact-on-existing-code"><span class="header-section-number">4</span> Impact on existing code<a href="#impact-on-existing-code" class="self-link"></a></h1>
<p>On my Mac I changed the system’s
<code class="sourceCode default">assert.h</code> header to provide
variadic macro versions of the
<code class="sourceCode default">assert(...)</code> macro for C++ and C.
I implemented a mechanism to prevent unintentional use of the comma
operator within the macro’s arguments. I compiled various software
(including LLVM) on my Mac using that changed system header and did not
encounter problems, beyond my own bugs that I made in that change. The
latter is, why I know that the adapted header was actually used.</p>
<p>When reading the C specification of the semantics of assert() one
could argue that the macro parameter should already have been variadic,
because even in C one can form a scalar expression with a comma that
doesn’t require balanced parentheses. So WG14 and WG21 might even
consider to apply this change as a backward defect fix to previous
revisions of the standards. The argument that the existing spec of C11
was broken with that respect was accepted by WG14 and thus the
definition of <code class="sourceCode default">assert(...)</code>
accepted for C23.</p>
<h1 data-number="5" id="potential-liabilities-of-the-proposed-change"><span class="header-section-number">5</span> Potential liabilities of the
proposed change<a href="#potential-liabilities-of-the-proposed-change" class="self-link"></a></h1>
<p>While sharing a preview of this document and during review of the
initial revision in the various online study and work groups addressed,
I got several people commenting on it. While some were in favor, there
were raised some potential issues that I’d like to share paraphrased
below.</p>
<p>There were liabilities that I do not list, because they are already
addressed by the initial revision of this paper</p>
<ul>
<li>breaking compatibility with C: This is not planned, see R0 version
of this paper, however, this revision (R1/2) provide a C++-only wording
to enable decoupling progress in WG14 and WG21</li>
<li>wording only addresses the NDEBUG case (for C++): I provide now more
context, the wording changes required for C++ definitely only relevant
with the NDEBUG case. However, if desired, we could split adoption of C
and C++ in parallel, but providing full assert specification in C++,
which is done now (in R1/2).</li>
</ul>
<h2 data-number="5.1" id="ndebug-will-allow-assert-without-any-arguments"><span class="header-section-number">5.1</span> NDEBUG will allow <code class="sourceCode cpp"><span class="ot">assert</span><span class="op">()</span></code>
without any arguments<a href="#ndebug-will-allow-assert-without-any-arguments" class="self-link"></a></h2>
<p>As specified at the moment, the NDEBUG version of <code class="sourceCode cpp"><span class="ot">assert</span><span class="op">(...)</span></code>
will swallow any macro arguments, even if there is none. I believe this
is a small price to pay, since any invalid code that matches a macro
argument is allowed today anyway if NDEBUG is set. A more sophisticated
specification could use the more-than-one argument variadic macro syntax
mentioned below.</p>
<h2 data-number="5.2" id="contracts-will-make-the-50-year-old-assert-macro-obsolete-and-to-not-suffer-from-the-macro-parsing-issue."><span class="header-section-number">5.2</span> “Contracts will make the 50
year old assert macro obsolete and to not suffer from the macro parsing
issue.”<a href="#contracts-will-make-the-50-year-old-assert-macro-obsolete-and-to-not-suffer-from-the-macro-parsing-issue." class="self-link"></a></h2>
<p>While I appreciate the notion of contracts, I and others think it is
worthwhile to make <code class="sourceCode default">assert()</code> more
beginner friendly, since professional code bases will have their own
versions of precondition checking stuff anyway. While beginners can be
shown a universally available feature that is identical to C and could
even be ported to older revisions of the standards without breaking
existing code.</p>
<h2 data-number="5.3" id="using-the-comma-operator-can-be-misapplied-to-an-always-true-assert-if-its-arguments-are-formed-as-for-static_assertconditionreason.-this-will-make-wrong-code-compile-that-today-doesnt."><span class="header-section-number">5.3</span> <em>“Using the comma operator
can be misapplied to an always true assert, if its arguments are formed
as for
<code class="sourceCode default">static_assert(condition,reason)</code>.
This will make wrong code compile that today doesn’t.”</em><a href="#using-the-comma-operator-can-be-misapplied-to-an-always-true-assert-if-its-arguments-are-formed-as-for-static_assertconditionreason.-this-will-make-wrong-code-compile-that-today-doesnt." class="self-link"></a></h2>
<p><strong>This problem is prevented by my implementation, unless
<code class="sourceCode default">NDEBUG</code> is defined, either by
defining an identity function taking a single argument (in C) or by
using <code class="sourceCode default">bool(__VA_ARGS__)</code>. I do
not think we need to update the specification with that
respect.</strong></p>
<h2 data-number="5.4" id="teachability-is-not-improved-because-we-can-teach-use-extra-parentheses-today."><span class="header-section-number">5.4</span> “Teachability is not improved,
because we can teach use extra parentheses today.”<a href="#teachability-is-not-improved-because-we-can-teach-use-extra-parentheses-today." class="self-link"></a></h2>
<p>I have a lot of experience in teaching C++ and i believe that using
those extra parenthesis is teachable when interacting with students
having such a problem, but the surprise and the time it takes to
remember this remedy when it hits, is worth the effort to make it more
user friendly. Especially, since assert() tends to be used as a unit
testing framework substitute and thus in C++ the use of templates or
initializer lists happens frequently, at least in tests I write.</p>
<p>During discussions in WG21/SG22 and WG14 the following issues were
raised:</p>
<h2 data-number="5.5" id="will-changing-static_assertconditionreason-to-assertconditionreason-compile-and-silently-make-the-assert-never-fire.-see-2-above"><span class="header-section-number">5.5</span> Will changing <code class="sourceCode default">static_assert(condition,&quot;reason&quot;)</code>
to <code class="sourceCode default">assert(condition,&quot;reason&quot;)</code>
compile and silently make the assert never fire. (see 2 above)<a href="#will-changing-static_assertconditionreason-to-assertconditionreason-compile-and-silently-make-the-assert-never-fire.-see-2-above" class="self-link"></a></h2>
<p>ad 2/4. My implementation prevents the use of the comma operator, so
the point 2 is clearly taken. Any decent optimizer should also eliminate
any call to the inline identity function that is only there to prevent
inadvertent use of the comma operator or missing to provide an argument.
However, my implementation provides no protection against using zero
arguments or the comma operator if
<code class="sourceCode default">NDEBUG</code> is defined due to the
nature of <code class="sourceCode default">assert()</code> being a
macro. The empty argument case could be addressed there as well, but I
did not attempt that (yet), because it could lead to side effects or
make the solution not backward compatible with older version of the
standards, where <code class="sourceCode default">assert(arg,...)</code>
would require at least 2 arguments, whereas in C++20 it only requires a
single argument.</p>
<h2 data-number="5.6" id="do-you-have-implementation-experience"><span class="header-section-number">5.6</span> Do you have implementation
experience?<a href="#do-you-have-implementation-experience" class="self-link"></a></h2>
<p>As stated above and can be seen in the appendix, I used an adapted
<code class="sourceCode default">assert.h</code> on my system and
compiled code with it over several months. I found bugs in my
implementation, and I cannot guarantee, that there are no corner cases,
I missed. But all bugs that I had during that time, stemmed not from the
macro being variadic, but my feeble attempts to detect the cases where a
comma operator might sneak in and my brain having forgotten C.</p>
<h2 data-number="5.7" id="why-dont-you-use-bool__va_args__-to-prevent-comma-operator-usage"><span class="header-section-number">5.7</span> Why don’t you use
<code class="sourceCode default">bool(__VA_ARGS__)</code> to prevent
comma operator usage?<a href="#why-dont-you-use-bool__va_args__-to-prevent-comma-operator-usage" class="self-link"></a></h2>
<p>I did opt for the usage of an identity function, because that
approach works both for C++ and C, whereas the suggested remedy
<code class="sourceCode default">bool(__VA_ARGS__)</code> would only
work for C++. This way, I could prevent implementation divergence
between C and C++ of the actual macro replacement. However, because I
doubt WG14 will accept the proposal, I prepared WG21 wording using the
bool conversion instead of an identity function.</p>
<h2 data-number="5.8" id="why-dont-you-use-assertarg__va_args__-to-prevent-zero-arguments-for-the-ndebug-case"><span class="header-section-number">5.8</span> Why don’t you use
<code class="sourceCode default">assert(arg,__VA_ARGS__)</code> to
prevent zero arguments for the NDEBUG case?<a href="#why-dont-you-use-assertarg__va_args__-to-prevent-zero-arguments-for-the-ndebug-case" class="self-link"></a></h2>
<p>As stated above, the feature is only usable in C++20 for at least one
argument macros and I want my system header compile with all versions of
C++ and C.</p>
<p>I do not have the resources to do a wider spread analysis of the
change, and would appreciate help, if such is required before further
consideration.</p>
<h2 data-number="5.9" id="to-be-discussed"><span class="header-section-number">5.9</span> To be discussed<a href="#to-be-discussed" class="self-link"></a></h2>
<p>Should the C++-only specification still require that
<code class="sourceCode default">&lt;cassert&gt;</code> and
<code class="sourceCode default">&lt;assert.h&gt;</code> have the same
content? This might make sense, but I did not want to put it in yet,
before any decision has been made to proceed.</p>
<h1 data-number="6" id="wording-for-c"><span class="header-section-number">6</span> Wording for C++<a href="#wording-for-c" class="self-link"></a></h1>
<p>The change is relative to n4892. I provide the C++ only change
version here. For a change that relies on the WG14 draft standard to
change as well, see below. Since C adopted the paper for C23 and C++
didn’t for C++23, I expect the later wording to be relevant for C++26
(considering it is to be based on C23).</p>
<p><em>In [<code class="sourceCode default">assertions.general</code>]
apply the following change (taken from C wording):</em></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
The header <code class="sourceCode default">&lt;cassert&gt;</code>
provides a macro for documenting C++ program assertions and a mechanism
for disabling the assertion checks <span class="add" style="color: #006e28"><ins>through defining the macro
<span><code class="sourceCode default">NDEBUG</code></span></ins></span>.</p>
<p><em>In [<code class="sourceCode default">cassert.syn</code>] change
the macro definition as follows:</em></p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(</span><span class="pp"> </span><span class="rm" style="color: #bf0303"><del><span><code class="sourceCode default">E</code></span></del></span> <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">...</code></span></ins></span><span class="pp"> </span><span class="op">)</span><span class="pp"> </span><em>see below</em></span></code></pre></div>
<div class="rm" style="color: #bf0303">
<p>The contents are the same as the C standard library header
<code class="sourceCode default">&lt;assert.h&gt;</code>, except that a
macro named <code class="sourceCode default">static_assert</code> is not
defined.</p>
<p>See also: ISO C 7.2</p>
</div>
<p><em>In [<code class="sourceCode default">assertions.assert</code>]
perform the following changes.</em></p>
<h3 data-number="6.0.1" id="the-assert-macro-assertions.assert"><span class="header-section-number">6.0.1</span> 19.3.2 The
<code class="sourceCode default">assert</code> macro
[assertions.assert]<a href="#the-assert-macro-assertions.assert" class="self-link"></a></h3>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
If <code class="sourceCode default">NDEBUG</code> is defined as a macro
name at the point in the source file where
<code class="sourceCode default">&lt;cassert&gt;</code> is included, the
<code class="sourceCode default">assert</code> macro is defined as</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode default default"><code class="sourceCode default"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>#define assert(...) ((void)0)</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
Otherwise, the <code class="sourceCode default">assert</code> macro puts
a diagnostic test into programs; it expands to an expression of type
<code class="sourceCode default">void</code>, that when executed
evaluates as a subexpression
<code class="sourceCode default">bool(__VA_ARGS__)</code>. If that
evaluation is false, the <code class="sourceCode default">assert</code>
macro’s expression creates a diagnostic containing
<code class="sourceCode default">#__VA_ARGS__</code> and information on
the name of the source file, the source line number, and the name of the
enclosing function (such as provided by
<code class="sourceCode default">source_location::current()</code>) on
the standard error stream in an implementation-defined format. It then
calls <code class="sourceCode default">abort()</code>. If the argument
to <code class="sourceCode default">assert</code> evaluates to
<code class="sourceCode default">true</code>, there is no further
effect.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
The macro <code class="sourceCode default">assert</code> is redefined
according to the current state of
<code class="sourceCode default">NDEBUG</code> each time that
<code class="sourceCode default">&lt;cassert&gt;</code> is included.</p>
</div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
An expression assert(E) is a constant subexpression (16.3.6), if</p>
<ul>
<li><code class="sourceCode default">NDEBUG</code> is defined at the
point where <code class="sourceCode default">assert</code> is last
defined or redefined, or</li>
<li><code class="sourceCode default">E</code> contextually converted to
<code class="sourceCode default">bool</code> (7.3) is a constant
subexpression that evaluates to the value
<code class="sourceCode default">true</code>.</li>
</ul>
<h1 data-number="7" id="wording-for-c-if-c-is-changed"><span class="header-section-number">7</span> Wording for C++ if C is changed<a href="#wording-for-c-if-c-is-changed" class="self-link"></a></h1>
<p>If C++ will be based on C23 for C++26, the following wording can be
applied, relating to the assert(…) specification change for C.</p>
<p><em>In [<code class="sourceCode default">cassert.syn</code>] change
the macro definition as follows:</em></p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(</span><span class="pp"> </span><span class="rm" style="color: #bf0303"><del><span><code class="sourceCode default">E</code></span></del></span> <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">...</code></span></ins></span><span class="pp"> </span><span class="op">)</span><span class="pp"> </span><em>see below</em></span></code></pre></div>
<p>The contents are the same as the C standard library header
<code class="sourceCode default">&lt;assert.h&gt;</code>, except that a
macro named <code class="sourceCode default">static_assert</code> is not
defined.</p>
<p>See also: ISO C 7.2</p>
<p><em>In [<code class="sourceCode default">assertions.assert</code>] no
change is required. It is provided here for easier reference by
reviewers.</em></p>
<h3 data-number="7.0.1" id="the-assert-macro-assertions.assert-1"><span class="header-section-number">7.0.1</span> 19.3.2 The
<code class="sourceCode default">assert</code> macro
[assertions.assert]<a href="#the-assert-macro-assertions.assert-1" class="self-link"></a></h3>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
An expression assert(E) is a constant subexpression (16.3.6), if</p>
<ul>
<li><code class="sourceCode default">NDEBUG</code> is defined at the
point where <code class="sourceCode default">assert</code> is last
defined or redefined, or</li>
<li><code class="sourceCode default">E</code> contextually converted to
<code class="sourceCode default">bool</code> (7.3) is a constant
subexpression that evaluates to the value
<code class="sourceCode default">true</code>.</li>
</ul>
<h1 data-number="8" id="wording-for-c-1"><span class="header-section-number">8</span> Wording for C<a href="#wording-for-c-1" class="self-link"></a></h1>
<p>These changes are relative to N2573. Those changes were applied for
C23 (N3047) and might be considered a specification bug fix, even for
previous revisions of the C standard due to the use of “scalar
expression” as the argument to assert’s specification if
<code class="sourceCode default">NDEBUG</code> is not defined. Thus, the
minimal change for C++ standard proposed above can be used.</p>
<p><em>In section 7.2 (Diagnostics
<code class="sourceCode default">&lt;assert.h&gt;</code>) change the
definition of the <code class="sourceCode default">assert()</code> macro
to use elipsis instead of a single macro parameter:</em></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
The header <code class="sourceCode default">&lt;assert.h&gt;</code>
defines the <code class="sourceCode default">assert</code> and
<code class="sourceCode default">static_assert</code> macros and refers
to another macro,</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>NDEBUG</span></code></pre></div>
<p>which is not defined by
<code class="sourceCode default">&lt;assert.h&gt;</code>. If
<code class="sourceCode default">NDEBUG</code> is defined as a macro
name at the point in the source file where
<code class="sourceCode default">&lt;assert.h&gt;</code> is included,
the <code class="sourceCode default">assert</code> macro is defined
simply as</p>
<div>
<div class="sourceCode" id="cb12"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="st">- #define assert(ignore) ((void)0)</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="va">+ #define assert(...) ((void)0)</span></span></code></pre></div>
</div>
<p>The <code class="sourceCode default">assert</code> macro is redefined
according to the current state of
<code class="sourceCode default">NDEBUG</code> each time that
&lt;assert.h&gt; is included.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
The <code class="sourceCode default">assert</code> macro shall be
implemented as a macro <span class="add" style="color: #006e28"><ins>with an ellipsis parameter</ins></span>, not
as an actual function. If the macro definition is suppressed in order to
access an actual function, the behavior is undefined.</p>
<p><em>In section 7.2.1 (Program Diagnostics) no change is needed. It is
included here for easier reference by reviewers.</em></p>
<h3 data-number="8.0.1" id="program-diagnostics"><span class="header-section-number">8.0.1</span> 7.2.1 Program diagnostics<a href="#program-diagnostics" class="self-link"></a></h3>
<h4 data-number="8.0.1.1" id="the-assert-macro"><span class="header-section-number">8.0.1.1</span> 7.2.1.1 The assert macro<a href="#the-assert-macro" class="self-link"></a></h4>
<p><strong>Synopsis</strong></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span></p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;assert.h&gt;</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="ot">assert</span><span class="op">(</span>scalar expression<span class="op">)</span>;</span></code></pre></div>
<p><strong>Description</strong></p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>The
<code class="sourceCode default">assert</code> macro puts diagnostic
tests into programs; it expands to a void expression. When it is
executed, if <code class="sourceCode default">expression</code> (which
shall have a scalar type) is false (that is, compares equal to 0), the
<code class="sourceCode default">assert</code> macro writes information
about the particular call that failed (including the text of the
argument, the name of the source file, the source line number, and the
name of the enclosing function – the latter are respectively the values
of the preprocessing macros
<code class="sourceCode default">__FILE__</code> and
<code class="sourceCode default">__LINE__</code> and of the identifier
<code class="sourceCode default">__func__</code>) on the standard error
stream in an implementation-defined format.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> It
then calls the <code class="sourceCode default">abort</code>
function.</p>
<p><strong>Returns</strong></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>The
<code class="sourceCode default">assert</code> macro returns no
value.</p>
<p><strong>Forward references:</strong> the
<code class="sourceCode default">abort</code> function (7.22.4.1).</p>
<h1 data-number="9" id="acknowledgements"><span class="header-section-number">9</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>Many thanks to Shafik Yaghmour and other Twitterers for inspiring
this “janitorial” clean up paper.</p>
<p>Thanks to the reviewers and discussion participants in LEWG, SG22 and
WG14.</p>
<h1 data-number="10" id="example-implementation-bsd-license-on-macos"><span class="header-section-number">10</span> Example implementation (BSD
license on MacOS)<a href="#example-implementation-bsd-license-on-macos" class="self-link"></a></h1>
<p>The implementation and some simple tests for checking for the
non-compilability of calling
<code class="sourceCode default">assert()</code> with the wrong number
of arguments are in <a href="https://github.com/PeterSommerlad/SC22WG21_Papers/tree/master/workspace/p2264_test_for_assert_dotdotdot_on_my_machine">https://github.com/PeterSommerlad/SC22WG21_Papers/tree/master/workspace/p2264_test_for_assert_dotdotdot_on_my_machine</a>.</p>
<p>Here are the key changes. I introduced</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef NDEBUG</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp"> </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifndef CHECK_SINGLE_ASSERT_ARGUMENT_PASSED_TO_ASSERT_DEFINED</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#define CHECK_SINGLE_ASSERT_ARGUMENT_PASSED_TO_ASSERT_DEFINED</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a><span class="co">// use bool(__VA_ARGS__)</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> __check_single_argument_passed_to_assert<span class="op">(</span><span class="dt">int</span> b<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> b; <span class="op">}</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* CHECK_SINGLE_ASSERT_ARGUMENT_PASSED_TO_ASSERT_DEFINED */</span></span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp">  </span>\</span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="pp"> </span><span class="op">(</span><span class="dt">bool</span><span class="op">(</span><span class="pp"> </span><span class="ot">__VA_ARGS__</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span>__assert<span class="pp"> </span><span class="op">(</span><span class="pp">#</span>_VA_ARGS__,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span><span class="op">)))</span></span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp">  </span>\</span>
<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="pp"> </span><span class="op">(</span>__check_single_argument_passed_to_assert<span class="op">(</span><span class="ot">__VA_ARGS__</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span>__assert<span class="pp"> </span><span class="op">(</span><span class="pp">#</span>_VA_ARGS__,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span><span class="op">)))</span></span>
<span id="cb14-20"><a href="#cb14-20" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span></code></pre></div>
<p>Full file:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="co">// THIS FILE IS MODIFIED for P2264 (WG21) N2621 &amp; successors (WG14)</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="co">// original file modified and tested on MacOS, but OK, because BSD license</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="co">// Peter Sommerlad.</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a><span class="co">/*-</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="co"> * Copyright (c) 1992, 1993</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="co"> *  The Regents of the University of California.  All rights reserved.</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="co"> * (c) UNIX System Laboratories, Inc.</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="co"> * All or some portions of this file are derived from material licensed</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a><span class="co"> * to the University of California by American Telephone and Telegraph</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a><span class="co"> * Co. or Unix System Laboratories, Inc. and are reproduced herein with</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a><span class="co"> * the permission of UNIX System Laboratories, Inc.</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a><span class="co"> *</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a><span class="co"> * Redistribution and use in source and binary forms, with or without</span></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a><span class="co"> * modification, are permitted provided that the following conditions</span></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a><span class="co"> * are met:</span></span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a><span class="co"> * 1. Redistributions of source code must retain the above copyright</span></span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a><span class="co"> *    notice, this list of conditions and the following disclaimer.</span></span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a><span class="co"> * 2. Redistributions in binary form must reproduce the above copyright</span></span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a><span class="co"> *    notice, this list of conditions and the following disclaimer in the</span></span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a><span class="co"> *    documentation and/or other materials provided with the distribution.</span></span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a><span class="co"> * 3. All advertising materials mentioning features or use of this software</span></span>
<span id="cb15-24"><a href="#cb15-24" aria-hidden="true" tabindex="-1"></a><span class="co"> *    must display the following acknowledgement:</span></span>
<span id="cb15-25"><a href="#cb15-25" aria-hidden="true" tabindex="-1"></a><span class="co"> *  This product includes software developed by the University of</span></span>
<span id="cb15-26"><a href="#cb15-26" aria-hidden="true" tabindex="-1"></a><span class="co"> *  California, Berkeley and its contributors.</span></span>
<span id="cb15-27"><a href="#cb15-27" aria-hidden="true" tabindex="-1"></a><span class="co"> * 4. Neither the name of the University nor the names of its contributors</span></span>
<span id="cb15-28"><a href="#cb15-28" aria-hidden="true" tabindex="-1"></a><span class="co"> *    may be used to endorse or promote products derived from this software</span></span>
<span id="cb15-29"><a href="#cb15-29" aria-hidden="true" tabindex="-1"></a><span class="co"> *    without specific prior written permission.</span></span>
<span id="cb15-30"><a href="#cb15-30" aria-hidden="true" tabindex="-1"></a><span class="co"> *</span></span>
<span id="cb15-31"><a href="#cb15-31" aria-hidden="true" tabindex="-1"></a><span class="co"> * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS&#39;&#39; AND</span></span>
<span id="cb15-32"><a href="#cb15-32" aria-hidden="true" tabindex="-1"></a><span class="co"> * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span></span>
<span id="cb15-33"><a href="#cb15-33" aria-hidden="true" tabindex="-1"></a><span class="co"> * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</span></span>
<span id="cb15-34"><a href="#cb15-34" aria-hidden="true" tabindex="-1"></a><span class="co"> * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE</span></span>
<span id="cb15-35"><a href="#cb15-35" aria-hidden="true" tabindex="-1"></a><span class="co"> * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span></span>
<span id="cb15-36"><a href="#cb15-36" aria-hidden="true" tabindex="-1"></a><span class="co"> * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS</span></span>
<span id="cb15-37"><a href="#cb15-37" aria-hidden="true" tabindex="-1"></a><span class="co"> * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)</span></span>
<span id="cb15-38"><a href="#cb15-38" aria-hidden="true" tabindex="-1"></a><span class="co"> * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT</span></span>
<span id="cb15-39"><a href="#cb15-39" aria-hidden="true" tabindex="-1"></a><span class="co"> * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY</span></span>
<span id="cb15-40"><a href="#cb15-40" aria-hidden="true" tabindex="-1"></a><span class="co"> * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF</span></span>
<span id="cb15-41"><a href="#cb15-41" aria-hidden="true" tabindex="-1"></a><span class="co"> * SUCH DAMAGE.</span></span>
<span id="cb15-42"><a href="#cb15-42" aria-hidden="true" tabindex="-1"></a><span class="co"> *</span></span>
<span id="cb15-43"><a href="#cb15-43" aria-hidden="true" tabindex="-1"></a><span class="co"> *  @(#)assert.h    8.2 (Berkeley) 1/21/94</span></span>
<span id="cb15-44"><a href="#cb15-44" aria-hidden="true" tabindex="-1"></a><span class="co"> * $FreeBSD: src/include/assert.h,v 1.4 2002/03/23 17:24:53 imp Exp $</span></span>
<span id="cb15-45"><a href="#cb15-45" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
<span id="cb15-46"><a href="#cb15-46" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-47"><a href="#cb15-47" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;sys/cdefs.h&gt;</span></span>
<span id="cb15-48"><a href="#cb15-48" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb15-49"><a href="#cb15-49" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;stdlib.h&gt;</span></span>
<span id="cb15-50"><a href="#cb15-50" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* __cplusplus */</span></span>
<span id="cb15-51"><a href="#cb15-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-52"><a href="#cb15-52" aria-hidden="true" tabindex="-1"></a><span class="co">/*</span></span>
<span id="cb15-53"><a href="#cb15-53" aria-hidden="true" tabindex="-1"></a><span class="co"> * Unlike other ANSI header files, &lt;assert.h&gt; may usefully be included</span></span>
<span id="cb15-54"><a href="#cb15-54" aria-hidden="true" tabindex="-1"></a><span class="co"> * multiple times, with and without NDEBUG defined.</span></span>
<span id="cb15-55"><a href="#cb15-55" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
<span id="cb15-56"><a href="#cb15-56" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-57"><a href="#cb15-57" aria-hidden="true" tabindex="-1"></a><span class="pp">#undef </span><span class="ot">assert</span></span>
<span id="cb15-58"><a href="#cb15-58" aria-hidden="true" tabindex="-1"></a><span class="pp">#undef __assert</span></span>
<span id="cb15-59"><a href="#cb15-59" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-60"><a href="#cb15-60" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef NDEBUG</span></span>
<span id="cb15-61"><a href="#cb15-61" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp"> </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span></span>
<span id="cb15-62"><a href="#cb15-62" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb15-63"><a href="#cb15-63" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-64"><a href="#cb15-64" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifndef CHECK_SINGLE_ASSERT_ARGUMENT_PASSED_TO_ASSERT_DEFINED</span></span>
<span id="cb15-65"><a href="#cb15-65" aria-hidden="true" tabindex="-1"></a><span class="pp">#define CHECK_SINGLE_ASSERT_ARGUMENT_PASSED_TO_ASSERT_DEFINED</span></span>
<span id="cb15-66"><a href="#cb15-66" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb15-67"><a href="#cb15-67" aria-hidden="true" tabindex="-1"></a><span class="co">// use bool(__VA_ARGS__)</span></span>
<span id="cb15-68"><a href="#cb15-68" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb15-69"><a href="#cb15-69" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">inline</span> <span class="dt">int</span> __check_single_argument_passed_to_assert<span class="op">(</span><span class="dt">int</span> b<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> b; <span class="op">}</span></span>
<span id="cb15-70"><a href="#cb15-70" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb15-71"><a href="#cb15-71" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* CHECK_SINGLE_ASSERT_ARGUMENT_PASSED_TO_ASSERT_DEFINED */</span></span>
<span id="cb15-72"><a href="#cb15-72" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-73"><a href="#cb15-73" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifndef __GNUC__</span></span>
<span id="cb15-74"><a href="#cb15-74" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-75"><a href="#cb15-75" aria-hidden="true" tabindex="-1"></a>__BEGIN_DECLS</span>
<span id="cb15-76"><a href="#cb15-76" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifndef __cplusplus</span></span>
<span id="cb15-77"><a href="#cb15-77" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> abort<span class="op">(</span><span class="dt">void</span><span class="op">)</span> __dead2;</span>
<span id="cb15-78"><a href="#cb15-78" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* !__cplusplus */</span></span>
<span id="cb15-79"><a href="#cb15-79" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span>  printf<span class="op">(</span><span class="kw">const</span> <span class="dt">char</span> <span class="op">*</span> <span class="ex">__restrict</span>, <span class="op">...)</span>;</span>
<span id="cb15-80"><a href="#cb15-80" aria-hidden="true" tabindex="-1"></a>__END_DECLS</span>
<span id="cb15-81"><a href="#cb15-81" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-82"><a href="#cb15-82" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb15-83"><a href="#cb15-83" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp">  </span>\</span>
<span id="cb15-84"><a href="#cb15-84" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="pp"> </span><span class="op">(</span><span class="dt">bool</span><span class="op">(</span><span class="pp"> </span><span class="ot">__VA_ARGS__</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span>__assert<span class="pp"> </span><span class="op">(</span><span class="pp">#</span>_VA_ARGS__,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span><span class="op">)))</span></span>
<span id="cb15-85"><a href="#cb15-85" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb15-86"><a href="#cb15-86" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp">  </span>\</span>
<span id="cb15-87"><a href="#cb15-87" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="pp"> </span><span class="op">(</span>__check_single_argument_passed_to_assert<span class="op">(</span><span class="ot">__VA_ARGS__</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span>__assert<span class="pp"> </span><span class="op">(</span><span class="pp">#</span>_VA_ARGS__,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span><span class="op">)))</span></span>
<span id="cb15-88"><a href="#cb15-88" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb15-89"><a href="#cb15-89" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-90"><a href="#cb15-90" aria-hidden="true" tabindex="-1"></a><span class="pp">#define __assert</span><span class="op">(</span>e,<span class="pp"> </span>file,<span class="pp"> </span>line<span class="op">)</span><span class="pp"> </span>\</span>
<span id="cb15-91"><a href="#cb15-91" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">((</span><span class="dt">void</span><span class="op">)</span>printf<span class="pp"> </span><span class="op">(</span><span class="st">&quot;</span><span class="sc">%s</span><span class="st">:</span><span class="sc">%u</span><span class="st">: failed assertion `</span><span class="sc">%s</span><span class="st">&#39;</span><span class="sc">\n</span><span class="st">&quot;</span>,<span class="pp"> </span>file,<span class="pp"> </span>line,<span class="pp"> </span>e<span class="op">)</span>,<span class="pp"> </span>abort<span class="op">())</span></span>
<span id="cb15-92"><a href="#cb15-92" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-93"><a href="#cb15-93" aria-hidden="true" tabindex="-1"></a><span class="pp">#else </span><span class="co">/* __GNUC__ */</span></span>
<span id="cb15-94"><a href="#cb15-94" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-95"><a href="#cb15-95" aria-hidden="true" tabindex="-1"></a>__BEGIN_DECLS</span>
<span id="cb15-96"><a href="#cb15-96" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> __assert_rtn<span class="op">(</span><span class="kw">const</span> <span class="dt">char</span> <span class="op">*</span>, <span class="kw">const</span> <span class="dt">char</span> <span class="op">*</span>, <span class="dt">int</span>, <span class="kw">const</span> <span class="dt">char</span> <span class="op">*)</span> __dead2 __disable_tail_calls;</span>
<span id="cb15-97"><a href="#cb15-97" aria-hidden="true" tabindex="-1"></a><span class="pp">#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) &amp;&amp; ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) &lt; 1070)</span></span>
<span id="cb15-98"><a href="#cb15-98" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> __eprintf<span class="op">(</span><span class="kw">const</span> <span class="dt">char</span> <span class="op">*</span>, <span class="kw">const</span> <span class="dt">char</span> <span class="op">*</span>, <span class="dt">unsigned</span>, <span class="kw">const</span> <span class="dt">char</span> <span class="op">*)</span> __dead2;</span>
<span id="cb15-99"><a href="#cb15-99" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb15-100"><a href="#cb15-100" aria-hidden="true" tabindex="-1"></a>__END_DECLS</span>
<span id="cb15-101"><a href="#cb15-101" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-102"><a href="#cb15-102" aria-hidden="true" tabindex="-1"></a><span class="pp">#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) &amp;&amp; ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) &lt; 1070)</span></span>
<span id="cb15-103"><a href="#cb15-103" aria-hidden="true" tabindex="-1"></a><span class="pp">#define __assert</span><span class="op">(</span>e,<span class="pp"> </span>file,<span class="pp"> </span>line<span class="op">)</span><span class="pp"> </span>\</span>
<span id="cb15-104"><a href="#cb15-104" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span>__eprintf<span class="pp"> </span><span class="op">(</span><span class="st">&quot;</span><span class="sc">%s</span><span class="st">:</span><span class="sc">%u</span><span class="st">: failed assertion `</span><span class="sc">%s</span><span class="st">&#39;</span><span class="sc">\n</span><span class="st">&quot;</span>,<span class="pp"> </span>file,<span class="pp"> </span>line,<span class="pp"> </span>e<span class="op">)</span></span>
<span id="cb15-105"><a href="#cb15-105" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb15-106"><a href="#cb15-106" aria-hidden="true" tabindex="-1"></a><span class="co">/* 8462256: modified __assert_rtn() replaces deprecated __eprintf() */</span></span>
<span id="cb15-107"><a href="#cb15-107" aria-hidden="true" tabindex="-1"></a><span class="pp">#define __assert</span><span class="op">(</span>e,<span class="pp"> </span>file,<span class="pp"> </span>line<span class="op">)</span><span class="pp"> </span>\</span>
<span id="cb15-108"><a href="#cb15-108" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span>__assert_rtn<span class="pp"> </span><span class="op">((</span><span class="kw">const</span><span class="pp"> </span><span class="dt">char</span><span class="pp"> </span><span class="op">*)-</span><span class="dv">1</span><span class="bu">L</span>,<span class="pp"> </span>file,<span class="pp"> </span>line,<span class="pp"> </span>e<span class="op">)</span></span>
<span id="cb15-109"><a href="#cb15-109" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb15-110"><a href="#cb15-110" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-111"><a href="#cb15-111" aria-hidden="true" tabindex="-1"></a><span class="pp">#if __DARWIN_UNIX03</span></span>
<span id="cb15-112"><a href="#cb15-112" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb15-113"><a href="#cb15-113" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp"> </span>\</span>
<span id="cb15-114"><a href="#cb15-114" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">(</span><span class="fu">__builtin_expect</span><span class="op">(!</span><span class="dt">bool</span><span class="op">(</span><span class="pp"> </span><span class="ot">__VA_ARGS__</span><span class="op">)</span>,<span class="pp"> </span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span>__assert_rtn<span class="op">(</span><span class="ot">__func__</span>,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span>,<span class="pp"> #</span><span class="ot">__VA_ARGS__</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span><span class="op">(</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span></span>
<span id="cb15-115"><a href="#cb15-115" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb15-116"><a href="#cb15-116" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp"> </span>\</span>
<span id="cb15-117"><a href="#cb15-117" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">(</span><span class="fu">__builtin_expect</span><span class="op">(!</span>__check_single_argument_passed_to_assert<span class="op">(</span><span class="pp"> </span><span class="ot">__VA_ARGS__</span><span class="op">)</span>,<span class="pp"> </span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span>__assert_rtn<span class="op">(</span><span class="ot">__func__</span>,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span>,<span class="pp"> #</span><span class="ot">__VA_ARGS__</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span><span class="op">(</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span></span>
<span id="cb15-118"><a href="#cb15-118" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb15-119"><a href="#cb15-119" aria-hidden="true" tabindex="-1"></a><span class="pp">#else </span><span class="co">/* !__DARWIN_UNIX03 */</span></span>
<span id="cb15-120"><a href="#cb15-120" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef __cplusplus</span></span>
<span id="cb15-121"><a href="#cb15-121" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp">  </span>\</span>
<span id="cb15-122"><a href="#cb15-122" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">(</span><span class="fu">__builtin_expect</span><span class="op">(!</span><span class="dt">bool</span><span class="op">(</span><span class="ot">__VA_ARGS__</span><span class="op">)</span>,<span class="pp"> </span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span>__assert<span class="pp"> </span><span class="op">(</span><span class="pp">#</span><span class="ot">__VA_ARGS__</span>,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span><span class="op">(</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span></span>
<span id="cb15-123"><a href="#cb15-123" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb15-124"><a href="#cb15-124" aria-hidden="true" tabindex="-1"></a><span class="pp">#define assert</span><span class="op">(...)</span><span class="pp">  </span>\</span>
<span id="cb15-125"><a href="#cb15-125" aria-hidden="true" tabindex="-1"></a><span class="pp">    </span><span class="op">(</span><span class="fu">__builtin_expect</span><span class="op">(!</span>__check_single_argument_passed_to_assert<span class="op">(</span><span class="ot">__VA_ARGS__</span><span class="op">)</span>,<span class="pp"> </span><span class="dv">0</span><span class="op">)</span><span class="pp"> </span><span class="op">?</span><span class="pp"> </span>__assert<span class="pp"> </span><span class="op">(</span><span class="pp">#</span><span class="ot">__VA_ARGS__</span>,<span class="pp"> </span><span class="ot">__FILE__</span>,<span class="pp"> </span><span class="ot">__LINE__</span><span class="op">)</span><span class="pp"> </span><span class="op">:</span><span class="pp"> </span><span class="op">(</span><span class="dt">void</span><span class="op">)</span><span class="dv">0</span><span class="op">)</span></span>
<span id="cb15-126"><a href="#cb15-126" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb15-127"><a href="#cb15-127" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* __DARWIN_UNIX03 */</span></span>
<span id="cb15-128"><a href="#cb15-128" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-129"><a href="#cb15-129" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* __GNUC__ */</span></span>
<span id="cb15-130"><a href="#cb15-130" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* NDEBUG */</span></span>
<span id="cb15-131"><a href="#cb15-131" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-132"><a href="#cb15-132" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifndef _ASSERT_H_</span></span>
<span id="cb15-133"><a href="#cb15-133" aria-hidden="true" tabindex="-1"></a><span class="pp">#define _ASSERT_H_</span></span>
<span id="cb15-134"><a href="#cb15-134" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-135"><a href="#cb15-135" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifndef __cplusplus</span></span>
<span id="cb15-136"><a href="#cb15-136" aria-hidden="true" tabindex="-1"></a><span class="pp">#if defined(</span><span class="ot">__STDC_VERSION__</span><span class="pp">) &amp;&amp; </span><span class="ot">__STDC_VERSION__</span><span class="pp"> &gt;= 201112L</span></span>
<span id="cb15-137"><a href="#cb15-137" aria-hidden="true" tabindex="-1"></a><span class="pp">#define static_assert </span>_Static_assert</span>
<span id="cb15-138"><a href="#cb15-138" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* __STDC_VERSION__ */</span></span>
<span id="cb15-139"><a href="#cb15-139" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* !__cplusplus */</span></span>
<span id="cb15-140"><a href="#cb15-140" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-141"><a href="#cb15-141" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif </span><span class="co">/* _ASSERT_H_ */</span></span></code></pre></div>
<h2 data-number="10.1" id="c-test-cases"><span class="header-section-number">10.1</span> C test cases<a href="#c-test-cases" class="self-link"></a></h2>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;system_assert_h_BSD.h&quot;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;system_assert_h_BSD.h&quot;</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="co">// NDEBUG not set</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> intpair<span class="op">{</span> <span class="dt">int</span> i,j;<span class="op">}</span>;</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatMultipleArgsDontCompile<span class="op">(){</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">//assert(1,2,3);</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">))</span>;</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatBracesConstructorWithCommasCompiles<span class="op">(){</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dt">int</span><span class="op">[</span><span class="dv">2</span><span class="op">]){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}[</span><span class="dv">0</span><span class="op">]</span> <span class="op">==</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">//assert((int[2]){1,2}[0] , 1);</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="kw">struct</span> intpair<span class="op">){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}.</span>j <span class="op">==</span> <span class="dv">1</span><span class="op">)</span>; <span class="co">// false</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a><span class="pp">#define NDEBUG</span></span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;system_assert_h_BSD.h&quot;</span></span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a><span class="co">// check double inclusion is possible without problems</span></span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;system_assert_h_BSD.h&quot;</span></span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatMultipleArgsDontCompileNDEBUG<span class="op">(){</span></span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">)</span>; <span class="co">// will compile with NDEBUG set</span></span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">))</span>;</span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-27"><a href="#cb16-27" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatBracesConstructorWithCommasCompilesNDEBUG<span class="op">(){</span></span>
<span id="cb16-28"><a href="#cb16-28" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dt">int</span><span class="op">[</span><span class="dv">2</span><span class="op">]){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}[</span><span class="dv">0</span><span class="op">]</span> <span class="op">==</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb16-29"><a href="#cb16-29" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dt">int</span><span class="op">[</span><span class="dv">2</span><span class="op">]){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}[</span><span class="dv">0</span><span class="op">]</span> , <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb16-30"><a href="#cb16-30" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="kw">struct</span> intpair<span class="op">){</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}.</span>j <span class="op">==</span> <span class="dv">1</span><span class="op">)</span>; <span class="co">// false</span></span>
<span id="cb16-31"><a href="#cb16-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb16-32"><a href="#cb16-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-33"><a href="#cb16-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-34"><a href="#cb16-34" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> runCasserts<span class="op">(){</span></span>
<span id="cb16-35"><a href="#cb16-35" aria-hidden="true" tabindex="-1"></a>    checkThatMultipleArgsDontCompileNDEBUG<span class="op">()</span>;</span>
<span id="cb16-36"><a href="#cb16-36" aria-hidden="true" tabindex="-1"></a>    checkThatBracesConstructorWithCommasCompilesNDEBUG<span class="op">()</span>;</span>
<span id="cb16-37"><a href="#cb16-37" aria-hidden="true" tabindex="-1"></a>    checkThatMultipleArgsDontCompile<span class="op">()</span>;</span>
<span id="cb16-38"><a href="#cb16-38" aria-hidden="true" tabindex="-1"></a>    <span class="co">//checkThatBracesConstructorWithCommasCompiles();</span></span>
<span id="cb16-39"><a href="#cb16-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="10.2" id="c-test-cases-1"><span class="header-section-number">10.2</span> C++ test cases<a href="#c-test-cases-1" class="self-link"></a></h2>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;vector&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;memory&gt;</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;cassert_gcc&quot;</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;cassert_gcc&quot;</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a><span class="co">// NDEBUG not set</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatNoArgumentDoesntCompile<span class="op">(){</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">//assert();</span></span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a>    <span class="co">// error: too few arguments to function &#39;constexpr bool __check_single_argument_passed_to_assert(bool)</span></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatMultipleArgsDontCompile<span class="op">(){</span></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">//assert(1,2,3); should not compile</span></span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">))</span>;</span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatBracesConstructorWithCommasCompiles<span class="op">(){</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;{</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span><span class="op">}.</span>size<span class="op">()==</span><span class="dv">4</span><span class="bu">u</span><span class="op">)</span>;</span>
<span id="cb17-22"><a href="#cb17-22" aria-hidden="true" tabindex="-1"></a>    <span class="co">//assert(std::vector{1,2,3,4}.size(),4u); // should not compile, comma operator</span></span>
<span id="cb17-23"><a href="#cb17-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-24"><a href="#cb17-24" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatContextualConversionToBoolWorks<span class="op">(){</span></span>
<span id="cb17-25"><a href="#cb17-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> vpi <span class="op">=</span> std<span class="op">::</span>vector<span class="op">&lt;</span>std<span class="op">::</span>unique_ptr<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>;</span>
<span id="cb17-26"><a href="#cb17-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> upvpi <span class="op">=</span> std<span class="op">::</span>unique_ptr<span class="op">&lt;</span>std<span class="op">::</span>vector<span class="op">&lt;</span>std<span class="op">::</span>unique_ptr<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;&gt;</span>;</span>
<span id="cb17-27"><a href="#cb17-27" aria-hidden="true" tabindex="-1"></a>    upvpi pi <span class="op">=</span> std<span class="op">::</span>make_unique<span class="op">&lt;</span>vpi<span class="op">&gt;()</span>;</span>
<span id="cb17-28"><a href="#cb17-28" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>pi<span class="op">)</span>;</span>
<span id="cb17-29"><a href="#cb17-29" aria-hidden="true" tabindex="-1"></a>    pi <span class="op">=</span> <span class="kw">nullptr</span>;</span>
<span id="cb17-30"><a href="#cb17-30" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(!</span>pi<span class="op">)</span>;</span>
<span id="cb17-31"><a href="#cb17-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-32"><a href="#cb17-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-33"><a href="#cb17-33" aria-hidden="true" tabindex="-1"></a><span class="pp">#define NDEBUG</span></span>
<span id="cb17-34"><a href="#cb17-34" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;cassert_gcc&quot;</span></span>
<span id="cb17-35"><a href="#cb17-35" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;cassert_gcc&quot;</span></span>
<span id="cb17-36"><a href="#cb17-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-37"><a href="#cb17-37" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatNoArgumentDoesntCompileNDEBUG<span class="op">(){</span></span>
<span id="cb17-38"><a href="#cb17-38" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">()</span>; <span class="co">// will compile with NDEBUG set</span></span>
<span id="cb17-39"><a href="#cb17-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-40"><a href="#cb17-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-41"><a href="#cb17-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-42"><a href="#cb17-42" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatMultipleArgsDontCompileNDEBUG<span class="op">(){</span></span>
<span id="cb17-43"><a href="#cb17-43" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">)</span>; <span class="co">// will compile with NDEBUG set</span></span>
<span id="cb17-44"><a href="#cb17-44" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">((</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">))</span>;</span>
<span id="cb17-45"><a href="#cb17-45" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-46"><a href="#cb17-46" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-47"><a href="#cb17-47" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> checkThatBracesConstructorWithCommasCompilesNDEBUG<span class="op">(){</span></span>
<span id="cb17-48"><a href="#cb17-48" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>std<span class="op">::</span>vector<span class="op">{</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span><span class="op">}.</span>size<span class="op">()==</span><span class="dv">3</span><span class="bu">u</span><span class="op">)</span>; <span class="co">// false</span></span>
<span id="cb17-49"><a href="#cb17-49" aria-hidden="true" tabindex="-1"></a>    <span class="ot">assert</span><span class="op">(</span>std<span class="op">::</span>vector<span class="op">{</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span><span class="op">}.</span>size<span class="op">()</span>,<span class="dv">4</span><span class="bu">u</span><span class="op">)</span>; <span class="co">// will compile with NDEBUG set</span></span>
<span id="cb17-50"><a href="#cb17-50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-51"><a href="#cb17-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-52"><a href="#cb17-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-53"><a href="#cb17-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-54"><a href="#cb17-54" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> runCppasserts<span class="op">(){</span></span>
<span id="cb17-55"><a href="#cb17-55" aria-hidden="true" tabindex="-1"></a>    checkThatMultipleArgsDontCompileNDEBUG<span class="op">()</span>;</span>
<span id="cb17-56"><a href="#cb17-56" aria-hidden="true" tabindex="-1"></a>    checkThatBracesConstructorWithCommasCompilesNDEBUG<span class="op">()</span>;</span>
<span id="cb17-57"><a href="#cb17-57" aria-hidden="true" tabindex="-1"></a>    checkThatMultipleArgsDontCompile<span class="op">()</span>;</span>
<span id="cb17-58"><a href="#cb17-58" aria-hidden="true" tabindex="-1"></a>    checkThatBracesConstructorWithCommasCompiles<span class="op">()</span>;</span>
<span id="cb17-59"><a href="#cb17-59" aria-hidden="true" tabindex="-1"></a>    checkThatContextualConversionToBoolWorks<span class="op">()</span>;</span>
<span id="cb17-60"><a href="#cb17-60" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-61"><a href="#cb17-61" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-62"><a href="#cb17-62" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-63"><a href="#cb17-63" aria-hidden="true" tabindex="-1"></a><span class="kw">extern</span> <span class="st">&quot;C&quot;</span> <span class="dt">void</span> runCasserts<span class="op">()</span>;</span>
<span id="cb17-64"><a href="#cb17-64" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-65"><a href="#cb17-65" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;iostream&gt;</span></span>
<span id="cb17-66"><a href="#cb17-66" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-67"><a href="#cb17-67" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb17-68"><a href="#cb17-68" aria-hidden="true" tabindex="-1"></a>    runCasserts<span class="op">()</span>;</span>
<span id="cb17-69"><a href="#cb17-69" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;!!!Hello World!!!&quot;</span> <span class="op">&lt;&lt;</span> std<span class="op">::</span>endl;</span>
<span id="cb17-70"><a href="#cb17-70" aria-hidden="true" tabindex="-1"></a>    runCppasserts<span class="op">()</span>;</span>
<span id="cb17-71"><a href="#cb17-71" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>The message might be of the form:
<code class="sourceCode default">Assertion failed: _expression_ function _abc_, file _xyz_ line _nnn_.</code><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
