<!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>
        Reference checking - 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{background-color:#f7f7f7;border-radius:3px;font-size:85%;line-height:1.45;overflow:auto;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>p:last-child{margin-bottom: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 .alert>p:last-child,.markdown-body .alert>ul:last-child{margin-bottom:0}.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>P2878R2</td>
</tr>
<tr>
<td>Date</td>
<td>2023-6-10</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>SG23 Safety and Security</td>
</tr>
</tbody></table><h1 id="Reference-checking" data-id="Reference-checking"><a class="anchor hidden-xs" href="#Reference-checking" title="Reference-checking"><span class="octicon octicon-link"></span></a><span>Reference checking</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="#Reference-checking"><span>Reference checking</span></a>
<ul>
<li><a href="#Changelog"><span>Changelog</span></a></li>
<li><a href="#Abstract"><span>Abstract</span></a></li>
<li><a href="#Motivational-Example"><span>Motivational Example</span></a></li>
<li><a href="#Motivation"><span>Motivation</span></a></li>
<li><a href="#Other-Proposals"><span>Other Proposals</span></a>
<ul>
<li><a href="#Impact-on-general-lifetime-safety"><span>Impact on general lifetime safety</span></a></li>
<li><a href="#Impact-on-Contracts"><span>Impact on Contracts</span></a></li>
</ul>
</li>
<li><a href="#Technical-Details"><span>Technical Details</span></a>
<ul>
<li><a href="#Structs-and-Classes"><span>Structs and Classes</span></a></li>
<li><a href="#Impact-on-Pattern-Matching"><span>Impact on Pattern Matching</span></a></li>
</ul>
</li>
<li><a href="#Resolution"><span>Resolution</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="Changelog" data-id="Changelog"><a class="anchor hidden-xs" href="#Changelog" title="Changelog"><span class="octicon octicon-link"></span></a><span>Changelog</span></h2><h3 id="R2" data-id="R2"><a class="anchor hidden-xs" href="#R2" title="R2"><span class="octicon octicon-link"></span></a><span>R2</span></h3><ul>
<li><span>fixed </span><code>f3</code><span> example of returning a </span><code>struct</code></li>
<li><span>revised comments of </span><code>4th check</code><span> example</span></li>
<li><span>added resolved resolution example</span></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 paper proposes that we allow programmers to provide explicit lifetime dependence information to the compiler for the following reasons:</span></p><ul>
<li><span>Standardize the documentation of lifetimes of API(s) for developers</span></li>
<li><span>Standardize the specification of lifetimes for proposals</span></li>
<li><span>Greatly reduce the dangling of the stack for references</span></li>
</ul><p><span>This paper is </span><strong><span>NOT</span></strong><span> about the following:</span></p><ul>
<li><span>Fixing dangling of the stack that can only be discovered at runtime</span></li>
<li><span>Directly fixing danging of the heap when not using RAII</span></li>
<li><span>Fixing dangling that can occur when using pointers and pointer like types</span></li>
</ul><p><span>Rather it is about making those instances of dangling references to the stack which are always bad code, detectable as errors in the language, instead of warnings.</span></p><h2 id="Motivational-Example" data-id="Motivational-Example"><a class="anchor hidden-xs" href="#Motivational-Example" title="Motivational-Example"><span class="octicon octicon-link"></span></a><span>Motivational Example</span></h2><p><span style="color:red"><em><strong><span>Disclaimer: I am not a RUST expert. Any RUST examples provided here is to illustrate this feature as a language feature instead of an attribute. This proposal will repeatedly refer to this as an attribute but there is no preference on which, rather it is important to gain the functionality.</span></strong></em></span></p><p><span>What is being asked for is similar to but not exactly like Rust’s feature called </span><code>explicit lifetimes</code><span>.</span></p><p><span>Example taken from </span><code>Why are explicit lifetimes needed in Rust?</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p><pre><code class="rust hljs"><span class="token keyword">fn</span> <span class="token function-definition function">foo</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token punctuation">,</span> <span class="token lifetime-annotation symbol">'b</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">u32</span><span class="token punctuation">,</span> y<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'b</span> <span class="token keyword">u32</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">u32</span> <span class="token punctuation">{</span>
    x
<span class="token punctuation">}</span>
</code></pre><p><span>Similar but better functionality has been requested in a variety of C++ proposals.</span></p><ol>
<li><code>Bind Returned/Initialized Objects to the Lifetime of Parameters, Rev0</code><span> </span><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></li>
</ol><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> x lifetimebound<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token keyword">return</span> x<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><ol start="2">
<li><code>indirect dangling identification</code><span> </span><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></li>
</ol><pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">parameter_dependency</span><span class="token punctuation">(</span>dependent<span class="token punctuation">{</span><span class="token string">"return"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> providers<span class="token punctuation">{</span><span class="token string">"x"</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">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> x<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token keyword">return</span> x<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><ol start="3">
<li><code>Towards memory safety in C++</code><span> </span><sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup></li>
</ol><pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> x<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token keyword">return</span> x<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Rust also allows providing </span><code>explicit lifetimes</code><span> on struct(s) but that is </span><strong><span>NOT</span></strong><span> being asked for in this proposal.</span></p><p><span>Example taken from </span><code>Why are explicit lifetimes needed in Rust?</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup></p><pre><code class="rust hljs"><span class="token keyword">struct</span> <span class="token type-definition class-name">Foo</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
    x<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token keyword">i32</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> f <span class="token punctuation">:</span> <span class="token class-name">Foo</span><span class="token punctuation">;</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>  <span class="token comment">// variable that is invalid outside this block</span>
        <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token operator">&amp;</span>n<span class="token punctuation">;</span>
        f <span class="token operator">=</span> <span class="token class-name">Foo</span> <span class="token punctuation">{</span> x<span class="token punctuation">:</span> y <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">"{}"</span><span class="token punctuation">,</span> f<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><h2 id="Motivation" data-id="Motivation"><a class="anchor hidden-xs" href="#Motivation" title="Motivation"><span class="octicon octicon-link"></span></a><span>Motivation</span></h2><p><span>Having these checks in the language is highly desirable because it is highly effective. Other proposals are advocating for a seperate tool whether that be a static analysis tool or a runtime tool. Those solutions, while needed, are less effective because they are at best only </span><code>PPE</code><span>, personal protective equipment that only works if you have it installed, turned on, configured, used and acted upon. This proposal, while limited, is highly effective because it eliminates these instances of safety issues as illustrated on the </span><em><span>[exponential]</span></em><span> safety scale </span><sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup><span>.</span></p><p><img src="https://upload.wikimedia.org/wikipedia/commons/3/36/NIOSH%E2%80%99s_%E2%80%9CHierarchy_of_Controls_infographic%E2%80%9D_as_SVG.svg" alt="Hierarchy of Controls" loading="lazy"></p><p><span>This proposal is also in line with what that C++ community believes and teaches.</span></p><table>
<tbody><tr>
<td>
<p><em><span>“</span><strong><span>In.force: Enforcement</span></strong><span>”</span></em><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup></p>
<p><span>…</span></p>
<p><em><span>“This adds up to quite a few dilemmas. We try to resolve those using tools. Each rule has an </span><strong><span>Enforcement</span></strong><span> section listing ideas for enforcement. </span><strong><span>Enforcement might be done by code review, by static analysis, by compiler, or by run-time checks. Wherever possible, we prefer ‘mechanical’ checking (humans are slow, inaccurate, and bore easily) and static checking. Run-time checks are suggested only rarely where no alternative exists</span></strong><span>; we do not want to introduce ‘distributed bloat’.”</span></em><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6:1">[6:1]</a></sup></p>
<p><span>…</span></p>
<p><strong><span>P.5: Prefer compile-time checking to run-time checking</span></strong><span> </span><sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup></p>
<hr>
<p><strong><span>C++ Core Guidelines</span></strong><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6:2">[6:2]</a></sup><br><em><span>Bjarne Stroustrup, Herb Sutter</span></em></p>
</td>
</tr>
</tbody></table><h2 id="Other-Proposals" data-id="Other-Proposals"><a class="anchor hidden-xs" href="#Other-Proposals" title="Other-Proposals"><span class="octicon octicon-link"></span></a><span>Other Proposals</span></h2><p><span>Before going into the technical details, it would be good to consider this in light of other safety related proposals.</span></p><h3 id="Impact-on-general-lifetime-safety" data-id="Impact-on-general-lifetime-safety"><a class="anchor hidden-xs" href="#Impact-on-general-lifetime-safety" title="Impact-on-general-lifetime-safety"><span class="octicon octicon-link"></span></a><span>Impact on general lifetime safety</span></h3><p><span>This proposal does not conflict with </span><code>Lifetime safety: Preventing common dangling</code><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup><span>. To the contrary, it is complimentary.</span></p><table>
<tbody><tr>
<td>
<p><em><span>“</span><strong><span>1.1.4 Function calls</span></strong><span>”</span></em>
<em><span>“Finally, since </span><strong><span>every function is analyzed in isolation</span></strong><span>, we have to have some way of reasoning about function calls when a function call returns a Pointer. </span><strong><span>If the user doesn’t annotate</span></strong><span> otherwise, </span><strong><span>by default we assume that a function returns values that are derived from its arguments.</span></strong><span>”</span></em></p>
<hr>
<p><strong><span>Lifetime safety: Preventing common dangling</span></strong><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8:1">[8:1]</a></sup><br><em><span>Herb Sutter</span></em></p>
</td>
</tr>
</tbody></table><p><span>Just like the </span><code>Lifetime safety: Preventing common dangling</code><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8:2">[8:2]</a></sup><span> paper, this proposal analyze each function in isolation. While that proposal is focused on when programmers do not annotate/document their code, this proposal is focused on when programmers do document their code. That proposal “</span><em><span>assume that a function returns values that are derived from its arguments</span></em><span>” and because of this assumption has to produce warnings. This proposal makes no assumption at all and consequently can produce errors from the library authors documented intentions. This is both complimentary, independent and both proposals are desired by the C++ community. Since both related features are independent than there is no reason why the compile checks proposal couldn’t be added before the runtime checks proposal.</span></p><h3 id="Impact-on-Contracts" data-id="Impact-on-Contracts"><a class="anchor hidden-xs" href="#Impact-on-Contracts" title="Impact-on-Contracts"><span class="octicon octicon-link"></span></a><span>Impact on Contracts</span></h3><p><span>This proposal also does not conflict with contracts. Matter of fact this proposal could be described in terms of contracts, just applied to existing language features. Since, none of the current contract proposals allow applying contracts to existing and future non functional language features such as </span><code>return</code><span> and </span><code>do return</code><span> </span><sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup><span>, this proposal is complimentary.</span></p><table>
<tbody><tr>
<td>
<p><em><span>“</span><strong><span>7.1 LIFETIME</span></strong><span>”</span></em>
<em><span>“These sources of undefined behavior pertain to accessing an object outside its lifetime or validity of a pointer. By their very nature, they are not directly syntactic. </span><strong><span>The approach suggested in this proposal is to prohibit the use of certain syntactic constructs which might – under the wrong circumstances – lead to undefined behavior. Those restrictions are syntactic, so clearly will prohibit cases that someone might find useful.</span></strong><span>”</span></em><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10">[10]</a></sup></p>
<hr>
<p><strong><span>Contracts for C++: Prioritizing Safety</span></strong><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10:1">[10:1]</a></sup><br><em><span>Gabriel Dos Reis</span></em></p>
</td>
</tr>
</tbody></table><p><span>The </span><code>Contracts for C++: Prioritizing Safety</code><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10:2">[10:2]</a></sup><span> proposal envisions a predicate called </span><code>object_address</code><span> that could be applied via contracts to functions. In contract like terms, this proposal would be advocating for </span><code>is_global_object_address</code><span>, </span><code>is_local_object_address</code><span>, </span><code>is_temporary_object_address</code><span>, </span><code>is_not_global_local_temporary_object_address</code><span> and then applying these predicates to </span><code>return</code><span>, reference dereference and the points of reference use. Since all of this is compile time information and the places where applied would always produce errors than there is no need for the programmer to add such checks anywhere because the compiler can do it automatically. Further, as this proposal only serve to identify code that is definitely bad, then this proposal does not “</span><em><span>prohibit cases that someone might find useful</span></em><span>”.</span></p><h2 id="Technical-Details" data-id="Technical-Details"><a class="anchor hidden-xs" href="#Technical-Details" title="Technical-Details"><span class="octicon octicon-link"></span></a><span>Technical Details</span></h2><p><span>In order to make this proposal work, 2 bits of information is needed per reference at compile time. The 2 bits represents an enumeration of 4 possible lifetime values.</span></p><ol>
<li><span>Is global</span></li>
<li><span>Is local</span></li>
<li><span>Is temporary</span></li>
<li><span>Is all other i.e. not global, local or temporary? i.e. unknown, </span><code>nullptr</code><span> and dynamic</span></li>
</ol><p><span>This lifetime enumeration gets associated with each reference at the point of construction since references have to be initialized, can’t be </span><code>nullptr</code><span> and can’t be rebound.</span></p><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">*</span> ip<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> ir<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token operator">=</span> <span class="token operator">*</span>ip<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token operator">=</span> ir<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token operator">=</span> GLOBAL<span class="token punctuation">;</span><span class="token comment">// global lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token operator">=</span> local<span class="token punctuation">;</span><span class="token comment">// local lifetime</span>
<span class="token punctuation">}</span>
</code></pre><p><span>The next step is copying a reference copies its lifetime metadata.</span></p><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">*</span> ip<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> ir<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token operator">=</span> <span class="token operator">*</span>ip<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token operator">=</span> ir<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token operator">=</span> GLOBAL<span class="token punctuation">;</span><span class="token comment">// global lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token operator">=</span> local<span class="token punctuation">;</span><span class="token comment">// local lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r5 <span class="token operator">=</span> r1<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r6 <span class="token operator">=</span> r2<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r7 <span class="token operator">=</span> r3<span class="token punctuation">;</span><span class="token comment">// global lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r8 <span class="token operator">=</span> r4<span class="token punctuation">;</span><span class="token comment">// local lifetime</span>
<span class="token punctuation">}</span>
</code></pre><p><strong><span>1st check: Returning a reference to a local produces an error.</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">*</span> ip<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> ir<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token operator">=</span> <span class="token operator">*</span>ip<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token operator">=</span> ir<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token operator">=</span> GLOBAL<span class="token punctuation">;</span><span class="token comment">// global lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token operator">=</span> local<span class="token punctuation">;</span><span class="token comment">// local lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r5 <span class="token operator">=</span> r1<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r6 <span class="token operator">=</span> r2<span class="token punctuation">;</span><span class="token comment">// unknown lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r7 <span class="token operator">=</span> r3<span class="token punctuation">;</span><span class="token comment">// global lifetime</span>
    <span class="token keyword">int</span><span class="token operator">&amp;</span> r8 <span class="token operator">=</span> r4<span class="token punctuation">;</span><span class="token comment">// local lifetime</span>
    <span class="token keyword">return</span> r8<span class="token punctuation">;</span><span class="token comment">// error: dangling a local</span>
