<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="mobile-web-app-capable" content="yes">
    <title>
        const references to constexpr variables - HackMD
    </title>
    <link rel="icon" type="image/png" href="https://hackmd.io/favicon.png">
    <link rel="apple-touch-icon" href="https://hackmd.io/apple-touch-icon.png">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha256-eZrrJcwDc/3uDhsdt61sL2oOBY362qM3lon1gyExkL0=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" integrity="sha256-3iu9jgsy9TpTwXKb7bNQzqWekRX7pPK+2OLj3R922fo=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css" integrity="sha256-QiWfLIsCT02Sdwkogf6YMiQlj4NE84MKkzEMkZnMGdg=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/themes/prism.min.css" integrity="sha256-vtR0hSWRc3Tb26iuN2oZHt3KRUomwTufNIf5/4oeCyg=" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@hackmd/emojify.js@2.1.0/dist/css/basic/emojify.min.css" integrity="sha256-UOrvMOsSDSrW6szVLe8ZDZezBxh5IoIfgTwdNDgTjiU=" crossorigin="anonymous" />
    <style>
        @import url(https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,500,500i|Source+Code+Pro:300,400,500|Source+Sans+Pro:300,300i,400,400i,600,600i|Source+Serif+Pro&subset=latin-ext);.hljs{background:#fff;color:#333;display:block;overflow-x:auto;padding:.5em}.hljs-comment,.hljs-meta{color:#969896}.hljs-emphasis,.hljs-quote,.hljs-string,.hljs-strong,.hljs-template-variable,.hljs-variable{color:#df5000}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#a71d5d}.hljs-attribute,.hljs-bullet,.hljs-literal,.hljs-number,.hljs-symbol{color:#0086b3}.hljs-built_in,.hljs-builtin-name{color:#005cc5}.hljs-name,.hljs-section{color:#63a35c}.hljs-tag{color:#333}.hljs-attr,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-title{color:#795da3}.hljs-addition{background-color:#eaffea;color:#55a532}.hljs-deletion{background-color:#ffecec;color:#bd2c00}.hljs-link{text-decoration:underline}.markdown-body{word-wrap:break-word;font-size:16px;line-height:1.5}.markdown-body:after,.markdown-body:before{content:"";display:table}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .absent{color:#c00}.markdown-body .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-bottom:16px;margin-top:0}.markdown-body hr{background-color:#e7e7e7;border:0;height:.25em;margin:24px 0;padding:0}.markdown-body blockquote{border-left:.25em solid #ddd;color:#777;font-size:16px;padding:0 1em}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd,.popover kbd{background-color:#fcfcfc;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#555;display:inline-block;font-size:11px;line-height:10px;padding:3px 5px;vertical-align:middle}.markdown-body .loweralpha{list-style-type:lower-alpha}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{font-weight:600;line-height:1.25;margin-bottom:16px;margin-top:24px}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#000;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1 code,.markdown-body h1 tt,.markdown-body h2 code,.markdown-body h2 tt,.markdown-body h3 code,.markdown-body h3 tt,.markdown-body h4 code,.markdown-body h4 tt,.markdown-body h5 code,.markdown-body h5 tt,.markdown-body h6 code,.markdown-body h6 tt{font-size:inherit}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{border-bottom:1px solid #eee;padding-bottom:.3em}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{color:#777;font-size:.85em}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol.no-list,.markdown-body ul.no-list{list-style-type:none;padding:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-bottom:0;margin-top:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{padding-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{font-size:1em;font-style:italic;font-weight:700;margin-top:16px;padding:0}.markdown-body dl dd{margin-bottom:16px;padding:0 16px}.markdown-body table{display:block;overflow:auto;width:100%;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{border:1px solid #ddd;padding:6px 13px}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{background-color:#fff;box-sizing:initial;max-width:100%}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{background-color:initial;max-width:none;vertical-align:text-top}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{border:1px solid #ddd;display:block;float:left;margin:13px 0 0;overflow:hidden;padding:7px;width:auto}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{clear:both;color:#333;display:block;padding:5px 0 0}.markdown-body span.align-center{clear:both;display:block;overflow:hidden}.markdown-body span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown-body span.align-center span img{margin:0 auto;text-align:center}.markdown-body span.align-right{clear:both;display:block;overflow:hidden}.markdown-body span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown-body span.align-right span img{margin:0;text-align:right}.markdown-body span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown-body span.float-left span{margin:13px 0 0}.markdown-body span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown-body span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown-body code,.markdown-body tt{background-color:#0000000a;border-radius:3px;font-size:85%;margin:0;padding:.2em 0}.markdown-body code:after,.markdown-body code:before,.markdown-body tt:after,.markdown-body tt:before{content:"\00a0";letter-spacing:-.2em}.markdown-body code br,.markdown-body tt br{display:none}.markdown-body del code{text-decoration:inherit}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{background:#0000;border:0;font-size:100%;margin:0;padding:0;white-space:pre;word-break:normal}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{border-radius:3px;font-size:85%;line-height:1.45;overflow:auto}.markdown-body:not(.next-editor) pre{background-color:#f7f7f7;padding:16px}.markdown-body pre code,.markdown-body pre tt{word-wrap:normal;background-color:initial;border:0;display:inline;line-height:inherit;margin:0;max-width:auto;overflow:visible;padding:0}.markdown-body pre code:after,.markdown-body pre code:before,.markdown-body pre tt:after,.markdown-body pre tt:before{content:normal}.markdown-body .csv-data td,.markdown-body .csv-data th{font-size:12px;line-height:1;overflow:hidden;padding:5px;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-line-num{background:#fff;border:0;padding:10px 8px 9px;text-align:right}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{background:#f8f8f8;border-top:0;font-weight:700}.news .alert .markdown-body blockquote{border:0;padding:0 0 0 40px}.activity-tab .news .alert .commits,.activity-tab .news .markdown-body blockquote{padding-left:0}.task-list-item{list-style-type:none}.task-list-item label{font-weight:400}.task-list-item.enabled label{cursor:pointer}.task-list-item+.task-list-item{margin-top:3px}.task-list-item-checkbox{cursor:default!important;float:left;margin:.31em 0 .2em -1.3em!important;vertical-align:middle}.markdown-body{max-width:758px;overflow:visible!important;padding-bottom:40px;padding-top:40px;position:relative}.markdown-body.next-editor{overflow-x:hidden!important}.markdown-body .emoji{vertical-align:top}.markdown-body pre{border:inherit!important}.markdown-body code{color:inherit!important}.markdown-body pre code .wrapper{display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}.markdown-body pre code .gutter{float:left;overflow:hidden;-webkit-user-select:none;user-select:none}.markdown-body pre code .gutter.linenumber{border-right:3px solid #6ce26c!important;box-sizing:initial;color:#afafaf!important;cursor:default;display:inline-block;min-width:20px;padding:0 8px 0 0;position:relative;text-align:right;z-index:4}.markdown-body pre code .gutter.linenumber>span:before{content:attr(data-linenumber)}.markdown-body pre code .code{float:left;margin:0 0 0 16px}.markdown-body .gist .line-numbers{border-bottom:none;border-left:none;border-top:none}.markdown-body .gist .line-data{border:none}.markdown-body .gist table{border-collapse:inherit!important;border-spacing:0}.markdown-body code[data-gist-id]{background:none;padding:0}.markdown-body code[data-gist-id]:after,.markdown-body code[data-gist-id]:before{content:""}.markdown-body code[data-gist-id] .blob-num{border:unset}.markdown-body code[data-gist-id] table{margin-bottom:unset;overflow:unset}.markdown-body code[data-gist-id] table tr{background:unset}.markdown-body[dir=rtl] pre{direction:ltr}.markdown-body[dir=rtl] code{direction:ltr;unicode-bidi:embed}.markdown-body .alert{display:flex;flex-direction:column;gap:16px}.markdown-body .alert>*{margin:0}.markdown-body pre.abc,.markdown-body pre.flow-chart,.markdown-body pre.graphviz,.markdown-body pre.mermaid,.markdown-body pre.sequence-diagram,.markdown-body pre.vega{background-color:inherit;border-radius:0;overflow:visible;text-align:center;white-space:inherit}.markdown-body pre.abc>code,.markdown-body pre.flow-chart>code,.markdown-body pre.graphviz>code,.markdown-body pre.mermaid>code,.markdown-body pre.sequence-diagram>code,.markdown-body pre.vega>code{text-align:left}.markdown-body pre.abc>svg,.markdown-body pre.flow-chart>svg,.markdown-body pre.graphviz>svg,.markdown-body pre.mermaid>svg,.markdown-body pre.sequence-diagram>svg,.markdown-body pre.vega>svg{height:100%;max-width:100%}.markdown-body pre>code.wrap{word-wrap:break-word;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap}.markdown-body summary{display:list-item}.markdown-body summary:focus{outline:none}.markdown-body details summary{cursor:pointer}.markdown-body details:not([open])>:not(summary){display:none}.markdown-body figure{margin:1em 40px}.markdown-body .mark,.markdown-body mark{background-color:#fff1a7}.vimeo,.youtube{background-color:#000;background-position:50%;background-repeat:no-repeat;background-size:contain;cursor:pointer;display:table;overflow:hidden;text-align:center}.vimeo,.youtube{position:relative;width:100%}.youtube{padding-bottom:56.25%}.vimeo img{object-fit:contain;width:100%;z-index:0}.youtube img{object-fit:cover;z-index:0}.vimeo iframe,.youtube iframe,.youtube img{height:100%;left:0;position:absolute;top:0;width:100%}.vimeo iframe,.youtube iframe{vertical-align:middle;z-index:1}.vimeo .icon,.youtube .icon{color:#fff;height:auto;left:50%;opacity:.3;position:absolute;top:50%;transform:translate(-50%,-50%);transition:opacity .2s;width:auto;z-index:0}.vimeo:hover .icon,.youtube:hover .icon{opacity:.6;transition:opacity .2s}.slideshare .inner,.speakerdeck .inner{position:relative;width:100%}.slideshare .inner iframe,.speakerdeck .inner iframe{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.figma{display:table;padding-bottom:56.25%;position:relative;width:100%}.figma iframe{border:1px solid #eee;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.markmap-container{height:300px}.markmap-container>svg{height:100%;width:100%}.MJX_Assistive_MathML{display:none}#MathJax_Message{z-index:1000!important}.ui-infobar{color:#777;margin:25px auto -25px;max-width:760px;position:relative;z-index:2}.toc .invisable-node{list-style-type:none}.ui-toc{bottom:20px;position:fixed;z-index:998}.ui-toc.both-mode{margin-left:8px}.ui-toc.both-mode .ui-toc-label{border-bottom-left-radius:0;border-top-left-radius:0;height:40px;padding:10px 4px}.ui-toc-label{background-color:#e6e6e6;border:none;color:#868686;transition:opacity .2s}.ui-toc .open .ui-toc-label{color:#fff;opacity:1;transition:opacity .2s}.ui-toc-label:focus{background-color:#ccc;color:#000;opacity:.3}.ui-toc-label:hover{background-color:#ccc;opacity:1;transition:opacity .2s}.ui-toc-dropdown{margin-bottom:20px;margin-top:20px;max-height:70vh;max-width:45vw;overflow:auto;padding-left:10px;padding-right:10px;text-align:inherit;width:25vw}.ui-toc-dropdown>.toc{max-height:calc(70vh - 100px);overflow:auto}.ui-toc-dropdown[dir=rtl] .nav{letter-spacing:.0029em;padding-right:0}.ui-toc-dropdown a{overflow:hidden;text-overflow:ellipsis;white-space:pre}.ui-toc-dropdown .nav>li>a{color:#767676;display:block;font-size:13px;font-weight:500;padding:4px 20px}.ui-toc-dropdown .nav>li:first-child:last-child>ul,.ui-toc-dropdown .toc.expand ul{display:block}.ui-toc-dropdown .nav>li>a:focus,.ui-toc-dropdown .nav>li>a:hover{background-color:initial;border-left:1px solid #000;color:#000;padding-left:19px;text-decoration:none}.ui-toc-dropdown[dir=rtl] .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav>li>a:hover{border-left:none;border-right:1px solid #000;padding-right:19px}.ui-toc-dropdown .nav>.active:focus>a,.ui-toc-dropdown .nav>.active:hover>a,.ui-toc-dropdown .nav>.active>a{background-color:initial;border-left:2px solid #000;color:#000;font-weight:700;padding-left:18px}.ui-toc-dropdown[dir=rtl] .nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav>.active>a{border-left:none;border-right:2px solid #000;padding-right:18px}.ui-toc-dropdown .nav .nav{display:none;padding-bottom:10px}.ui-toc-dropdown .nav>.active>ul{display:block}.ui-toc-dropdown .nav .nav>li>a{font-size:12px;font-weight:400;padding-bottom:1px;padding-left:30px;padding-top:1px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a{padding-right:30px}.ui-toc-dropdown .nav .nav>li>ul>li>a{font-size:12px;font-weight:400;padding-bottom:1px;padding-left:40px;padding-top:1px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a{padding-right:40px}.ui-toc-dropdown .nav .nav>li>a:focus,.ui-toc-dropdown .nav .nav>li>a:hover{padding-left:29px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav .nav>li>a:hover{padding-right:29px}.ui-toc-dropdown .nav .nav>li>ul>li>a:focus,.ui-toc-dropdown .nav .nav>li>ul>li>a:hover{padding-left:39px}.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a:focus,.ui-toc-dropdown[dir=rtl] .nav .nav>li>ul>li>a:hover{padding-right:39px}.ui-toc-dropdown .nav .nav>.active:focus>a,.ui-toc-dropdown .nav .nav>.active:hover>a,.ui-toc-dropdown .nav .nav>.active>a{font-weight:500;padding-left:28px}.ui-toc-dropdown[dir=rtl] .nav .nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>a{padding-right:28px}.ui-toc-dropdown .nav .nav>.active>.nav>.active:focus>a,.ui-toc-dropdown .nav .nav>.active>.nav>.active:hover>a,.ui-toc-dropdown .nav .nav>.active>.nav>.active>a{font-weight:500;padding-left:38px}.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active:focus>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active:hover>a,.ui-toc-dropdown[dir=rtl] .nav .nav>.active>.nav>.active>a{padding-right:38px}.markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang^=ja] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang=zh-tw] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang=zh-cn] .markdown-body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang^=ja]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang=zh-tw]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html .markdown-body[lang=zh-cn]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Helvetica,Roboto,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}html[lang^=ja] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ Ｐゴシック,sans-serif}html[lang=zh-tw] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}html[lang=zh-cn] .ui-toc-dropdown{font-family:Source Sans Pro,Helvetica,Arial,Microsoft YaHei UI,微软雅黑UI,sans-serif}html .ui-toc-dropdown[lang^=ja]{font-family:Source Sans Pro,Helvetica,Arial,Meiryo UI,MS PGothic,ＭＳ Ｐゴシック,sans-serif}html .ui-toc-dropdown[lang=zh-tw]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft JhengHei UI,微軟正黑UI,sans-serif}html .ui-toc-dropdown[lang=zh-cn]{font-family:Source Sans Pro,Helvetica,Arial,Microsoft YaHei UI,微软雅黑UI,sans-serif}.ui-affix-toc{max-height:70vh;max-width:15vw;overflow:auto;position:fixed;top:0}.back-to-top,.expand-toggle,.go-to-bottom{color:#999;display:block;font-size:12px;font-weight:500;margin-left:10px;margin-top:10px;padding:4px 10px}.back-to-top:focus,.back-to-top:hover,.expand-toggle:focus,.expand-toggle:hover,.go-to-bottom:focus,.go-to-bottom:hover{color:#563d7c;text-decoration:none}.back-to-top,.go-to-bottom{margin-top:0}.ui-user-icon{background-position:50%;background-repeat:no-repeat;background-size:cover;border-radius:50%;display:block;height:20px;margin-bottom:2px;margin-right:5px;margin-top:2px;width:20px}.ui-user-icon.small{display:inline-block;height:18px;margin:0 0 .2em;vertical-align:middle;width:18px}.ui-infobar>small>span{line-height:22px}.ui-infobar>small .dropdown{display:inline-block}.ui-infobar>small .dropdown a:focus,.ui-infobar>small .dropdown a:hover{text-decoration:none}.ui-more-info{color:#888;cursor:pointer;vertical-align:middle}.ui-more-info .fa{font-size:16px}.ui-connectedGithub,.ui-published-note{color:#888}.ui-connectedGithub{line-height:23px;white-space:nowrap}.ui-connectedGithub a.file-path{color:#888;padding-left:22px;text-decoration:none}.ui-connectedGithub a.file-path:active,.ui-connectedGithub a.file-path:hover{color:#888;text-decoration:underline}.ui-connectedGithub .fa{font-size:20px}.ui-published-note .fa{font-size:20px;vertical-align:top}.unselectable{-webkit-user-select:none;-o-user-select:none;user-select:none}.selectable{-webkit-user-select:text;-o-user-select:text;user-select:text}.inline-spoiler-section{cursor:pointer}.inline-spoiler-section .spoiler-text{background-color:#333;border-radius:2px}.inline-spoiler-section .spoiler-text>*{opacity:0}.inline-spoiler-section .spoiler-img{filter:blur(10px)}.inline-spoiler-section.raw{background-color:#333;border-radius:2px}.inline-spoiler-section.raw>*{opacity:0}.inline-spoiler-section.unveil{cursor:auto}.inline-spoiler-section.unveil .spoiler-text{background-color:#3333331a}.inline-spoiler-section.unveil .spoiler-text>*{opacity:1}.inline-spoiler-section.unveil .spoiler-img{filter:none}@media print{blockquote,div,img,pre,table{page-break-inside:avoid!important}a[href]:after{font-size:12px!important}}.markdown-body.slides{color:#222;position:relative;z-index:1}.markdown-body.slides:before{background-color:currentColor;bottom:0;box-shadow:0 0 0 50vw;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:-1}.markdown-body.slides section[data-markdown]{background-color:#fff;margin-bottom:1.5em;position:relative;text-align:center}.markdown-body.slides section[data-markdown] code{text-align:left}.markdown-body.slides section[data-markdown]:before{content:"";display:block;padding-bottom:56.23%}.markdown-body.slides section[data-markdown]>div:first-child{left:1em;max-height:100%;overflow:hidden;position:absolute;right:1em;top:50%;transform:translateY(-50%)}.markdown-body.slides section[data-markdown]>ul{display:inline-block}.markdown-body.slides>section>section+section:after{border:3px solid #777;content:"";height:1.5em;position:absolute;right:1em;top:-1.5em}.site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,sans-serif}html[lang^=ja] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif}html[lang=zh-tw] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] .site-ui-font{font-family:Source Sans Pro,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}body{font-smoothing:subpixel-antialiased!important;-webkit-font-smoothing:subpixel-antialiased!important;-moz-osx-font-smoothing:auto!important;-webkit-overflow-scrolling:touch;font-family:Source Sans Pro,Helvetica,Arial,sans-serif;letter-spacing:.025em}html[lang^=ja] body{font-family:Source Sans Pro,Helvetica,Arial,Hiragino Kaku Gothic Pro,ヒラギノ角ゴ Pro W3,Osaka,Meiryo,メイリオ,MS Gothic,ＭＳ ゴシック,sans-serif}html[lang=zh-tw] body{font-family:Source Sans Pro,Helvetica,Arial,PingFang TC,Microsoft JhengHei,微軟正黑,sans-serif}html[lang=zh-cn] body{font-family:Source Sans Pro,Helvetica,Arial,PingFang SC,Microsoft YaHei,微软雅黑,sans-serif}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}abbr[data-original-title],abbr[title]{cursor:help}body.modal-open{overflow-y:auto;padding-right:0!important}svg{text-shadow:none}
    </style>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js" integrity="sha256-3Jy/GbSLrg0o9y5Z5n1uw0qxZECH7C6OQpVBgNFYa0g=" crossorigin="anonymous"></script>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js" integrity="sha256-g6iAfvZp+nDQ2TdTR/VVKJf3bGro4ub5fvWSWVRi2NE=" crossorigin="anonymous"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.9/es5-shim.min.js" integrity="sha256-8E4Is26QH0bD52WoQpcB+R/tcWQtpzlCojrybUd7Mxo=" crossorigin="anonymous"></script>
    <![endif]-->
</head>

<body>
    <div id="doc" class="markdown-body container-fluid comment-enabled" data-hard-breaks="false"><style>
ins { background-color: #CCFFCC }
s { background-color: #FFCACA }
blockquote { color: inherit !important }
</style><table>
<tbody><tr>
<td>Document number</td>
<td>P3218R0</td>
</tr>
<tr>
<td>Date</td>
<td>2024-04-09</td>
</tr>
<tr>
<td>Reply-to</td>
<td>
<p><span>Jarrad J. Waterloo &lt;descender76 at gmail dot com&gt;</span></p>
</td>
</tr>
<tr>
<td>Audience</td>
<td>Evolution Working Group (EWG)<br>Core Working Group (CWG)</td>
</tr>
</tbody></table><h1 id="const-references-to-constexpr-variables" data-id="const-references-to-constexpr-variables"><a class="anchor hidden-xs" href="#const-references-to-constexpr-variables" title="const-references-to-constexpr-variables"><span class="octicon octicon-link"></span></a><span>const references to constexpr variables</span></h1><style>
.inline-link
{
    font-size: small;
    margin-top: -2.8em;
    margin-right: 4px;
    text-align: right;
    font-weight: bold;
}

code
{
    font-family: "Fira Code", monospace !important;
    font-size: 0.87em;
}

.sourceCode
{
    font-size: 0.95em;
}

a code
{
    color: #0645ad;
}
</style><h2 id="Table-of-contents" data-id="Table-of-contents"><a class="anchor hidden-xs" href="#Table-of-contents" title="Table-of-contents"><span class="octicon octicon-link"></span></a><span>Table of contents</span></h2><ul>
<li><a href="#const-references-to-constexpr-variables"><span>const references to constexpr variables</span></a>
<ul>
<li><a href="#Abstract"><span>Abstract</span></a></li>
<li><a href="#Simpler"><span>Simpler</span></a></li>
<li><a href="#Safer"><span>Safer</span></a></li>
<li><a href="#Relationship-to-constexpr-wrapper"><span>Relationship to constexpr wrapper</span></a></li>
<li><a href="#Related-Work"><span>Related Work</span></a></li>
<li><a href="#Summary"><span>Summary</span></a></li>
<li><a href="#Frequently-Asked-Questions"><span>Frequently Asked Questions</span></a></li>
<li><a href="#References"><span>References</span></a></li>
</ul>
</li>
</ul><h2 id="Abstract" data-id="Abstract"><a class="anchor hidden-xs" href="#Abstract" title="Abstract"><span class="octicon octicon-link"></span></a><span>Abstract</span></h2><p><span>This proposal is an addendum to the </span><code>"constexpr structured bindings and references to constexpr variables"</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><span> proposal with a focus on simplicity and safety.</span></p><h2 id="Simpler" data-id="Simpler"><a class="anchor hidden-xs" href="#Simpler" title="Simpler"><span class="octicon octicon-link"></span></a><span>Simpler</span></h2><p><span>The </span><code>P2686</code><span>, </span><code>constexpr structured bindings and references to constexpr variables</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1-1">[1:1]</a></sup><span>, proposal outlines 4 solutions to its problem.</span></p><ol>
<li><code>"Allowing static and non-tuple constexpr structured binding"</code></li>
<li><code>"Making constexpr implicitly static"</code></li>
<li><code>"Always re-evaluate a call to get?"</code></li>
<li><code>"Symbolic addressing"</code></li>
</ol><p><span>Of these four, </span><code>P2686</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1-2">[1:2]</a></sup><span> recommends that the first and the last be implemented. Concerning the first, the authors wrote; </span><em><span>"Independently of the other solutions presented here, this option would be useful and should be done"</span></em><span>. Concerning the last, the authors wrote; </span><em><span>"The most promising option - the one we think should be pursued"</span></em><span>.</span></p><p><span>This proposal does not argue for or against the first and the last. To the contrary, this proposal argues that there is a place in at least some [limited] capacity for the second solution, </span><code>Making constexpr implicitly static</code><span>.</span></p><h3 id="given" data-id="given"><a class="anchor hidden-xs" href="#given" title="given"><span class="octicon octicon-link"></span></a><span>given</span></h3><pre><code class="cpp hljs"><span class="token keyword">struct</span> <span class="token class-name">point</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> x<span class="token punctuation">;</span>
    <span class="token keyword">int</span> y<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
    
<span class="token keyword">const</span> point<span class="token operator">&amp;</span> <span class="token function">dangler</span><span class="token punctuation">(</span><span class="token keyword">const</span> point<span class="token operator">&amp;</span> p<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">// ...</span>
    <span class="token keyword">return</span> p<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> <span class="token function">dangler</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> s<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">// ...</span>
    <span class="token keyword">return</span> s<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><h3 id="usage" data-id="usage"><a class="anchor hidden-xs" href="#usage" title="usage"><span class="octicon octicon-link"></span></a><span>usage</span></h3><pre><code class="cpp hljs"><span class="token comment">// {4, 2} is static</span>
<span class="token keyword">const</span> point<span class="token operator">&amp;</span> always_safe <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> point<span class="token operator">&amp;</span> safe <span class="token operator">=</span> <span class="token function">dangler</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// "42"s is static</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> always_safe <span class="token operator">=</span> <span class="token string">"42"</span>s<span class="token punctuation">;</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> safe <span class="token operator">=</span> <span class="token function">dangler</span><span class="token punctuation">(</span><span class="token string">"42"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><span>NOTE: While this proposal is only concerned about "const references to constant expressions" implicity creating constants, it would make sense to end programmers for const variables as well.</span></p><table>
<tbody><tr>
<td>
<pre><code class="cpp hljs"><span class="token comment">// {4, 2} is static</span>
<span class="token keyword">const</span> point<span class="token operator">&amp;</span> always_safe <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// {4, 2} can be static</span>
<span class="token keyword">const</span> point always_safe<span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</td>
</tr>
<tr>
<td>
<pre><code class="cpp hljs"><span class="token comment">// "42"s is static</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> always_safe <span class="token operator">=</span> <span class="token string">"42"</span>s<span class="token punctuation">;</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// "42"s can be static</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string always_safe<span class="token punctuation">{</span><span class="token string">"42"</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</td>
</tr>
</tbody></table><p><span>It should be noted that </span><code>constexpr structured bindings and references to constexpr variables</code><span>'s </span><sup class="footnote-ref"><a href="#fn1" id="fnref1-3">[1:3]</a></sup><span> first option is simpler than the last, at least in wording but is more complex than the last in the sense that it explictly requires the programmer to litter their code with </span><code>static</code><span>. The second option is simpler than both the first and the last options because the static is implied, just as it is at namespace scope, resulting in simplified wording and simplified usage by the end programmers. Are the reasons presented against the second option totally legitimate or could those rare exceptions be handled in such a way that simplicity wouldn't be lost for the greater whole?</span></p><p><span>Let's consider the complete rationale against, before breaking down each point in turn.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>constexpr structured bindings and references to constexpr variables</span></strong><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1-4">[1:4]</a></sup></p>
<p><em><strong><span>"1. Making constexpr implicitly static"</span></strong></em></p>
<p><em><span>"We could make constexpr variables implicitly static, but doing so would most certainly break existing code, in addition to being inconsistent with the meaning of </span><code>constexpr</code><span>:"</span></em></p>
<pre><code class="cpp hljs"><span class="token keyword">int</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">constexpr</span> <span class="token keyword">struct</span> <span class="token class-name">S</span> <span class="token punctuation">{</span>
      <span class="token keyword">mutable</span> <span class="token keyword">int</span> m <span class="token punctuation">;</span>
    <span class="token punctuation">}</span> s<span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token operator">++</span>s<span class="token punctuation">.</span>m<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">assert</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// currently 2. Becomes 3 if 's' is made implicitly static</span>
<span class="token punctuation">}</span>
</code></pre>
<p><em><span>"So this solution is impractical. We could make constexpr static only in some cases to alleviate some of the breakages or even make only constexpr bindings static, not other variables, but this option feels like a hack rather than an actual solution."</span></em></p>
</td>
</tr>
</tbody></table><h3 id="doing-so-would-most-certainly-break-existing-code" data-id="doing-so-would-most-certainly-break-existing-code"><a class="anchor hidden-xs" href="#doing-so-would-most-certainly-break-existing-code" title="doing-so-would-most-certainly-break-existing-code"><span class="octicon octicon-link"></span></a><em><span>"doing so would most certainly break existing code"</span></em></h3><p><span>To the contrary, code that is broken is now fixed. Code that would be invalid is now valid, makes sense and can be rationally explained. Let me explain. This feature not only changes the point of destruction but also the point of construction. Instances that were of automatic storage duration, are now of static storage duration. Instances that were temporaries, are no longer temporaries. Surely, something must be broken! The </span><code>C++</code><span> standard already recognized that their are other opportunities for constant initialization.</span></p><table>
<tbody><tr>
<td>
<p><code>Working Draft, Standard for Programming Language C++</code><span> </span><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p>
<p><strong><span>"</span><em><span>6.9.3.2 Static initialization [basic.start.static]</span></em><span>"</span></strong></p>
<p><span>"</span><em><span>3 An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically </span><span class="smartypants">…</span></em><span>"</span></p>
</td>
</tr>
</tbody></table><p><span>So, what is the point? For the instances that would benefit from implicit constant initialization, their are currently NO guarantees as far as their lifetime and as such is indeterminite. With this portion of the proposal, a guarantee is given and as such that which was non determinite becomes determinite.</span></p><p><span>It should also be noted that while this enhancement is applied implicitly, programmers has opted into this up to three times.</span></p><ol>
<li><span>The programmer of the type must have provided a means for the type to be constructed at compile time likely by having a </span><code>constexpr</code><span> constructor.</span></li>
<li><span>The programmer of the variable or function parameter must have stated that they want a </span><code>const</code><span>.</span></li>
<li><span>The end programmer have </span><code>const-initialized</code><span> the variable or argument.</span></li>
</ol><p><span>Having expressed contant requirements three times, it is pretty certain that the end programmer wanted a constant, even if it is anonymous.</span></p><p><span>Next, a function that takes an argument by reference does not know whether the caller of said function will pass to it a global, local, temporary or a dynamically created object. Rather it expects that said parameter would exist for the life of the function and if the reference is returned, in part or in whole, than the life of the object needs to be longer.</span></p><h3 id="inconsistent-with-the-meaning-of-constexpr" data-id="inconsistent-with-the-meaning-of-constexpr"><a class="anchor hidden-xs" href="#inconsistent-with-the-meaning-of-constexpr" title="inconsistent-with-the-meaning-of-constexpr"><span class="octicon octicon-link"></span></a><em><span>"inconsistent with the meaning of </span><code>constexpr</code><span>"</span></em></h3><p><span>Really! One only have to read the original motivations for </span><code>constexpr</code><span> to realize that </span><code>static</code><span> is consistent with its meaning.</span></p><h4 id="n1511" data-id="n1511"><a class="anchor hidden-xs" href="#n1511" title="n1511"><span class="octicon octicon-link"></span></a><span>n1511</span></h4><table>
<tbody><tr>
<td>
<p><em><strong><code>Literals for user-defined types</code></strong></em><span> </span><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></p>
<p><strong><span>2003</span></strong></p>
<p><em><span>"This note proposes a notion of user-defined literals based on literal constructors without requiring new syntax. If combined with the separate proposal for generalized initializer lists, it becomes a generalization of the C99 notion of compound literals."</span></em></p>
<p><em><span>"However, a constructor is a very general construct and there have been many requests for a way to express literals for user-defined types in such a way that a programmer can be </span><strong><span>confident that a value </span><u><span>will be</span></u><span> constructed at compile time</span></strong><span> and </span><strong><span>potentially stored in ROM</span></strong><span>. For example:"</span></em></p>
<pre><code class="cpp hljs">complex <span class="token function">z</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// the variable z can be constructed at compile time</span>
<span class="token keyword">const</span> complex <span class="token function">cz</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// the const cz can potentially be put in ROM</span>
</code></pre>
<p><em><span>"</span><strong><span>Personally, I prefer (1): basically, a value is a literal if it is composed out of literals and implemented by a literal constructor. The problem with that is that some people will not trust compilers to do proper resolution, placement in ROM, placement in text segment</span></strong><span>"</span></em></p>
<p><em><span>"</span><strong><span>C99 compound literals</span></strong><span>"</span></em></p>
<p><em><span>"In C99, it is explicitly allowed to take the address of a compound literal. For example:"</span></em></p>
<pre><code class="cpp hljs"><span class="token function">f</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">foo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p><em><span>"</span><strong><span>This makes sense only if we assume that the {1,2} is stored in a data segment (like a string literal</span></strong><span>, but different from a int literal). </span><strong><span>I see no problem allowing that</span></strong><span>"</span></em></p>
<p><em><span>"</span><strong><span>It would be tempting to expand this rule to user-defined literals bound to references.</span></strong><span>"</span></em></p>
</td>
</tr>
</tbody></table><h4 id="n2235" data-id="n2235"><a class="anchor hidden-xs" href="#n2235" title="n2235"><span class="octicon octicon-link"></span></a><span>n2235</span></h4><table>
<tbody><tr>
<td>
<p><em><strong><code>Generalized Constant Expressions—Revision 5</code></strong></em><span> </span><sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup></p>
<p><strong><span>2007</span></strong></p>
<p><em><span>"This paper generalizes the notion of constant expressions to include constant-expression functions and user-defined literals"</span></em></p>
<p><em><span>"The goal is </span><span class="smartypants">…</span><span> to </span><strong><span>increase C99 compatibility.</span></strong><span>"</span></em></p>
<p><span class="smartypants">…</span></p>
<p><em><span>"</span><strong><span>simplify the language</span></strong><span> definition in the area of constant expression </span><strong><span>to match existing practice</span></strong><span>"</span></em></p>
<p><span class="smartypants">…</span></p>
<p><em><span>"</span><strong><span>3. Static initialization of objects with static storage.</span></strong><span>"</span></em></p>
<p><em><span>"</span><span class="smartypants">…</span><span> However </span><strong><span>we strive for more uniform and consistency among related C++ language features and compatibility</span></strong><span>"</span></em></p>
<p><em><span>"</span><strong><span>3 Problems</span></strong><span>"</span></em></p>
<p><span class="smartypants">…</span></p>
<p><em><span>"</span><strong><span>3.4 Unexpected dynamic initialization</span></strong><span>"</span></em></p>
<p><em><span>"</span><strong><span>However, it is possible to be surprised by expressions that (to someone) “look const” but are not.</span></strong><span>"</span></em></p>
<p><em><span>"</span><strong><span>3.5 Complex rules for simple things</span></strong><span>"</span></em></p>
<p><em><span>"The focus of this proposal is to address the issues mentioned in preceding sections. However, discussions in the Core Working Group at the Berlin meeting (April 2006) concluded that the current rules for integral constant expressions are too complicated, and source of several Defect Reports. </span><strong><span>Consequently, a “cleanup”, i.e. adoption of simpler, more general rules is suggested.</span></strong><span>"</span></em></p>
<p><span class="smartypants">…</span></p>
<p><em><span>"As for other const variables, storage need not be allocated for a constant expression datum, unless its address is taken."</span></em></p>
<pre><code class="cpp hljs"><span class="token comment">// the &amp;x forces x into memory</span>
</code></pre>
<p><em><strong><span>"When the initializer for an ordinary variable (i.e. not a constexpr) happens to be a constant, the compiler can choose to do dynamic or static initialization (as ever)."</span></strong></em></p>
<p><em><strong><span>"Declaring a constructor constexpr will help compilers to identify static initialization and perform appropriate optimizations (like putting literals in read-only memory.) Note that since “ROM” isn’t a concept of the C++ Standard and what to put into ROM is often a quite subtle design decision, this proposal simply allows the programmer to indicate what might be put into ROM (constant-expression data) rather than trying to specify what actually goes into ROM in a particular implementation."</span></strong></em></p>
<p><em><strong><span>"We do not propose to make constexpr a storage-class-specifier because it can be combined with either static or extern or register, much like const."</span></strong></em></p>
</td>
</tr>
</tbody></table><p><span>One of the main motivations for </span><code>constexpr</code><span> was for objects to be placed in </span><code>ROM</code><span>. What is read only memory, if not const and static storage duration!</span></p><h3 id="the-mutable-example" data-id="the-mutable-example"><a class="anchor hidden-xs" href="#the-mutable-example" title="the-mutable-example"><span class="octicon octicon-link"></span></a><em><span>"the mutable example"</span></em></h3><pre><code class="cpp hljs"><span class="token keyword">int</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">constexpr</span> <span class="token keyword">struct</span> <span class="token class-name">S</span> <span class="token punctuation">{</span>
      <span class="token keyword">mutable</span> <span class="token keyword">int</span> m <span class="token punctuation">;</span>
    <span class="token punctuation">}</span> s<span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token operator">++</span>s<span class="token punctuation">.</span>m<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">assert</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// currently 2. Becomes 3 if 's' is made implicitly static</span>
<span class="token punctuation">}</span>
</code></pre><p><span>It's a shame that mutable is permitted to be used in constant expressions as it is rarely used, actively discouraged and potentially disabled by future safety enhancements. It is barely rational to have mutation associated with something associated with ROM as that typically brings about segmentation faults. It is also unnatural since template, constexpr and consteval functions are C++'s closest thing to pure functions. One can hardly say in the example f() is pure if it sometimes return 1 and another time returns 2, given the same arguments. The damage is done but also mostly irrelevant, with respect to this proposal. We'll see this in the next point but before moving on to it, keep in mind that the example is not an example of taking a reference to constexpr variable, more less a const reference to constexpr variable.</span></p><h3 id="We-could-make-constexpr-static-only-in-some-cases-to-alleviate-some-of-the-breakages-or-even-make-only-constexpr-bindings-static-not-other-variables-but-this-option-feels-like-a-hack-rather-than-an-actual-solution" data-id="We-could-make-constexpr-static-only-in-some-cases-to-alleviate-some-of-the-breakages-or-even-make-only-constexpr-bindings-static-not-other-variables-but-this-option-feels-like-a-hack-rather-than-an-actual-solution"><a class="anchor hidden-xs" href="#We-could-make-constexpr-static-only-in-some-cases-to-alleviate-some-of-the-breakages-or-even-make-only-constexpr-bindings-static-not-other-variables-but-this-option-feels-like-a-hack-rather-than-an-actual-solution" title="We-could-make-constexpr-static-only-in-some-cases-to-alleviate-some-of-the-breakages-or-even-make-only-constexpr-bindings-static-not-other-variables-but-this-option-feels-like-a-hack-rather-than-an-actual-solution"><span class="octicon octicon-link"></span></a><em><span>"We could make constexpr static only in some cases to alleviate some of the breakages or even make only constexpr bindings static, not other variables, but this option feels like a hack rather than an actual solution."</span></em></h3><p><span>Actually, no it doesn't. It is rather consistent with what is already proposed for C++26.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>P2752R3</span><br><span>Static storage for braced initializers</span></strong><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup></p>
<p><strong><span>4. Mutable members</span></strong></p>
<p><span class="smartypants">…</span></p>
<p><span>Vendors are expected to deal with this by simply disabling their promote-to-shared-storage optimization when the element type (recursively) contains any mutable bits.</span></p>
<p><span class="smartypants">…</span></p>
<p><strong><span>7. Proposed wording relative to the current C++23 draft</span></strong></p>
<p><span class="smartypants">…</span></p>
<p><span>[Example 12:</span></p>
<pre><code class="cpp hljs">    <span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>initializer_list<span class="token operator">&lt;</span><span class="token keyword">double</span><span class="token operator">&gt;</span> il<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">g</span><span class="token punctuation">(</span><span class="token keyword">float</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> x<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token function">h</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">struct</span> <span class="token class-name">A</span> <span class="token punctuation">{</span>
      <span class="token keyword">mutable</span> <span class="token keyword">int</span> i<span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">q</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>initializer_list<span class="token operator">&lt;</span>A<span class="token operator">&gt;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">r</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token function">q</span><span class="token punctuation">(</span><span class="token punctuation">{</span>A<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span> A<span class="token punctuation">{</span><span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">,</span> A<span class="token punctuation">{</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre>
<p><span>The initializations can be implemented in a way roughly equivalent to this:</span></p>
<pre><code class="cpp hljs">    <span class="token keyword">void</span> <span class="token function">g</span><span class="token punctuation">(</span><span class="token keyword">float</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token keyword">double</span> __a<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token keyword">double</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">{</span>x<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">{</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// backing array</span>
      <span class="token function">f</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">initializer_list</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">double</span><span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>__a<span class="token punctuation">,</span> __a<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token function">h</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">static</span> <span class="token keyword">constexpr</span> <span class="token keyword">double</span> __b<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token keyword">double</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">{</span><span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">{</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// backing array</span>
      <span class="token function">f</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">initializer_list</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">double</span><span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>__b<span class="token punctuation">,</span> __b<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token function">r</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> A __c<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span>A<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span> A<span class="token punctuation">{</span><span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">,</span> A<span class="token punctuation">{</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// backing array</span>
      <span class="token function">q</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">initializer_list</span><span class="token generic class-name"><span class="token operator">&lt;</span>A<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>__c<span class="token punctuation">,</span> __c<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre>
</td>
</tr>
</tbody></table><p><span>This already accepted solution to the mutable problem could also be used as the solution to the mutable problem of this proposal.</span></p><h2 id="Safer" data-id="Safer"><a class="anchor hidden-xs" href="#Safer" title="Safer"><span class="octicon octicon-link"></span></a><span>Safer</span></h2><p><span>Besides simplicity, why does this proposal recommend that const references to constexpr variables have static storage duration? One word, safety. These objects would be impossible to dangle and also would be thread safe. This also fixes one of C++'s most embarassing forms of dangling; dangling constants. This problem is unique to C++. Practically all languages, except C++, doesn't immediately dangle their constants, not even assembly, C, or even the earliest version of C++, cfront.</span></p><p><span>Things are even worse in C++ because as programmers we can't look at the code and know for sure whether an object is static or not. This requires C++ programmers even beginners to have to look at machine code to see how the compiler decided where to store the object. Not only does this vary from compiler to compiler, it also varies within any given compiler. Frequently in optimized release builds these constant objects are given static duration but made a dangling local in debug builds. This is totally backwards, as the increased safety is expected in debug builds.</span></p><p><span>Futher if the optimized build is both the safest and the better performant then why shouldn't it be available always! Dangling constants is like returning from a function using an input parameter in pre C++11 because programmers did not have sufficient assurance that "return value optimization" would occur.</span></p><p><span>Similarly, programmers have to name the currently unnamed temporary and move it far from the point of use, just to ensure dangling doesn't occur in both debug and release builds. This habit works against the recommendation to use unnamed [temporary] variables and move semantics.</span></p><h2 id="Relationship-to-constexpr-wrapper" data-id="Relationship-to-constexpr-wrapper"><a class="anchor hidden-xs" href="#Relationship-to-constexpr-wrapper" title="Relationship-to-constexpr-wrapper"><span class="octicon octicon-link"></span></a><span>Relationship to constexpr wrapper</span></h2><p><span>This proposal is related to the </span><code>std::constexpr_wrapper</code><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup><span> proposal on the safety level. While that proposal explicity creates safe anonymously named constants as a library, this proposal would be an implicit language feature. As a language feature, there are a couple of advantages.</span></p><ol>
<li><code>std::constexpr_wrapper</code><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6-1">[6:1]</a></sup><span> only works with structural types as those are currently the only types permitted for non type template parameters. This proposal can work with all types that haven't deleted their reference of operators.</span></li>
<li><span>simpler and more consistent, not having to resort to different libraries for structural and non structural types</span></li>
</ol><table>
<tbody><tr>
<td>&nbsp;</td>
<td>
<p><code>this proposal</code></p>
</td>
<td>
<p><code>std::constexpr_wrapper</code><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6-2">[6:2]</a></sup></p>
</td>
</tr>    
<tr>
<td>
<p><code>structural type</code></p>
</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// {4, 2} is static</span>
<span class="token keyword">const</span> point<span class="token operator">&amp;</span> safe <span class="token operator">=</span> <span class="token function">dangler</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// {4, 2} is a temporary</span>
<span class="token keyword">const</span> point<span class="token operator">&amp;</span> safe <span class="token operator">=</span> <span class="token function">dangler</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>cw<span class="token operator">&lt;</span><span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token operator">&gt;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td>
</tr>    
<tr>
<td>
<p><span>non </span><code>structural type</code></p>
</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// "42"s is static</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> safe <span class="token operator">=</span> <span class="token function">dangler</span><span class="token punctuation">(</span><span class="token string">"42"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// "42"s is a temporary</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> safe <span class="token operator">=</span> <span class="token function">dangler</span><span class="token punctuation">(</span>
    <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token comment">/*consteval*/</span> <span class="token operator">-&gt;</span> <span class="token keyword">auto</span> <span class="token keyword">const</span> <span class="token operator">&amp;</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">static</span> <span class="token keyword">constinit</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string anonymous<span class="token punctuation">{</span><span class="token string">"42"</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> anonymous<span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td>
</tr>    
</tbody></table><p><span>As demonstrated in the previous examples, the result of this proposal is that the same simple syntax is used regardless of whether the type was structural or not, while the current state of affairs require using a lambda function in order to provide an anonymously named constant.</span></p><h2 id="Related-Work" data-id="Related-Work"><a class="anchor hidden-xs" href="#Related-Work" title="Related-Work"><span class="octicon octicon-link"></span></a><span>Related Work</span></h2><p><span>A similar but more complicated feature exists in the Rust programming languge known as </span><code>rvalue static promotion</code><span> </span><sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup><span>. This makes sense for Rust as all types are by default movable. Similarly, the proposed feature would work for C++ since by default all types are referable.</span></p><pre><code class="rust hljs"><span class="token keyword">let</span> x<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'static</span> <span class="token keyword">u32</span> <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token number">42</span><span class="token punctuation">;</span>
</code></pre><p><span>The proposed feature would be simpler than </span><code>rust</code><span> as it doesn't require an explicit </span><code>'static</code><span> lifetime but rather would be implied because the would be temporary was </span><code>constexpr</code><span> capable, initialized with only constants and was initially assigned to a </span><code>const &amp;</code><span>.</span></p><p><span>More verbose information on the motivation for this proposed feature also exists in the previous </span><code>constant dangling</code><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup><span> proposal.</span></p><h2 id="Summary" data-id="Summary"><a class="anchor hidden-xs" href="#Summary" title="Summary"><span class="octicon octicon-link"></span></a><span>Summary</span></h2><p><span>"Making constexpr implicitly static" </span><sup class="footnote-ref"><a href="#fn1" id="fnref1-5">[1:5]</a></sup><span> for constants makes the language simpler and at least for constant references makes the language safer. Like the </span><code>Static storage for braced initializers</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5-1">[5:1]</a></sup><span> proposal it would minimize "CPU cycles", "stack space" and heap allocations caused by types that dynamically allocate such </span><code>std::string</code><span> and </span><code>std::vector</code><span> when they are better off being a constant.</span></p><h2 id="Frequently-Asked-Questions" data-id="Frequently-Asked-Questions"><a class="anchor hidden-xs" href="#Frequently-Asked-Questions" title="Frequently-Asked-Questions"><span class="octicon octicon-link"></span></a><span>Frequently Asked Questions</span></h2><h3 id="Who-would-even-use-these-features-Their-isnt-sufficient-use-to-justify-these-changes" data-id="Who-would-even-use-these-features-Their-isnt-sufficient-use-to-justify-these-changes"><a class="anchor hidden-xs" href="#Who-would-even-use-these-features-Their-isnt-sufficient-use-to-justify-these-changes" title="Who-would-even-use-these-features-Their-isnt-sufficient-use-to-justify-these-changes"><span class="octicon octicon-link"></span></a><span>Who would even use these features? Their isn't sufficient use to justify these changes.</span></h3><p><span>The best proof can be found in our usage and other proposals.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>C++ Core Guidelines</span></strong>
<em><strong><span>F.16: For "in" parameters, pass</span></strong><span> cheaply-copied types by value and others </span><strong><span>by reference to const</span></strong></em><span> </span><sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>In </span><code>C++</code><span>, we use </span><code>const</code><span> parameters alot. This is the first of three requirements of </span><code>implicit constant initialization</code><span>. What about the use of types that can be constructed at compile time?</span></p><ul>
<li><strong><code>C++20</code></strong><span>: </span><code>std::pair</code><span>, </span><code>std::tuple</code><span>, </span><code>std::string</code><span>, </span><code>std::vector</code></li>
<li><strong><code>C++23</code></strong><span>: </span><code>std::optional</code><span>, </span><code>std::variant</code><span>, </span><code>std::unique_ptr</code></li>
</ul><p><span>As their was sufficient use to justify making the constructors of any one of these listed above types to be </span><code>constexpr</code><span> than their would be sufficient use of the </span><code>implicit constant initialization</code><span> feature which would use them all as this satisfies its first and second of the three requirements that the instances be constructable at compile time and that they </span><code>const</code><span>.</span></p><ol>
<li><strong><span>The programmer of the type must have provided a means for the type to be constructed at compile time likely by having a </span><code>constexpr</code><span> constructor.</span></strong></li>
<li><strong><span>The programmer of the variable or function parameter must have stated that they want a </span><code>const</code><span>.</span></strong></li>
<li><span>The end programmer have </span><code>const-initialized</code><span> the variable or argument.</span></li>
</ol><h3 id="Doesnt-this-make-C-harder-to-teach" data-id="Doesnt-this-make-C-harder-to-teach"><a class="anchor hidden-xs" href="#Doesnt-this-make-C-harder-to-teach" title="Doesnt-this-make-C-harder-to-teach"><span class="octicon octicon-link"></span></a><span>Doesn't this make C++ harder to teach?</span></h3><p><span>Until the day that all dangling gets fixed, any incremental compile time fixes to dangling still would require programmers to be able to identify any remaining dangling and know how to fix it specific to the given scenario, as there are multiple solutions. Since dangling occurs even for things as simple as constants than dangling resolution still have to be taught, even to beginners. As this proposal fixes these types of dangling, it makes teaching </span><code>C++</code><span> easier because it makes </span><code>C++</code><span> easier.</span></p><p><span>So, what do we teach now and what bearing does these teachings, the </span><code>C++</code><span> standard and this proposal have on one another.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>C++ Core Guidelines</span></strong><br><strong><span>F.42: Return a </span><code>T*</code><span> to indicate a position (only)</span></strong><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10">[10]</a></sup><br><em><strong><span>Note</span></strong><span> Do not return a pointer to something that is not in the caller’s scope; see F.43.</span></em><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11">[11]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>Returning references to something in the caller's scope is only natural. It is a part of our reference delegating programming model. A function when given a reference does not know how the instance was created and it doesn't care as long as it is good for the life of the function call (and beyond).  Unfortunately, scoping temporary arguments to the statement instead of the containing block doesn't just create immediate dangling but it provides to functions references to instances that are near death. These instances are almost dead on arrival. Having the ability to return a reference to a caller's instance or a sub-instance thereof assumes, correctly, that reference from the caller's scope would still be alive after this function call. The fact that temporary rules shortened the life to the statement is at odds with what we teach. This proposal extends the lifetimes of some temporaries, making them global which is not only natural but also consistent with what programmers already know. It is also in line with what we teach as was codified in the C++ Core Guidelines.</span></p><p><span>Other types of dangling can still occur. One simple type is directly called out in the C++ Core Guidelines.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>C++ Core Guidelines</span></strong><br><strong><span>F.43: Never (directly or indirectly) return a pointer or a reference to a local object</span></strong><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11-1">[11:1]</a></sup></p>
<p><em><strong><span>Reason</span></strong><span> To avoid the crashes and data corruption that can result from the use of such a dangling pointer.</span></em><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11-2">[11:2]</a></sup></p>
<p><span class="smartypants">…</span></p>
<p><em><strong><span>Note</span></strong><span> This applies only to non-static local variables. </span><u><span>All static variables</span></u><span> are (as their name indicates) statically allocated, so that pointers to them </span><u><span>cannot dangle</span></u><span>.</span></em><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11-3">[11:3]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>Other than turning some of these locals into globals, this proposal does not solve nor contradict this teaching. If anything, by cleaning up, the remaining dangling is made all the more visible.</span></p><p><span>Further, what is proposed is easy to teach because we already teach it and it makes </span><code>C++</code><span> even easier to teach.</span></p><ul>
<li><span>We already teach that native string literals don't dangle because they have static storage duration. This proposal just extends the concept to constants, as expected. This increases good consistency and reduces a bifurcation that is currently taught.</span></li>
<li><span>Somehow, we already teach the temporary lifetime extension rules which consist of numerous paragraphs and exception examples. This is just another lifetime extension but instead of extending an object's lifetime from being scoped to the statement to instead be scoped globally and not the block.</span></li>
</ul><p><span>All of this can be done without adding any new keywords or any new attributes. We just use constant concepts that beginners are already familiar with. In fact, we will would be working in harmony with all that we already teach about globals in the </span><code>Core C++ Guidelines</code><span> </span><sup class="footnote-ref"><a href="#fn12" id="fnref12">[12]</a></sup><span>.</span></p><ul>
<li><code>I.2: Avoid non-const global variables</code><span> </span><sup class="footnote-ref"><a href="#fn13" id="fnref13">[13]</a></sup></li>
<li><code>I.22: Avoid complex initialization of global objects</code><span> </span><sup class="footnote-ref"><a href="#fn14" id="fnref14">[14]</a></sup></li>
<li><code>F.15: Prefer simple and conventional ways of passing information</code><span> </span><sup class="footnote-ref"><a href="#fn15" id="fnref15">[15]</a></sup></li>
<li><code>F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const</code><span> </span><sup class="footnote-ref"><a href="#fn16" id="fnref16">[16]</a></sup></li>
<li><code>F.43: Never (directly or indirectly) return a pointer or a reference to a local object</code><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11-4">[11:4]</a></sup></li>
<li><code>R.5: Prefer scoped objects, don’t heap-allocate unnecessarily</code><span> </span><sup class="footnote-ref"><a href="#fn17" id="fnref17">[17]</a></sup></li>
<li><code>R.6: Avoid non-const global variables</code><span> </span><sup class="footnote-ref"><a href="#fn18" id="fnref18">[18]</a></sup></li>
<li><code>CP.2: Avoid data races</code><span> </span><sup class="footnote-ref"><a href="#fn19" id="fnref19">[19]</a></sup></li>
<li><code>CP.24: Think of a thread as a global container</code><span> </span><sup class="footnote-ref"><a href="#fn20" id="fnref20">[20]</a></sup></li>
<li><code>CP.32: To share ownership between unrelated threads use shared_ptr</code><span> </span><sup class="footnote-ref"><a href="#fn21" id="fnref21">[21]</a></sup></li>
</ul><h2 id="References" data-id="References"><a class="anchor hidden-xs" href="#References" title="References"><span class="octicon octicon-link"></span></a><span>References</span></h2><hr class="footnotes-sep"><section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2686r3.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2686r3.pdf</span></a> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1-1" class="footnote-backref">↩︎</a> <a href="#fnref1-2" class="footnote-backref">↩︎</a> <a href="#fnref1-3" class="footnote-backref">↩︎</a> <a href="#fnref1-4" class="footnote-backref">↩︎</a> <a href="#fnref1-5" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf</span></a> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1511.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1511.pdf</span></a> <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf</span></a> <a href="#fnref4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2752r3.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2752r3.html</span></a> <a href="#fnref5" class="footnote-backref">↩︎</a> <a href="#fnref5-1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2781r4.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2781r4.html</span></a> <a href="#fnref6" class="footnote-backref">↩︎</a> <a href="#fnref6-1" class="footnote-backref">↩︎</a> <a href="#fnref6-2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn7" class="footnote-item"><p><a href="https://rust-lang.github.io/rfcs/1414-rvalue_static_promotion.html" target="_blank" rel="noopener"><span>https://rust-lang.github.io/rfcs/1414-rvalue_static_promotion.html</span></a> <a href="#fnref7" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn8" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2724r1.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2724r1.html</span></a> <a href="#fnref8" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn9" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-in" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-in</span></a> <a href="#fnref9" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn10" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f42-return-a-t-to-indicate-a-position-only" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f42-return-a-t-to-indicate-a-position-only</span></a> <a href="#fnref10" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn11" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f43-never-directly-or-indirectly-return-a-pointer-or-a-reference-to-a-local-object" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f43-never-directly-or-indirectly-return-a-pointer-or-a-reference-to-a-local-object</span></a> <a href="#fnref11" class="footnote-backref">↩︎</a> <a href="#fnref11-1" class="footnote-backref">↩︎</a> <a href="#fnref11-2" class="footnote-backref">↩︎</a> <a href="#fnref11-3" class="footnote-backref">↩︎</a> <a href="#fnref11-4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn12" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines</span></a> <a href="#fnref12" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn13" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i2-avoid-non-const-global-variables" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i2-avoid-non-const-global-variables</span></a> <a href="#fnref13" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn14" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i22-avoid-complex-initialization-of-global-objects" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i22-avoid-complex-initialization-of-global-objects</span></a> <a href="#fnref14" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn15" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f15-prefer-simple-and-conventional-ways-of-passing-information" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f15-prefer-simple-and-conventional-ways-of-passing-information</span></a> <a href="#fnref15" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn16" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f16-for-in-parameters-pass-cheaply-copied-types-by-value-and-others-by-reference-to-const" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f16-for-in-parameters-pass-cheaply-copied-types-by-value-and-others-by-reference-to-const</span></a> <a href="#fnref16" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn17" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r5-prefer-scoped-objects-dont-heap-allocate-unnecessarily" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r5-prefer-scoped-objects-dont-heap-allocate-unnecessarily</span></a> <a href="#fnref17" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn18" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r6-avoid-non-const-global-variables" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r6-avoid-non-const-global-variables</span></a> <a href="#fnref18" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn19" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp2-avoid-data-races" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp2-avoid-data-races</span></a> <a href="#fnref19" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn20" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp24-think-of-a-thread-as-a-global-container" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp24-think-of-a-thread-as-a-global-container</span></a> <a href="#fnref20" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn21" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp32-to-share-ownership-between-unrelated-threads-use-shared_ptr" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp32-to-share-ownership-between-unrelated-threads-use-shared_ptr</span></a> <a href="#fnref21" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section></div>
    <div class="ui-toc dropup unselectable hidden-print" style="display:none;">
        <div class="pull-right dropdown">
            <a id="tocLabel" class="ui-toc-label btn btn-default" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false" title="Table of content">
                <i class="fa fa-bars"></i>
            </a>
            <ul id="ui-toc" class="ui-toc-dropdown dropdown-menu" aria-labelledby="tocLabel">
                <div class="toc"><ul class="nav">
<li class=""><a href="#const-references-to-constexpr-variables" title="const references to constexpr variables">const references to constexpr variables</a><ul class="nav">
<li class=""><a href="#Table-of-contents" title="Table of contents">Table of contents</a></li>
<li class=""><a href="#Abstract" title="Abstract">Abstract</a></li>
<li class=""><a href="#Simpler" title="Simpler">Simpler</a><ul class="nav">
<li class=""><a href="#given" title="given">given</a></li>
<li class=""><a href="#usage" title="usage">usage</a></li>
<li class=""><a href="#doing-so-would-most-certainly-break-existing-code" title="&quot;doing so would most certainly break existing code&quot;">"doing so would most certainly break existing code"</a></li>
<li class=""><a href="#inconsistent-with-the-meaning-of-constexpr" title="&quot;inconsistent with the meaning of constexpr&quot;">"inconsistent with the meaning of constexpr"</a></li>
<li><a href="#the-mutable-example" title="&quot;the mutable example&quot;">"the mutable example"</a></li>
<li><a href="#We-could-make-constexpr-static-only-in-some-cases-to-alleviate-some-of-the-breakages-or-even-make-only-constexpr-bindings-static-not-other-variables-but-this-option-feels-like-a-hack-rather-than-an-actual-solution" title="&quot;We could make constexpr static only in some cases to alleviate some of the breakages or even make only constexpr bindings static, not other variables, but this option feels like a hack rather than an actual solution.&quot;">"We could make constexpr static only in some cases to alleviate some of the breakages or even make only constexpr bindings static, not other variables, but this option feels like a hack rather than an actual solution."</a></li>
</ul>
</li>
<li><a href="#Safer" title="Safer">Safer</a></li>
<li><a href="#Relationship-to-constexpr-wrapper" title="Relationship to constexpr wrapper">Relationship to constexpr wrapper</a></li>
<li><a href="#Related-Work" title="Related Work">Related Work</a></li>
<li><a href="#Summary" title="Summary">Summary</a></li>
<li><a href="#Frequently-Asked-Questions" title="Frequently Asked Questions">Frequently Asked Questions</a><ul class="nav">
<li><a href="#Who-would-even-use-these-features-Their-isnt-sufficient-use-to-justify-these-changes" title="Who would even use these features? Their isn't sufficient use to justify these changes.">Who would even use these features? Their isn't sufficient use to justify these changes.</a></li>
<li><a href="#Doesnt-this-make-C-harder-to-teach" title="Doesn't this make C++ harder to teach?">Doesn't this make C++ harder to teach?</a></li>
</ul>
</li>
<li class=""><a href="#References" title="References">References</a></li>
</ul>
</li>
</ul>
</div><div class="toc-menu"><a class="expand-toggle" href="#">Expand all</a><a class="back-to-top" href="#">Back to top</a><a class="go-to-bottom" href="#">Go to bottom</a></div>
            </ul>
        </div>
    </div>
    <div id="ui-toc-affix" class="ui-affix-toc ui-toc-dropdown unselectable hidden-print" data-spy="affix" style="top:17px;display:none;"  >
        <div class="toc"><ul class="nav">
<li class=""><a href="#const-references-to-constexpr-variables" title="const references to constexpr variables">const references to constexpr variables</a><ul class="nav">
<li class=""><a href="#Table-of-contents" title="Table of contents">Table of contents</a></li>
<li class=""><a href="#Abstract" title="Abstract">Abstract</a></li>
<li class=""><a href="#Simpler" title="Simpler">Simpler</a><ul class="nav">
<li class=""><a href="#given" title="given">given</a></li>
<li class=""><a href="#usage" title="usage">usage</a></li>
<li class=""><a href="#doing-so-would-most-certainly-break-existing-code" title="&quot;doing so would most certainly break existing code&quot;">"doing so would most certainly break existing code"</a></li>
<li class=""><a href="#inconsistent-with-the-meaning-of-constexpr" title="&quot;inconsistent with the meaning of constexpr&quot;">"inconsistent with the meaning of constexpr"</a></li>
<li><a href="#the-mutable-example" title="&quot;the mutable example&quot;">"the mutable example"</a></li>
<li><a href="#We-could-make-constexpr-static-only-in-some-cases-to-alleviate-some-of-the-breakages-or-even-make-only-constexpr-bindings-static-not-other-variables-but-this-option-feels-like-a-hack-rather-than-an-actual-solution" title="&quot;We could make constexpr static only in some cases to alleviate some of the breakages or even make only constexpr bindings static, not other variables, but this option feels like a hack rather than an actual solution.&quot;">"We could make constexpr static only in some cases to alleviate some of the breakages or even make only constexpr bindings static, not other variables, but this option feels like a hack rather than an actual solution."</a></li>
</ul>
</li>
<li><a href="#Safer" title="Safer">Safer</a></li>
<li><a href="#Relationship-to-constexpr-wrapper" title="Relationship to constexpr wrapper">Relationship to constexpr wrapper</a></li>
<li><a href="#Related-Work" title="Related Work">Related Work</a></li>
<li><a href="#Summary" title="Summary">Summary</a></li>
<li><a href="#Frequently-Asked-Questions" title="Frequently Asked Questions">Frequently Asked Questions</a><ul class="nav">
<li><a href="#Who-would-even-use-these-features-Their-isnt-sufficient-use-to-justify-these-changes" title="Who would even use these features? Their isn't sufficient use to justify these changes.">Who would even use these features? Their isn't sufficient use to justify these changes.</a></li>
<li><a href="#Doesnt-this-make-C-harder-to-teach" title="Doesn't this make C++ harder to teach?">Doesn't this make C++ harder to teach?</a></li>
</ul>
</li>
<li class=""><a href="#References" title="References">References</a></li>
</ul>
</li>
</ul>
</div><div class="toc-menu"><a class="expand-toggle" href="#">Expand all</a><a class="back-to-top" href="#">Back to top</a><a class="go-to-bottom" href="#">Go to bottom</a></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous" defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.6.0/gist-embed.min.js" integrity="sha256-KyF2D6xPIJUW5sUDSs93vWyZm+1RzIpKCexxElmxl8g=" crossorigin="anonymous" defer></script>
    <script>
        var markdown = $(".markdown-body");
        //smooth all hash trigger scrolling
        function smoothHashScroll() {
            var hashElements = $("a[href^='#']").toArray();
            for (var i = 0; i < hashElements.length; i++) {
                var element = hashElements[i];
                var $element = $(element);
                var hash = element.hash;
                if (hash) {
                    $element.on('click', function (e) {
                        // store hash
                        var hash = this.hash;
                        if ($(hash).length <= 0) return;
                        // prevent default anchor click behavior
                        e.preventDefault();
                        // animate
                        $('body, html').stop(true, true).animate({
                            scrollTop: $(hash).offset().top
                        }, 100, "linear", function () {
                            // when done, add hash to url
                            // (default click behaviour)
                            window.location.hash = hash;
                        });
                    });
                }
            }
        }

        smoothHashScroll();
        var toc = $('.ui-toc');
        var tocAffix = $('.ui-affix-toc');
        var tocDropdown = $('.ui-toc-dropdown');
        //toc
        tocDropdown.click(function (e) {
            e.stopPropagation();
        });

        var enoughForAffixToc = true;

        function generateScrollspy() {
            $(document.body).scrollspy({
                target: ''
            });
            $(document.body).scrollspy('refresh');
            if (enoughForAffixToc) {
                toc.hide();
                tocAffix.show();
            } else {
                tocAffix.hide();
                toc.show();
            }
            $(document.body).scroll();
        }

        function windowResize() {
            //toc right
            var paddingRight = parseFloat(markdown.css('padding-right'));
            var right = ($(window).width() - (markdown.offset().left + markdown.outerWidth() - paddingRight));
            toc.css('right', right + 'px');
            //affix toc left
            var newbool;
            var rightMargin = (markdown.parent().outerWidth() - markdown.outerWidth()) / 2;
            //for ipad or wider device
            if (rightMargin >= 133) {
                newbool = true;
                var affixLeftMargin = (tocAffix.outerWidth() - tocAffix.width()) / 2;
                var left = markdown.offset().left + markdown.outerWidth() - affixLeftMargin;
                tocAffix.css('left', left + 'px');
            } else {
                newbool = false;
            }
            if (newbool != enoughForAffixToc) {
                enoughForAffixToc = newbool;
                generateScrollspy();
            }
        }
        $(window).resize(function () {
            windowResize();
        });
        $(document).ready(function () {
            windowResize();
            generateScrollspy();
        });

        //remove hash
        function removeHash() {
            window.location.hash = '';
        }

        var backtotop = $('.back-to-top');
        var gotobottom = $('.go-to-bottom');

        backtotop.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (scrollToTop)
                scrollToTop();
            removeHash();
        });
        gotobottom.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (scrollToBottom)
                scrollToBottom();
            removeHash();
        });

        var toggle = $('.expand-toggle');
        var tocExpand = false;

        checkExpandToggle();
        toggle.click(function (e) {
            e.preventDefault();
            e.stopPropagation();
            tocExpand = !tocExpand;
            checkExpandToggle();
        })

        function checkExpandToggle () {
            var toc = $('.ui-toc-dropdown .toc');
            var toggle = $('.expand-toggle');
            if (!tocExpand) {
                toc.removeClass('expand');
                toggle.text('Expand all');
            } else {
                toc.addClass('expand');
                toggle.text('Collapse all');
            }
        }

        function scrollToTop() {
            $('body, html').stop(true, true).animate({
                scrollTop: 0
            }, 100, "linear");
        }

        function scrollToBottom() {
            $('body, html').stop(true, true).animate({
                scrollTop: $(document.body)[0].scrollHeight
            }, 100, "linear");
        }
    </script>
</body>

</html>