<span class="token punctuation">}</span>
</code></pre><p><span>This error doesn’t give programmers much as C++ addressed this in C++23 with </span><code>Simpler implicit move</code><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11">[11]</a></sup><span>. However, since </span><code>Simpler implicit move</code><span> </span><sup class="footnote-ref"><a href="#fn11" id="fnref11:1">[11:1]</a></sup><span> was framed in terms of value categories than any error message would also be in terms of value categories. This proposal advises such an error would be expressed in terms of dangling which is more human readable for programmers.</span></p><p><span>Things get really interesting when programmers are allowed to provide explicit lifetime dependence information to the compiler. Unlike Rust’s </span><code>explicit lifetimes</code><span>, this feature, </span><code>explicit lifetime dependence</code><span>, allows a reference to be tied to the lifetimes of multiple other references. In these cases, the lifetime is the most constrained as in </span><code>temporary</code><span> is more constrained than </span><code>local</code><span> which is more constrained than </span><code>global</code><span>.</span></p><pre><code>global &gt; local &gt; temporary
</code></pre><p><span>This is also time to add two more checks.</span></p><p><strong><span>2nd check: Returning a reference to a </span><code>temporary</code><span> produces an error.</span>
<br><span>3rd check: Using a reference to a </span><code>temporary</code><span> after it has been assigned, i.e. on another line of code which is not the full-expression, produces an error.</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span>left<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> left<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> right<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> left<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> right<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> local<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token comment">/*global*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r5 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r6 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r1<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r2<span class="token punctuation">;</span><span class="token comment">// OK its a reference to a global</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r3<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r4<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r5<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r6<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">int</span> x1 <span class="token operator">=</span> r3 <span class="token operator">+</span> <span class="token number">43</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">int</span> x2 <span class="token operator">=</span> r5 <span class="token operator">+</span> <span class="token number">44</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">int</span> x3 <span class="token operator">=</span> r6 <span class="token operator">+</span> <span class="token number">45</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">return</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<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">// error: can't return temporary</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Besides fixing indirect dangling of a local, this also fixes indirect dangling of temporaries which causes immediate dangling.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>6.7.7 Temporary objects [class.temporary]</span></strong></p>
<p><span>…</span></p>
<p><sub><span>4</span></sub><span> When an implementation introduces a temporary object of a class that has a non-trivial constructor (11.4.5.2, 11.4.5.3), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (11.4.7). </span><strong><span>Temporary objects are destroyed as the last step in evaluating the full-expression</span></strong><span> (6.9.1) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side eﬀects of destroying a temporary object are associated only with the full-expression, not with any specifc subexpression.</span></p>
<p><span>…</span></p>
<p><span>(6.12) - A temporary bound to a reference in a </span><em><span>new-initializer</span></em><span> (7.6.2.8) persists until the completion of the </span><strong><span>full-expression</span></strong><span> containing the </span><em><span>new-initializer</span></em><span>.</span></p>
<p><span>[</span><em><span>Note 7</span></em><span>: </span><strong><span>This might introduce a dangling reference.</span></strong><span> - </span><em><span>end note</span></em><span>]</span></p>
<!--
[*Example 5*:

```cpp    
struct S { int mi; const std::pair&lt;int,int&gt;& mp; };
S a { 1, {2,3} };
S* p = new S{ 1, {2,3} }; // creates dangling reference
```

-- *end example*]
-->
<hr>
<p><strong><span>Working Draft, Standard for Programming Language C++</span></strong><span> </span><sup class="footnote-ref"><a href="#fn12" id="fnref12">[12]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>If we fixed nothing else identified in this proposal, that would be a welcome reprieve. However, much more can be done simply. Let’s say, instead of adding this lifetime metadata to each reference, we add it to each instance. For references, lifetime metadata would still say that the reference refers to an instance with a particular lifetime but for non reference and non pointer instances, lifetime metadata would indicate that the instance is dependent upon another instance. Let’s see what type of dangling this would mitigate.</span></p><h3 id="Structs-and-Classes" data-id="Structs-and-Classes"><a class="anchor hidden-xs" href="#Structs-and-Classes" title="Structs-and-Classes"><span class="octicon octicon-link"></span></a><span>Structs and Classes</span></h3><p><span>Before adding this metadata to instances in general, consider a struct that contains references. This shows that the composition and decomposition of references can be handled by the compiler provided the reference is accessible such as </span><code>public</code><span>.</span></p><pre><code class="cpp hljs"><span class="token keyword">struct</span> <span class="token class-name">S</span> <span class="token punctuation">{</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> first<span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> second<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span>left<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> left<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> right<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> left<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> right<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    S s1<span class="token punctuation">{</span>GLOBAL<span class="token punctuation">,</span> local<span class="token punctuation">}</span><span class="token punctuation">;</span>
    S s2<span class="token punctuation">{</span>local<span class="token punctuation">,</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token comment">/*global*/</span> <span class="token operator">=</span> s1<span class="token punctuation">.</span>first<span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token comment">/*local*/</span> <span class="token operator">=</span> s1<span class="token punctuation">.</span>second<span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token comment">/*local*/</span> <span class="token operator">=</span> s2<span class="token punctuation">.</span>first<span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> s2<span class="token punctuation">.</span>second<span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r1<span class="token punctuation">;</span><span class="token comment">// OK its a reference to a global</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r2<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r3<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r4<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">int</span> x <span class="token operator">=</span> r4 <span class="token operator">+</span> <span class="token number">43</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">return</span> <span class="token number">42</span><span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
<span class="token punctuation">}</span>

S <span class="token function">f3</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    S s1<span class="token punctuation">{</span>GLOBAL<span class="token punctuation">,</span> local<span class="token punctuation">}</span><span class="token punctuation">;</span>
    S s2<span class="token punctuation">{</span>local<span class="token punctuation">,</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> s1<span class="token punctuation">;</span><span class="token comment">// error: still returning a local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> s2<span class="token punctuation">;</span><span class="token comment">// error: still returning a local</span>
    <span class="token comment">// error: still returning a temporary</span>
<span class="token punctuation">}</span>

<span class="token comment">// prevents returning lambda that captures or returns a local or temporary</span>
<span class="token keyword">auto</span> <span class="token function">lambda</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> ref_temporary <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token operator">&amp;</span>local<span class="token punctuation">,</span> <span class="token operator">&amp;</span>ref_temporary<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> local<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> ref_temporary<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// error: still returning a local</span>
    <span class="token comment">// error: still returning a temporary</span>
<span class="token punctuation">}</span>

<span class="token comment">// prevents returning coroutine that captures or returns a local or temporary</span>
<span class="token keyword">auto</span> <span class="token function">coroutine</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> ref_temporary <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token operator">&amp;</span>local<span class="token punctuation">,</span> <span class="token operator">&amp;</span>ref_temporary<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> generator<span class="token operator">&lt;</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span><span class="token operator">&gt;</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">co_return</span> local<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">co_return</span> ref_temporary<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">// error: still returning a local</span>
    <span class="token comment">// error: still returning a temporary</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Is there any way we can mitigate dangling when the reference has been hidden by abstractions such as for reference like classes via </span><code>protected</code><span>, </span><code>private</code><span> access and </span><code>public</code><span> accessors. If lifetime metadata are also appied to instances in general, than constructors, conversion operators and factory functions could be annotated to say a returned reference like type is dependent upon another type. Consider the </span><code>std::string_view</code><span> and </span><code>sts::string</code><span>.</span></p><p><strong><span>GIVEN</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">constexpr</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span><span class="token keyword">operator</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">basic_string_view</span><span class="token generic class-name"><span class="token operator">&lt;</span>CharT<span class="token punctuation">,</span> Traits<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token keyword">noexcept</span><span class="token punctuation">;</span>
</code></pre><pre><code class="cpp hljs">std<span class="token double-colon punctuation">::</span>string_view sv <span class="token comment">/* dependent upon temporary */</span> <span class="token operator">=</span> <span class="token string">"hello world"</span>s<span class="token punctuation">;</span><span class="token comment">// temporary</span>
sv<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// error: can't use a temporary outside of the line it was created on</span>
</code></pre><p><span>This would also work with other reference like types such as </span><code>std::span</code><span> and </span><code>function_ref</code><span> </span><sup class="footnote-ref"><a href="#fn13" id="fnref13">[13]</a></sup><span>. Just as this proposal does not address pointers because they are more run time than compile time, this proposal would not address </span><code>std::reference_wrapper</code><span> since it is rebindable. Nor would this proposal address, </span><code>std::shared_ptr</code><span> and </span><code>std::unique_ptr</code><span> which like pointers are nullable and rebindable, even though they already have runtime safeties built in.</span><!--However, if the standard ever adopted shared_ref and unique_ref which would have to be initialized to a non-null and wasn't rebindable than this proposal would be invaluable.--></p><p><span>Even though this proposal does not address pointers and pointer like types, it is still useful to non owning versions of these constructs when they are const constructed because they would need to be non null initialized to be usable and wouldn’t be rebindable because they were </span><code>const</code><span>. For instance, </span><code>std::reference_wrapper</code><span> is rebindable like a pointer so it tends to be more runtime than compile time. However, a </span><code>const std::reference_wrapper</code><span> can’t be rebound so it would make sense if a programmer bound its lifetime to another instance.</span></p><pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span>left<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>reference_wrapper<span class="token operator">&lt;</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&gt;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> left<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> right<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> std<span class="token double-colon punctuation">::</span><span class="token function">cref</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> std<span class="token double-colon punctuation">::</span><span class="token function">cref</span><span class="token punctuation">(</span>right<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p><span>This is also time to mention our final check.</span></p><p><strong><span>4th check: You can’t use a temporary in a </span><code>new</code><span> expression if the type being instantiated will become dependent upon that temporary.</span></strong></p><table>
<tbody><tr>
<td>
<p><strong><span>6.7.7 Temporary objects [class.temporary]</span></strong></p>
<p><span>…</span></p>
<p><sub><span>4</span></sub><span> … (11.4.7). </span><strong><span>Temporary objects are destroyed as the last step in evaluating the full-expression</span></strong><span> (6.9.1) …</span></p>
<p><span>…</span></p>
<p><span>(6.12) - A temporary bound to a reference in a </span><em><span>new-initializer</span></em><span> (7.6.2.8) persists until the completion of the </span><strong><span>full-expression</span></strong><span> containing the </span><em><span>new-initializer</span></em><span>.</span></p>
<p><span>[</span><em><span>Note 7</span></em><span>: </span><strong><span>This might introduce a dangling reference.</span></strong><span> - </span><em><span>end note</span></em><span>]</span></p>
<p><span>[</span><em><span>Example 5</span></em><span>:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">struct</span> <span class="token class-name">S</span> <span class="token punctuation">{</span> <span class="token keyword">int</span> mi<span class="token punctuation">;</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>pair<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">,</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token operator">&amp;</span> mp<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
S a <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</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>
S<span class="token operator">*</span> p <span class="token operator">=</span> <span class="token keyword">new</span> S<span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</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 comment">// creates dangling reference</span>
</code></pre>
<p><span>– </span><em><span>end example</span></em><span>]</span></p>
<hr>
<p><strong><span>Working Draft, Standard for Programming Language C++</span></strong><span> </span><sup class="footnote-ref"><a href="#fn12" id="fnref12:1">[12:1]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>In the previous example an instance of type S became dependent upon the temporary, </span><code>{2, 3}</code><span>, because it retained a reference to the temporary. This is detectable because the member </span><code>mp</code><span> is publicly available since the type </span><code>S</code><span> is a struct.</span></p><p><span>For a class where members </span><code>mi</code><span> and </span><code>mp</code><span> are abstracted away, the dependence can be expressed in its constructor.</span></p><pre><code class="cpp hljs"><span class="token keyword">class</span> <span class="token class-name">S</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">parameter_dependency</span><span class="token punctuation">(</span>dependent<span class="token punctuation">{</span><span class="token string">"this"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> providers<span class="token punctuation">{</span><span class="token string">"mp"</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
    <span class="token function">S</span><span class="token punctuation">(</span><span class="token keyword">int</span> mi<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>pair<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">,</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token operator">&amp;</span> mp<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token keyword">int</span> mi<span class="token punctuation">;</span>
    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>pair<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">,</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token operator">&amp;</span> mp<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

S a <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</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 comment">// instance dependent upon temporary</span>
<span class="token function">some_other_function</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// error: can't use `a` as it is dependent upon a temporary</span>
S<span class="token operator">*</span> p <span class="token operator">=</span> <span class="token keyword">new</span> S<span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</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 comment">// error: instance dependent upon temporary</span>
</code></pre><h3 id="Impact-on-Pattern-Matching" data-id="Impact-on-Pattern-Matching"><a class="anchor hidden-xs" href="#Impact-on-Pattern-Matching" title="Impact-on-Pattern-Matching"><span class="octicon octicon-link"></span></a><span>Impact on Pattern Matching</span></h3><p><span>This feature can be enhanced further to work with potential future </span><code>C++</code><span> language features such as pattern matching.</span></p><p><span style="color:red"><strong><span>WARNING: If pattern patching can allow propagating references from inner scopes to containing scopes than there will be a new category of dangling added to C++ and consequently a weakening of the safety of references.</span></strong></span></p><p><span>This paper references the </span><code>do expressions</code><span> </span><sup class="footnote-ref"><a href="#fn9" id="fnref9:1">[9:1]</a></sup><span> paper for the relevant portion of pattern matching because it is more explicit. If the C++ standard goes with an implicit syntax it can still be an issue if it allow propagating references from inner scopes to containing scopes.</span></p><p><span>The simplest example is as follows.</span></p><pre><code class="cpp hljs">
<span class="token keyword">int</span> x <span class="token operator">=</span> <span class="token keyword">do</span> <span class="token punctuation">{</span> <span class="token keyword">do</span> <span class="token keyword">return</span> <span class="token number">42</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

</code></pre><p><span>The simplest example we have to be on guard against is as follows.</span></p><pre><code class="cpp hljs">
<span class="token keyword">int</span><span class="token operator">&amp;</span> x <span class="token operator">=</span> <span class="token keyword">do</span>
<span class="token punctuation">{</span>
    <span class="token keyword">do</span> <span class="token keyword">return</span> <span class="token number">42</span><span class="token punctuation">;</span><span class="token comment">// dangling likely caught by `Simpler implicit move`</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

</code></pre><p><span>This paper can similarly handle the indirect cases as was performed for returns.</span></p><pre><code class="cpp hljs">
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> x <span class="token operator">=</span> <span class="token keyword">do</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> local<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token comment">/*global*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r5 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r6 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> r1<span class="token punctuation">;</span><span class="token comment">// error: can't do return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> r2<span class="token punctuation">;</span><span class="token comment">// OK its a reference to a global</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> r3<span class="token punctuation">;</span><span class="token comment">// error: can't do return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> r4<span class="token punctuation">;</span><span class="token comment">// error: can't do return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> r5<span class="token punctuation">;</span><span class="token comment">// error: can't do return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> r6<span class="token punctuation">;</span><span class="token comment">// error: can't do return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">int</span> x1 <span class="token operator">=</span> r3 <span class="token operator">+</span> <span class="token number">43</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">int</span> x2 <span class="token operator">=</span> r5 <span class="token operator">+</span> <span class="token number">44</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">int</span> x3 <span class="token operator">=</span> r6 <span class="token operator">+</span> <span class="token number">45</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">return</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<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">// error: can't return temporary</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

</code></pre><p><span>Do expressions i.e. pattern matching expressions are not completely self contained like functions. They can directly use locals from containing scopes. Do returning these locals </span><strong><span>COULD</span></strong><span> be allowed, while </span><code>do return</code><span>ing locals in the same scope of the </span><code>do expression</code><span> should </span><strong><span>DEFINITELY</span></strong><span> be disallowed.</span></p><pre><code class="cpp hljs">
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</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">int</span> local1 <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> rint1 <span class="token operator">=</span> <span class="token keyword">do</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">int</span> local2 <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> rint2 <span class="token operator">=</span> <span class="token keyword">do</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">int</span> local3 <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> local1<span class="token punctuation">;</span><span class="token comment">// OK, definitively safe</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> local2<span class="token punctuation">;</span><span class="token comment">// OK for now, problem later</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">do</span> <span class="token keyword">return</span> local3<span class="token punctuation">;</span><span class="token comment">// error: can't do return local</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> local1<span class="token punctuation">;</span><span class="token comment">// OK, definitively safe</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">do</span> <span class="token keyword">return</span> local2<span class="token punctuation">;</span><span class="token comment">// error: can't do return local</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">do</span> <span class="token keyword">return</span> rint2<span class="token punctuation">;</span><span class="token comment">// ?error or runtime unknown? could be local1 or local2</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre><p><span>The problem on </span><code>rint2</code><span> is that what should its lifetime response be; an error or unknown? I could think of a couple of solutions.</span></p><ul>
<li><span>Prevent </span><code>do expressions</code><span> whether explicit or implicit in some other pattern matching proposals from </span><code>do returning</code><span> references to locals that are not declared before the top most nested </span><code>do</code><span>. “An ounce of prevention is worth a pound of cure.”</span></li>
<li><span>Do nothing as this proposal is not meant to fix runtime dangling of the stack</span></li>
</ul><p><span>Regardless of the decision that would need to be made, so much definitively bad dangling has been identified and made more transparent.</span></p><hr><p><span>So, how does this proposal stack up to the design group’s opinion on safety for C++.</span></p><table>
<tbody><tr>
<td>
<ul>
<li><em><span>Do not radically break backwards compatibility – compatibility is a key feature and strength of C++ compared to more modern and more fashionable languages.</span></em><span> </span><sup class="footnote-ref"><a href="#fn14" id="fnref14">[14]</a></sup>
<ul>
<li><strong><span>This proposal does not break any correct code. It only produces errors for code that definitely dangle.</span></strong></li>
</ul>
</li>
<li><span>Do not deliver safety at the cost of an inability to express the abstractions that are currently at the core of C++ strengths. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:1">[14:1]</a></sup>
<ul>
<li><strong><span>This proposal does not compromise nor remove any of C++ features so abstractions are still there.</span></strong></li>
</ul>
</li>
<li><span>Do not leave us with a “safe” subset of C that eliminates C++’s productivity advantages. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:2">[14:2]</a></sup>
<ul>
<li><strong><span>This proposal works with all existing code. It is purely optin.</span></strong></li>
</ul>
</li>
<li><span>Do not deliver a purely run-time model that imposes overheads that eliminate C++’s strengths in the area of performance. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:3">[14:3]</a></sup>
<ul>
<li><strong><span>This proposal is completely compile time.</span></strong></li>
</ul>
</li>
<li><span>Do not imply that there is exactly one form of “safety” that must be adopted by all. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:4">[14:4]</a></sup>
<ul>
<li><strong><span>This proposal does not conflict with existing safety designs. While most others are runtime, this proposal is purely compile time. As such they are complimentary.</span></strong></li>
</ul>
</li>
<li><span>Do not promise to deliver complete guaranteed type-and-resource safety for all uses. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:5">[14:5]</a></sup>
<ul>
<li><strong><span>This proposal only address dangling of the stack via references which can be easily achieved if library authors provide the compiler a little more information that is needed by library users anyway.</span></strong></li>
</ul>
</li>
<li><span>Do offer paths to gradual and partial adoption – opening paths to improving the billions of lines of existing C++ code. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:6">[14:6]</a></sup>
<ul>
<li><strong><span>This proposal is opt in on a per function basis.</span></strong></li>
</ul>
</li>
<li><span>Do not imply a freeze on further development of C++ in other directions. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:7">[14:7]</a></sup>
<ul>
<li><strong><span>Runtime checks can be performed concurrently.</span></strong></li>
</ul>
</li>
<li><span>Do not imply that equivalent-looking code written in different environments will have different semantics (exception: some environments may give some code “undefined behavior” while others give it (a single!) defined behavior). </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:8">[14:8]</a></sup>
<ul>
<li><strong><span>Bad code is bad code regardless of the environment. This proposal makes such bad code more transparent.</span></strong></li>
</ul>
</li>
</ul>
<hr>
<p><strong><span>DG OPINION ON SAFETY FOR ISO C++</span></strong><span> </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:9">[14:9]</a></sup><br><em><span>H. Hinnant, R. Orr, B. Stroustrup, D. Vandevoorde, M. Wong</span></em></p>
</td>
</tr>
</tbody></table><h2 id="Resolution" data-id="Resolution"><a class="anchor hidden-xs" href="#Resolution" title="Resolution"><span class="octicon octicon-link"></span></a><span>Resolution</span></h2><p><span>Now that these types of dangling can be detected, there are some tools that could be provided to developers to make it easier to fix these detected instances of dangling which are </span><strong><span>NOT</span></strong><span> a part of this proposal. Let’s go back to our first example.</span></p><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span>left<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> left<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> right<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> left<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> right<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> local<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token comment">/*global*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r5 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r6 <span class="token comment">/*temporary*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r1<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r2<span class="token punctuation">;</span><span class="token comment">// OK its a reference to a global</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r3<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r4<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r5<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r6<span class="token punctuation">;</span><span class="token comment">// error: can't return temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">int</span> x1 <span class="token operator">=</span> r3 <span class="token operator">+</span> <span class="token number">43</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">int</span> x2 <span class="token operator">=</span> r5 <span class="token operator">+</span> <span class="token number">44</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">int</span> x3 <span class="token operator">=</span> r6 <span class="token operator">+</span> <span class="token number">45</span><span class="token punctuation">;</span><span class="token comment">// error: can't use reference to a temporary</span>
    <span class="token keyword">return</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<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">// error: can't return temporary</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Since locals and temporaries should not be returned from functions, most functions that possess this type of dangling may be in need of some refactoring, perhaps using movable value types. For dangling that occurs in the body of a function, locals need to be moved up in scope and temporaries need to be changed into locals and then perhaps moved up in scope. This results in more lines of code, superfluous naming and excessive refactoring. If the fixed temporary is only ever used in a constant fashion and if it is a literal type and constant initialized than it would likely be manually turned into a global and moved far from the point of use. All of this could be made easier upon programmers with the following features.</span></p><ol>
<li><span>Temporaries that are initially constant referenced, where the type is a literal type and the instance could be constant initialized, then the compiler would automatically promote these to having static storage duration </span><sup class="footnote-ref"><a href="#fn15" id="fnref15">[15]</a></sup><span> just like a string and hopefully in the future like </span><code>std::initializer_list</code><span> </span><sup class="footnote-ref"><a href="#fn16" id="fnref16">[16]</a></sup><span>.</span></li>
<li><span>C23 introduced storage-class specifiers for compound literals. </span><sup class="footnote-ref"><a href="#fn17" id="fnref17">[17]</a></sup><span> If C++ followed suit, than we could be able to apply </span><code>static</code><span> and </span><code>constexpr</code><span> to our temporaries. Since these two would frequently be used together it could be shortened to </span><code>constant</code><span> or </span><code>constinit</code><span>. C++ could go even farther by introducting a new specifier perhaps called </span><code>var</code><span> for variable scope that would turn the temporary into a anonymously named variable with the same life of the left most instance in the full expression. </span><sup class="footnote-ref"><a href="#fn18" id="fnref18">[18]</a></sup></li>
</ol><p><span>Let’s see how these resolutions simply fixes some of the dangling in the previous example. In the following example, the keyword </span><code>constinit</code><span> is used to represent explicit constant initialization while the keyword </span><code>variable</code><span> is used to represent variable scope i.e. explicit lifetime extension. All of the </span><code>constinit</code><span> keywords in the example could be removed if there was implicit constant initialization.</span></p><pre><code class="cpp hljs"><span class="token keyword">const</span> <span class="token keyword">int</span> GLOBAL <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>

<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token function">dependson</span><span class="token punctuation">(</span>left<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> left<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> right<span class="token comment">/* unknown lifetime */</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> left<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> right<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> local <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r1 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> local<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r2 <span class="token comment">/*global*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r3 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token keyword">constinit</span> <span class="token number">42</span><span class="token punctuation">,</span> variable <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// was temporary</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r4 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> GLOBAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r5 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> <span class="token keyword">constinit</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// was temporary</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> r6 <span class="token comment">/*local*/</span> <span class="token operator">=</span> <span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> variable <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// was temporary</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r1<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r2<span class="token punctuation">;</span><span class="token comment">// OK its a reference to a global</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r3<span class="token punctuation">;</span><span class="token comment">// error: can't return local// NOTE: was temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r4<span class="token punctuation">;</span><span class="token comment">// error: can't return local</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r5<span class="token punctuation">;</span><span class="token comment">// error: can't return local// NOTE: was temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">randomBool</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">return</span> r6<span class="token punctuation">;</span><span class="token comment">// error: can't return local// NOTE: was temporary</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">int</span> x1 <span class="token operator">=</span> r3 <span class="token operator">+</span> <span class="token number">43</span><span class="token punctuation">;</span><span class="token comment">// FIXED: was a reference to a temporary, now local</span>
    <span class="token keyword">int</span> x2 <span class="token operator">=</span> r5 <span class="token operator">+</span> <span class="token number">44</span><span class="token punctuation">;</span><span class="token comment">// FIXED: was a reference to a temporary, now local</span>
    <span class="token keyword">int</span> x3 <span class="token operator">=</span> r6 <span class="token operator">+</span> <span class="token number">45</span><span class="token punctuation">;</span><span class="token comment">// FIXED: was a reference to a temporary, now local</span>
    <span class="token keyword">return</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token function">f1</span><span class="token punctuation">(</span>GLOBAL<span class="token punctuation">,</span> variable <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">f1</span><span class="token punctuation">(</span>local<span class="token punctuation">,</span> <span class="token keyword">constinit</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">// error: can't return local</span>
    <span class="token comment">// NOTE: was temporary instead of local</span>
<span class="token punctuation">}</span>
</code></pre><p><span>This proposal and these three resolutions all satisfy the design group’s opinion on safety for C++.</span></p><table>
<tbody><tr>
<td>&amp;<span style="color:green">✓</span></td>
<td>implicit<br>constant</td>
<td>explicit<br>constant</td>
<td>var</td>
<td>Opinion</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><em><span>Do not radically break backwards compatibility – compatibility is a key feature and strength of C++ compared to more modern and more fashionable languages.</span></em><span> </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:10">[14:10]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not deliver safety at the cost of an inability to express the abstractions that are currently at the core of C++ strengths. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:11">[14:11]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not leave us with a “safe” subset of C that eliminates C++’s productivity advantages. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:12">[14:12]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not deliver a purely run-time model that imposes overheads that eliminate C++’s strengths in the area of performance. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:13">[14:13]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not imply that there is exactly one form of “safety” that must be adopted by all. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:14">[14:14]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not promise to deliver complete guaranteed type-and-resource safety for all uses. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:15">[14:15]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do offer paths to gradual and partial adoption – opening paths to improving the billions of lines of existing C++ code. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:16">[14:16]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not imply a freeze on further development of C++ in other directions. </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:17">[14:17]</a></sup></p>
</td>
</tr>
<tr>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td style="color:green;text-align:center">✓</td>
<td>
<p><span>Do not imply that equivalent-looking code written in different environments will have different semantics (exception: some environments may give some code “undefined behavior” while others give it (a single!) defined behavior). </span><sup class="footnote-ref"><a href="#fn14" id="fnref14:18">[14:18]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>What’s more, </span><code>implicit constant</code><span> is the most effective. While both ‘&amp;</span><span style="color:green"><span>✓</span></span><span>’ and </span><code>implicit constant</code><span> can be categorized as </span><code>elimination</code><span>, only </span><code>implicit constant</code><span> automatically fixes instances of dangling in a non breaking way that is logical to end programmers.</span></p><p><img src="https://upload.wikimedia.org/wikipedia/commons/3/36/NIOSH%E2%80%99s_%E2%80%9CHierarchy_of_Controls_infographic%E2%80%9D_as_SVG.svg" alt="Hierarchy of Controls" loading="lazy"></p><p><span>While </span><code>explicit constant</code><span> and </span><code>var</code><span> are only </span><code>Personal Protective Equipment</code><span>, they are highly useful with or without this proposal as generic tools programmers can use to fix instances of dangling simply. They especially compliment this proposal as tools to fix dangling identified by this 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>The advantages of adopting said proposal are as follows:</span></p><ol>
<li><span>Standardize the documentation of lifetimes of API(s) for developers</span></li>
<li><span>Standardize the specification of lifetimes for proposals</span></li>
<li><span>Produce more meaningful return error messages that doesn’t involve value categories</span></li>
<li><span>Empowers programmers with tools to identify indirect occurences of immediate dangling of references to the stack, simply</span></li>
<li><span>Empowers programmers with tools to identify indirect occurences of return dangling of references to the stack, simply</span></li>
</ol><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="Why-not-pointers" data-id="Why-not-pointers"><a class="anchor hidden-xs" href="#Why-not-pointers" title="Why-not-pointers"><span class="octicon octicon-link"></span></a><span>Why not pointers?</span></h3><p><span>References have to be initialized, can’t be </span><code>nullptr</code><span> and can’t be rebound which means by default the lifetime of the instance the reference points to is fixed at the moment of construction which has to exist lower on the stack i.e. prior to reference creation which is known at compile time. This is very safe by default. Pointers and reference classes that has pointer semantics are none of these things. Since they are so dynamic, the relevant metadata would more frequently be needed at run time.</span></p><h3 id="Why-not-explicit-lifetime-dependence-on-structs" data-id="Why-not-explicit-lifetime-dependence-on-structs"><a class="anchor hidden-xs" href="#Why-not-explicit-lifetime-dependence-on-structs" title="Why-not-explicit-lifetime-dependence-on-structs"><span class="octicon octicon-link"></span></a><span>Why not </span><code>explicit lifetime dependence</code><span> on </span><code>struct</code><span>(s)?</span></h3><ol>
<li><span>References are rarely used in class definitions. Instead programmers use std::reference_wrapper, smart pointers and plain old pointers. Since all of these are rebindable, they are more runtime than compile time and as such is not the subject of this proposal. See </span><code>Why not pointers?</code><span> for more information.</span></li>
<li><code>Explicit lifetime dependence</code><span> on </span><code>struct</code><span>(s)/</span><code>class</code><span>[es] breaks abstraction because the user of a library need to know class/struct implementation details that are likely </span><code>protected</code><span>, </span><code>private</code><span> and internal. For public reference members of </span><code>struct</code><span> instances, the compiler with these enhancements can already propagate these references. Further, </span><code>explicit lifetime dependence</code><span> on functions allows propagating the needed information when applied to constructors, conversion operators and factory functions.</span></li>
</ol><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://stackoverflow.com/questions/31609137/why-are-explicit-lifetimes-needed-in-rust" target="_blank" rel="noopener"><span>https://stackoverflow.com/questions/31609137/why-are-explicit-lifetimes-needed-in-rust</span></a> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" 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/2018/p0936r0.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0936r0.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/2023/p2742r2.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2742r2.html</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/2023/p2771r0.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2771r0.html</span></a> <a href="#fnref4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p><a href="https://www.cdc.gov/niosh/topics/hierarchy/default.html" target="_blank" rel="noopener"><span>https://www.cdc.gov/niosh/topics/hierarchy/default.html</span></a> <a href="#fnref5" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#inforce-enforcement" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#inforce-enforcement</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://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#p5-prefer-compile-time-checking-to-run-time-checking" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#p5-prefer-compile-time-checking-to-run-time-checking</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/2019/p1179r1.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1179r1.pdf</span></a> <a href="#fnref8" class="footnote-backref">↩︎</a> <a href="#fnref8:1" class="footnote-backref">↩︎</a> <a href="#fnref8:2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn9" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2806r1.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2806r1.html</span></a> <a href="#fnref9" class="footnote-backref">↩︎</a> <a href="#fnref9:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn10" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2680r1.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2680r1.pdf</span></a> <a href="#fnref10" class="footnote-backref">↩︎</a> <a href="#fnref10:1" class="footnote-backref">↩︎</a> <a href="#fnref10:2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn11" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html</span></a> <a href="#fnref11" class="footnote-backref">↩︎</a> <a href="#fnref11:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn12" 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="#fnref12" class="footnote-backref">↩︎</a> <a href="#fnref12:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn13" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html</span></a> <a href="#fnref13" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn14" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2759r1.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2759r1.pdf</span></a> <a href="#fnref14" class="footnote-backref">↩︎</a> <a href="#fnref14:1" class="footnote-backref">↩︎</a> <a href="#fnref14:2" class="footnote-backref">↩︎</a> <a href="#fnref14:3" class="footnote-backref">↩︎</a> <a href="#fnref14:4" class="footnote-backref">↩︎</a> <a href="#fnref14:5" class="footnote-backref">↩︎</a> <a href="#fnref14:6" class="footnote-backref">↩︎</a> <a href="#fnref14:7" class="footnote-backref">↩︎</a> <a href="#fnref14:8" class="footnote-backref">↩︎</a> <a href="#fnref14:9" class="footnote-backref">↩︎</a> <a href="#fnref14:10" class="footnote-backref">↩︎</a> <a href="#fnref14:11" class="footnote-backref">↩︎</a> <a href="#fnref14:12" class="footnote-backref">↩︎</a> <a href="#fnref14:13" class="footnote-backref">↩︎</a> <a href="#fnref14:14" class="footnote-backref">↩︎</a> <a href="#fnref14:15" class="footnote-backref">↩︎</a> <a href="#fnref14:16" class="footnote-backref">↩︎</a> <a href="#fnref14:17" class="footnote-backref">↩︎</a> <a href="#fnref14:18" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn15" 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="#fnref15" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn16" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2752r1.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2752r1.html</span></a> <a href="#fnref16" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn17" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3038.htm" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3038.htm</span></a> <a href="#fnref17" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn18" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2658r1.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2658r1.html</span></a> <a href="#fnref18" 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><a href="#Reference-checking" title="Reference checking">Reference checking</a><ul class="nav">
<li><a href="#Table-of-contents" title="Table of contents">Table of contents</a></li>
<li><a href="#Changelog" title="Changelog">Changelog</a><ul class="nav">
<li><a href="#R2" title="R2">R2</a></li>
</ul>
</li>
<li><a href="#Abstract" title="Abstract">Abstract</a></li>
<li><a href="#Motivational-Example" title="Motivational Example">Motivational Example</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a></li>
<li><a href="#Other-Proposals" title="Other Proposals">Other Proposals</a><ul class="nav">
<li><a href="#Impact-on-general-lifetime-safety" title="Impact on general lifetime safety">Impact on general lifetime safety</a></li>
<li><a href="#Impact-on-Contracts" title="Impact on Contracts">Impact on Contracts</a></li>
</ul>
</li>
<li><a href="#Technical-Details" title="Technical Details">Technical Details</a><ul class="nav">
<li><a href="#Structs-and-Classes" title="Structs and Classes">Structs and Classes</a></li>
<li><a href="#Impact-on-Pattern-Matching" title="Impact on Pattern Matching">Impact on Pattern Matching</a></li>
</ul>
</li>
<li><a href="#Resolution" title="Resolution">Resolution</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="#Why-not-pointers" title="Why not pointers?">Why not pointers?</a></li>
<li><a href="#Why-not-explicit-lifetime-dependence-on-structs" title="Why not explicit lifetime dependence on struct(s)?">Why not explicit lifetime dependence on struct(s)?</a></li>
</ul>
</li>
<li><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;" null null>
        <div class="toc"><ul class="nav">
<li><a href="#Reference-checking" title="Reference checking">Reference checking</a><ul class="nav">
<li><a href="#Table-of-contents" title="Table of contents">Table of contents</a></li>
<li><a href="#Changelog" title="Changelog">Changelog</a><ul class="nav">
<li><a href="#R2" title="R2">R2</a></li>
</ul>
</li>
<li><a href="#Abstract" title="Abstract">Abstract</a></li>
<li><a href="#Motivational-Example" title="Motivational Example">Motivational Example</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a></li>
<li><a href="#Other-Proposals" title="Other Proposals">Other Proposals</a><ul class="nav">
<li><a href="#Impact-on-general-lifetime-safety" title="Impact on general lifetime safety">Impact on general lifetime safety</a></li>
<li><a href="#Impact-on-Contracts" title="Impact on Contracts">Impact on Contracts</a></li>
</ul>
</li>
<li><a href="#Technical-Details" title="Technical Details">Technical Details</a><ul class="nav">
<li><a href="#Structs-and-Classes" title="Structs and Classes">Structs and Classes</a></li>
<li><a href="#Impact-on-Pattern-Matching" title="Impact on Pattern Matching">Impact on Pattern Matching</a></li>
</ul>
</li>
<li><a href="#Resolution" title="Resolution">Resolution</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="#Why-not-pointers" title="Why not pointers?">Why not pointers?</a></li>
<li><a href="#Why-not-explicit-lifetime-dependence-on-structs" title="Why not explicit lifetime dependence on struct(s)?">Why not explicit lifetime dependence on struct(s)?</a></li>
</ul>
</li>
<li><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>
