<!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>
        variable scope - 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 .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>P2730R0</td>
</tr>
<tr>
<td>Date</td>
<td>2022-11-27</td>
</tr>
<tr>
<td>Reply-to</td>
<td>
<p><span>Jarrad J. Waterloo &lt;descender76 at gmail dot com&gt;</span></p>
</td>
</tr>
<tr>
<td>Audience</td>
<td>Evolution Working Group (EWG)</td>
</tr>
</tbody></table><h1 id="variable-scope" data-id="variable-scope"><a class="anchor hidden-xs" href="#variable-scope" title="variable-scope"><span class="octicon octicon-link"></span></a><span>variable scope</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="#variable-scope"><span>variable scope</span></a>
<ul>
<li><a href="#Changelog"><span>Changelog</span></a></li>
<li><a href="#Abstract"><span>Abstract</span></a></li>
<li><a href="#Motivation"><span>Motivation</span></a></li>
<li><a href="#Proposed-Wording"><span>Proposed Wording</span></a></li>
<li><a href="#Details"><span>Details</span></a>
<ul>
<li><a href="#Other-Anonymous-Things"><span>Other Anonymous Things</span></a></li>
<li><a href="#Value-Categories"><span>Value Categories</span></a></li>
</ul>
</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="R0" data-id="R0"><a class="anchor hidden-xs" href="#R0" title="R0"><span class="octicon octicon-link"></span></a><span>R0</span></h3><ul>
<li><span>The variable scope content was extracted and merged from the </span><code>temporary storage class specifiers</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><span> and </span><code>implicit constant initialization</code><span> </span><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><span> proposals.</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 the standard changes the default lifetime of temporaries from being statement scope to block and variable scope. These two changes would eliminate immediate dangling of the stack. It would also fix </span><strong><span>direct</span></strong><span> dangling that occurs in the body of a function. By handling the </span><strong><span>indirect</span></strong><span> returning of locals passed as arguments to functions, this proposal would also compliment </span><code>simpler implicit move</code><span> </span><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup><span>, which resolved direct returning of local. This would leave </span><code>C++</code><span> in a good position to identify the remaining indirect dangling with help of return/parameter dependency attributes from the programmer. </span><sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup></p><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>There are multiple resolutions to dangling in the </span><code>C++</code><span> language.</span></p><ol>
<li><span>Produce an error</span>
<ul>
<li><code>Simpler implicit move</code><span> </span><sup class="footnote-ref"><a href="#fn3" id="fnref3:1">[3:1]</a></sup></li>
</ul>
</li>
<li><span>Fix with block/variable scoping</span>
<ul>
<li><code>Fix the range-based for loop, Rev2</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup></li>
<li><code>Get Fix of Broken Range-based for Loop Finally Done</code><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup></li>
<li><strong><code>This proposal</code></strong></li>
</ul>
</li>
<li><span>Fix by making the instance global</span></li>
</ol><p><span>All are valid resolutions and individually are better than the others, given the scenario. This proposal is focused on the second option, which is to fix by changing the scope of the temporary instance from statement scope to block/variable scope.</span></p><p><span>Dangling the stack is shocking because is violates our trust in our compilers and language, since they are primarily responsible for the stack. However, there are three types of dangling that are even more shocking than the rest.</span></p><ol>
<li><span>Returning a </span><strong><span>direct</span></strong><span> reference to a local</span>
<ul>
<li><span>partially resolved by </span><code>Simpler implicit move</code><span> </span><sup class="footnote-ref"><a href="#fn3" id="fnref3:2">[3:2]</a></sup></li>
</ul>
</li>
<li><strong><span>Immediate dangling</span></strong></li>
<li><span>Dangling Constants</span></li>
</ol><p><span>This proposal is primarily focused on immediate dangling. Returning a reference that was passed as an argument to a function is perfectly legitimate.</span></p><pre><code class="cpp hljs"><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> defaultValue<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> defaultValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> value <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token string">"Hello World"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// immediate dangling</span>
<span class="token comment">// using `value` is bad</span>
</code></pre><p><span>The function </span><code>f</code><span> does not know whether </span><code>defaultValue</code><span> was created locally, globally or dynamically, nor does it care. The function </span><code>f</code><span> does expect that whatever instance is passed to it is alive after </span><code>f</code><span> is called. This makes sense because globals live to the end of the program, dynamically allocated instances provided would need to be deleted afterward and locals provided are lower on the stack since they were created in the caller’s scope and live to the end of the block they were allocated in. This is reaffirmed in a note in the </span><code>C++ Core Guidelines</code><span>.</span></p><table>
<tbody><tr>
<td>
<p><strong><span>C++ Core Guidelines</span></strong><br><strong><span>F.42: Return a </span><code>T*</code><span> to indicate a position (only)</span></strong><span> </span><sup class="footnote-ref"><a href="#fn7" id="fnref7">[7]</a></sup></p>
<p><span>…</span></p>
<p><u><em><strong><span>Note</span></strong><span> Do not return a pointer to something that is not in the caller’s scope; see F.43.</span></em></u><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8">[8]</a></sup></p>
</td>
</tr>
</tbody></table><p><span>Temporaries default lifetime is something totally different.</span></p><table>
<tbody><tr>
<td>
<p><em><span>“6.7.7 Temporary objects [class.temporary]”</span></em></p>
<p><em><span>“(6.12) — A temporary bound to a reference in a new-initializer (7.6.2.8) persists until the completion of the full-expression containing the new-initializer.”</span></em></p>
<p><em><span>“[Note 7: This might introduce a dangling reference. — end note]”</span></em></p>
</td>
</tr>
</tbody></table><p><span>For simplicity sake, I’ll call this </span><code>statement scope[d]</code><span>. As note 7 admits, this introduces more dangling to the language, besides the existing dangling of returning a reference to a local. It is also very unnatural in multiple ways.</span></p><h3 id="indirect-dangling-of-caller’s-local" data-id="indirect-dangling-of-caller’s-local"><a class="anchor hidden-xs" href="#indirect-dangling-of-caller’s-local" title="indirect-dangling-of-caller’s-local"><span class="octicon octicon-link"></span></a><span>indirect dangling of caller’s local</span></h3><p><span>What is </span><code>C++</code><span> doing when calling a function such as </span><code>f</code><span> in the previous example?</span></p><table>
<tbody><tr>
<td>Programmer's Code</td>
<td>What C++ did!</td>
</tr>
<tr>
<td>
<pre><code class="cpp hljs"><span class="token punctuation">{</span>
    <span class="token function">f</span><span class="token punctuation">(</span><span class="token string">"Hello World"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token punctuation">{</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">auto</span> anonymous <span class="token operator">=</span> <span class="token string">"Hello World"</span>s<span class="token punctuation">;</span>
        <span class="token function">f</span><span class="token punctuation">(</span>anonymous<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</td>
</tr>
</tbody></table><p><span>When dangling occurs, what programmers usually do is name the instance in order to fix it. Programmers don’t do this initially because this increases both superfluous names and lines of code which only increases the complexity of the program. A programmer expects the compiler to write code better than a programmer would, not worse. Dangling is way worse. In this case, the compiler is adding undersirable braces. </span><!--`C++` is not LIS~~P~~B.--><span> When has a </span><code>C</code><span> or </span><code>C++</code><span> developer ever polluted every function call in their program with superfluous braces. This is just unnatural. Unfortunately, things get worse. What does </span><code>C++</code><span> do when that same function returns?</span></p><table>
<tbody><tr>
<td>Programmer's Code</td>
<td>What C++ did!</td>
</tr>
<tr>
<td>
<pre><code class="cpp hljs"><span class="token punctuation">{</span>
    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> value <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token string">"Hello World"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token punctuation">{</span>
    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> value<span class="token punctuation">;</span><span class="token comment">//impossible, must be initialized</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">auto</span> anonymous <span class="token operator">=</span> <span class="token string">"Hello World"</span>s<span class="token punctuation">;</span>
        value <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">(</span>anonymous<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</td>
</tr>
</tbody></table><p><span>In this case, the compiler wrote code that is impossible for the programmer to write. The compiler scoped the arguments without scoping the return. A </span><code>C++</code><span> programmer can’t write a brace scope and have it apply to some locals declared in it and not to others. This makes things harder to understand.</span></p><table>
    <tbody><tr>
        <td rowspan="3">
            <div style="transform: rotate(-90deg);">
                <span>outer scope</span>
            </div>
        </td>
        <td>&nbsp;</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// before the call of the function `f`</span>
</code></pre>
</td>
    </tr>
    <tr>
        <td rowspan="2">
            <div style="transform: rotate(-90deg);">
                <span>`value` scope</span>
            </div>
        </td>
<td>
<pre><code class="cpp hljs"><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> value <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token string">"Hello World"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</td>
    </tr>
    <tr>
<td style="background-color:red">
<pre><code class="cpp hljs"><span class="token comment">// `value` dangles for the remainder of the outer scope</span>
</code></pre>
</td>
    </tr>
</tbody></table><p><span>The result is the unnatural </span><code>indirect dangling of caller's local</code><span>. This is also unnatural for any programmer with a </span><code>C</code><span> background.</span></p><table>
<tbody><tr>
<td>
<p><code>2021/10/18 Meneide, C Working Draft</code><span> </span><sup class="footnote-ref"><a href="#fn9" id="fnref9">[9]</a></sup></p>
<p><em><span>“6.5.2.5 Compound literals”</span></em></p>
<p><strong><span>paragraph 5</span></strong></p>
<p><em><span>“The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has </span><strong><span>automatic storage duration associated with the enclosing block</span></strong><span>.”</span></em></p>
</td>
</tr>
</tbody></table><p><span>For simplicity sake, we’ll call this </span><code>block scope</code><span>. In short, </span><code>C</code><span> has less dangling than </span><code>C++</code><span>. Dropping the superfluous unnatural braces fixes </span><code>indirect dangling of caller's local</code><span> but it also fixes </span><code>immediate dangling</code><span>.</span></p><h3 id="immediate-dangling" data-id="immediate-dangling"><a class="anchor hidden-xs" href="#immediate-dangling" title="immediate-dangling"><span class="octicon octicon-link"></span></a><span>immediate dangling</span></h3><pre><code class="cpp hljs">std<span class="token double-colon punctuation">::</span>string_view sv <span class="token operator">=</span> <span class="token string">"hello world"</span>s<span class="token punctuation">;</span><span class="token comment">// immediate dangling reference</span>
</code></pre><p><span>Set aside the fact that this should be fixed by constant initialization. This example dangles similar to </span><code>indirect dangling of caller's local</code><span>. However, something else unnatural is happening.</span></p><table>
    <tbody><tr>
        <td rowspan="3">
            <div style="transform: rotate(-90deg);">
                <span>outer scope</span>
            </div>
        </td>
        <td>&nbsp;</td>
<td>
<pre><code class="cpp hljs"><span class="token comment">// before assigning `sv`</span>
</code></pre>
</td>
    </tr>
    <tr>
        <td rowspan="2">
            <div style="transform: rotate(-90deg);">
                <span>`sv` scope</span>
            </div>
        </td>
<td>
<pre><code class="cpp hljs">std<span class="token double-colon punctuation">::</span>string_view sv <span class="token operator">=</span> <span class="token string">"hello world"</span>s<span class="token punctuation">;</span>
</code></pre>
</td>
    </tr>
    <tr>
<td style="background-color:red">
<pre><code class="cpp hljs"><span class="token comment">// `sv` dangles for the remainder of the outer scope</span>
</code></pre>
</td>
    </tr>
</tbody></table><p><span>When initializing or reinitializing locals, the lifetime of the temporary is divorced from the lifetime of the local variable that it is being assigned too. The temporary </span><code>"hello world"s</code><span> should have died when the variable </span><code>sv</code><span> died, not sooner. </span><code>block scope</code><span> would have fixed it in this instance but it doesn’t work with all locals as the next example illustrates.</span></p><pre><code class="cpp hljs">std<span class="token double-colon punctuation">::</span>string_view sv <span class="token operator">=</span> <span class="token string">"initial value"</span>s<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>
    sv <span class="token operator">=</span> <span class="token string">"if value"</span>s<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span>
    sv <span class="token operator">=</span> <span class="token string">"else value"</span>s<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>While </span><code>block scope</code><span> would fix the </span><code>"initial value"s</code><span> temporary, it would not fix the </span><code>"if value"s</code><span> or the </span><code>"else value"s</code><span> temporaries. In all three cases, the temporary was divorced from the lifetime of the local variable </span><code>sv</code><span>, that it is being assigned to. Had these temporaries died when the assigned variable </span><code>sv</code><span> died then there would not be any dangling. For simplicity sake, we’ll call this </span><code>variable scope</code><span>. </span><code>variable scope</code><span> fixes all the non return </span><strong><span>direct</span></strong><span> dangling that occurs in the body of a function. </span><code>variable scope</code><span> does not fix dangling associated with it being arguments to a function call as the variable in question is the parameter/argument which would just make it </span><code>statement scope</code><span>.</span></p><p><span>Let me summarize, statement scoping of a temporary is unnatural because …</span></p><ul>
<li><span>It prevents/discourages functions from returning references/pointers to instances that do exist lower on the stack.</span></li>
<li><span>It introduces superfluous scopes that the programmer would never code.</span></li>
<li><span>It introduces code that the programmer could never write thus making things harder to understand.</span></li>
<li><span>The lifetime of the temporary is divorced from the lifetime of the local variable that it is being assigned to.</span></li>
<li><span>It creates all of the more complex direct dangling associated with parameters/arguments as well as what exists in the body of the function.</span></li>
</ul><p><span>Consequently, all of the non return direct dangling can be fixed by doing the following two things.</span></p><ul>
<li><span>local variable’s temporaries get </span><code>variable scope</code><span> and</span></li>
<li><span>function argument’s temporaries get </span><code>block scope</code></li>
</ul><p><span>Extending the lifetime of the temporary to be the lifetime of the variable to which it is assigned is not unreasonable for C++. Matter of fact it is already happening but the rules are so targeted that it limits its use by many programmers as the following examples illustrate.</span></p><p><code>Working Draft, Standard for Programming Language C++</code><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10">[10]</a></sup></p><p><strong><span>“</span><em><span>6.7.7 Temporary objects</span></em><span>”</span></strong></p><p><span>…</span></p><p><strong><span>“</span><em><sub><span>5</span></sub><span> There are … contexts in which temporaries are destroyed at a diﬀerent point than the end of the fullexpression.</span></em><span>”</span></strong></p><p><span>…</span></p><p><strong><span>“</span><em><span>(6.8)</span></em><span>”</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">&gt;</span> <span class="token keyword">using</span> id <span class="token operator">=</span> T<span class="token punctuation">;</span>

<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> a <span class="token operator">=</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// temporary array has same lifetime as a</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> b <span class="token operator">=</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><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></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// temporary int has same lifetime as b</span>
<span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> c <span class="token operator">=</span> cond <span class="token operator">?</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&amp;&amp;</span><span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// exactly one of the two temporaries is lifetime-extended</span>
</code></pre><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 punctuation">(</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 number">1</span><span class="token punctuation">;</span> <span class="token comment">// temporary for value 1 has same lifetime as x</span>
</code></pre><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">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> m<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> S<span class="token operator">&amp;</span> s <span class="token operator">=</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 comment">// both S and int temporaries have lifetime of s</span>
</code></pre><p><span>Even though the standard says that the temporaries lifetime is extended to match that of the variable, in reality, it is the same as </span><code>block scope</code><span>. The one example that is closest to the </span><code>if/else</code><span> variable scope example is as follows:</span></p><pre><code class="cpp hljs"><span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> c <span class="token operator">=</span> cond <span class="token operator">?</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&amp;&amp;</span><span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// exactly one of the two temporaries is lifetime-extended</span>
</code></pre><p><span>This isn’t quite the same as both temporaries being </span><code>lifetime-extended</code><span>. Shouldn’t the </span><code>?:</code><span> ternary operator example work for variables that are delayed initialized or reinitialized inside of the </span><code>if</code><span> and </span><code>else</code><span> clauses of </span><code>if/else</code><span> statements? Shouldn’t the block of the variable declared above a </span><code>if/else</code><span> statement be used over the blocks of </span><code>if</code><span> and </span><code>else</code><span> clause where the temporary was assigned? This seems reasonable and consequently </span><code>variable scope</code><span> fixes even more dangling than </span><code>block scope</code><span>.</span></p><pre><code class="cpp hljs">std<span class="token double-colon punctuation">::</span>string_view sv <span class="token operator">=</span> <span class="token string">"1"</span>s<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">switch</span><span class="token punctuation">(</span><span class="token function">randomInt</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">case</span> <span class="token number">1</span><span class="token operator">:</span>
            sv <span class="token operator">=</span> <span class="token string">"10"</span>s<span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">default</span><span class="token operator">:</span>
            sv <span class="token operator">=</span> <span class="token string">"100"</span>s<span class="token punctuation">;</span>
            <span class="token keyword">break</span><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">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>
        sv <span class="token operator">=</span> <span class="token string">"1000"</span>s<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">else</span>
    <span class="token punctuation">{</span>
        sv <span class="token operator">=</span> <span class="token string">"10000"</span>s<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Here, </span><code>variable scope</code><span> fixes all 5 dangling references. It works regardless of the nesting and it also works with other control sructures such as </span><code>switch/case</code><span>.</span></p><h3 id="towards-a-less-complicated-standard" data-id="towards-a-less-complicated-standard"><a class="anchor hidden-xs" href="#towards-a-less-complicated-standard" title="towards-a-less-complicated-standard"><span class="octicon octicon-link"></span></a><span>towards a less complicated standard</span></h3><p><span>Changing the lifetime of temporaries from </span><code>statement scope</code><span> to </span><code>block scope</code><span> and </span><code>variable scope</code><span> would also vastly simplify the standard, making dangling even easier to teach. Notice the levels of complexity when comparing </span><code>C</code><span> and the as proposed verbiage with the current standard.</span></p><h4 id="C-verbiage" data-id="C-verbiage"><a class="anchor hidden-xs" href="#C-verbiage" title="C-verbiage"><span class="octicon octicon-link"></span></a><span>C verbiage</span></h4><table>
<tbody><tr>
<td>
<p><code>2021/10/18 Meneide, C Working Draft</code><span> </span><sup class="footnote-ref"><a href="#fn9" id="fnref9:1">[9:1]</a></sup></p>
<p><em><span>“6.5.2.5 Compound literals”</span></em></p>
<p><strong><span>paragraph 5</span></strong></p>
<p><em><span>“The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has </span><strong><span>automatic storage duration associated with the enclosing block</span></strong><span>.”</span></em></p>
</td>
</tr>
</tbody></table><h4 id="As-proposed" data-id="As-proposed"><a class="anchor hidden-xs" href="#As-proposed" title="As-proposed"><span class="octicon octicon-link"></span></a><span>As proposed</span></h4><table>
<tbody><tr>
<td>
<p><strong><span>6.7.7 Temporary objects</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). Temporary objects are destroyed via automatic storage duration (6.7.5.4) associated with the enclosing block of the expression as if the compiler was naming the temporaries anonymously or via automatic storage duration associated with the enclosing block of the variable to which the temporary is assigned, whichever is greater lifetime.</span></p>
</td>
</tr>
</tbody></table><h4 id="C-verbiage1" data-id="C-verbiage"><a class="anchor hidden-xs" href="#C-verbiage1" title="C-verbiage1"><span class="octicon octicon-link"></span></a><span>C++ verbiage</span></h4><table>
<tbody><tr>
<td>
<p><strong><span>6.7.7 Temporary objects</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). Temporary objects are destroyed as the last step in evaluating the full-expression (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 effects of destroying a temporary object are associated only with the full-expression, not with any specifc subexpression.</span></p>
<p><sub><span>5</span></sub><span> There are three contexts in which temporaries are destroyed at a different point than the end of the full expression. The first context is when a default constructor is called to initialize an element of an array with no corresponding initializer (9.4). The second context is when a copy constructor is called to copy an element of an array while the entire array is copied (7.5.5.3, 11.4.5.3). In either case, if the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any.</span></p>
<p><sub><span>6</span></sub><span> The third context is when a reference binds to a temporary object.</span><sup><span>29</span></sup><span> The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:</span></p>
<p><sub><span>(6.1)</span></sub><span> —- a temporary materialization conversion (7.3.5),</span></p>
<p><sub><span>(6.2)</span></sub><span> — ( expression ), where expression is one of these expressions,</span></p>
<p><sub><span>(6.3)</span></sub><span> — subscripting (7.6.1.2) of an array operand, where that operand is one of these expressions,</span></p>
<p><sub><span>(6.4)</span></sub><span> — a class member access (7.6.1.5) using the . operator where the left operand is one of these expressions and the right operand designates a non-static data member of non-reference type,</span></p>
<p><sub><span>(6.5)</span></sub><span> — a pointer-to-member operation (7.6.4) using the .* operator where the left operand is one of these expressions and the right operand is a pointer to data member of non-reference type,</span></p>
<p><sub><span>(6.6)</span></sub><span> — a</span></p>
<p><sub><span>(6.6.1)</span></sub><span> — const_cast (7.6.1.11),</span></p>
<p><sub><span>(6.6.2)</span></sub><span> — static_cast (7.6.1.9),</span></p>
<p><sub><span>(6.6.3)</span></sub><span> — dynamic_cast (7.6.1.7), or</span></p>
<p><sub><span>(6.6.4)</span></sub><span> — reinterpret_cast (7.6.1.10)</span></p>
<p><span>converting, without a user-defned conversion, a glvalue operand that is one of these expressions to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof,</span></p>
<p><sub><span>(6.7)</span></sub><span> — a conditional expression (7.6.16) that is a glvalue where the second or third operand is one of these expressions, or</span></p>
<p><sub><span>(6.8)</span></sub><span> — a comma expression (7.6.20) that is a glvalue where the right operand is one of these expressions.</span></p>
<p><span>[Example 2:</span></p>
<pre><code class="cpp hljs"><span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">&gt;</span> <span class="token keyword">using</span> id <span class="token operator">=</span> T<span class="token punctuation">;</span>

<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> a <span class="token operator">=</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// temporary array has same lifetime as a</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> b <span class="token operator">=</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><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></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// temporary int has same lifetime as b</span>
<span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> c <span class="token operator">=</span> cond <span class="token operator">?</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&amp;&amp;</span><span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// exactly one of the two temporaries is lifetime-extended</span>
</code></pre>
<p><span>— end example]</span></p>
<p><span>[Note 5: An explicit type conversion (7.6.1.4, 7.6.3) is interpreted as a sequence of elementary casts, covered above.</span></p>
<p><span>[Example 3:</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 punctuation">(</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 number">1</span><span class="token punctuation">;</span> <span class="token comment">// temporary for value 1 has same lifetime as x</span>
</code></pre>
<p><span>— end example]</span></p>
<p><span>— end note]</span></p>
<p><span>[Note 6: If a temporary object has a reference member initialized by another temporary object, lifetime extension applies recursively to such a member’s initializer.</span></p>
<p><span>[Example 4:</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">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> m<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> S<span class="token operator">&amp;</span> s <span class="token operator">=</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 comment">// both S and int temporaries have lifetime of s</span>
</code></pre>
<p><span>— end example]</span></p>
<p><span>— end note]</span></p>
<p><span>The exceptions to this lifetime rule are:~</span></p>
<p><sub><span>(6.9)</span></sub><span> — A temporary object bound to a reference parameter in a function call (7.6.1.3) persists until the completion of the full-expression containing the call.</span></p>
<p><sub><span>(6.10)</span></sub><span> — A temporary object bound to a reference element of an aggregate of class type initialized from a parenthesized expression-list (9.4) persists until the completion of the full-expression containing the expression-list.</span></p>
<p><sub><span>(6.11)</span></sub><span> — The lifetime of a temporary bound to the returned value in a function return statement (8.7.4) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.</span></p>
<p><sub><span>(6.12)</span></sub><span> — A temporary bound to a reference in a new-initializer (7.6.2.8) persists until the completion of the full-expression containing the new-initializer.</span></p>
<p><span>[Note 7: This might introduce a dangling reference. — end note]</span></p>
<p><span>[Example 5:</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>— end example]</span></p>
<p><sub><span>7</span></sub><span> The destruction of a temporary whose lifetime is not extended by being bound to a reference is sequenced before the destruction of every temporary which is constructed earlier in the same full-expression. If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their construction. In addition, the destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static, thread, or automatic storage duration (6.7.5.2, 6.7.5.3, 6.7.5.4); that is, if obj1 is an object with the same storage duration as the temporary and created before the temporary is created the temporary shall be destroyed before obj1 is destroyed; if obj2 is an object with the same storage duration as the temporary and created after the temporary is created the temporary shall be destroyed after obj2 is destroyed.</span></p>
<p><sub><span>8</span></sub><span> [Example 6:</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 function">S</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><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">friend</span> S <span class="token keyword">operator</span><span class="token operator">+</span><span class="token punctuation">(</span><span class="token keyword">const</span> S<span class="token operator">&amp;</span><span class="token punctuation">,</span> <span class="token keyword">const</span> S<span class="token operator">&amp;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token operator">~</span><span class="token function">S</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
S obj1<span class="token punctuation">;</span>
<span class="token keyword">const</span> S<span class="token operator">&amp;</span> cr <span class="token operator">=</span> <span class="token function">S</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token function">S</span><span class="token punctuation">(</span><span class="token number">23</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
S obj2<span class="token punctuation">;</span>
</code></pre>
<p><span>The expression S(16) + S(23) creates three temporaries: a frst temporary T1 to hold the result of the expression S(16), a second temporary T2 to hold the result of the expression S(23), and a third temporary T3 to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference cr. It is unspecifed whether T1 or T2 is created frst. On an implementation where T1 is created before T2, T2 shall be destroyed before T1. The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the end of the full-expression containing the call to operator+. The temporary T3 bound to the reference cr is destroyed at the end of cr’s lifetime, that is, at the end of the program. In addition, the order in which T3 is destroyed takes into account the destruction order of other objects with static storage duration. That is, because obj1 is constructed before T3, and T3 is constructed before obj2, obj2 shall be destroyed before T3, and T3 shall be destroyed before obj1.</span></p>
<p><span>— end example]</span></p>
</td>
</tr>
</tbody></table><p><span>Why the complexity? </span><code>statement scope</code><span> itself is simple, weighing in as just the first cited paragraph. However, all the other verbiage is for all of the, consistently the same, exceptions to the rule. This list is growing. This makes teaching </span><code>C++</code><span> more difficult. This makes teaching dangling and dangling resolution more difficult because one must know whether dangling was even an issue or not due to whether the temporary was lifetime extended or not.</span></p><p><span>The question is, can the proposed wording cover the use cases in those numerous exceptions to the statement scoping rule. I have previous covered that the current standard says that all of these exceptions were scoped to the variable, while in fact were actually </span><code>blocked scope</code><span>. However, let’s consider a recent addition in greater detail. That is the range based for loop dangling fix.</span></p><ul>
<li><code>Fix the range-based for loop, Rev2</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:1">[5:1]</a></sup></li>
<li><code>Get Fix of Broken Range-based for Loop Finally Done</code><span> </span><sup class="footnote-ref"><a href="#fn6" id="fnref6:1">[6:1]</a></sup></li>
</ul><pre><code class="cpp hljs"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> elem <span class="token operator">:</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getValues</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
</code></pre><p><span>“should be expanded equivalent to the following:” </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:2">[5:2]</a></sup></p><pre><code class="cpp hljs"><span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> tmp1 <span class="token operator">=</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lifetime of all temporaries extended</span>
<span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> tmp2 <span class="token operator">=</span> tmp1<span class="token punctuation">.</span><span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lifetime of all temporaries extended</span>
<span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> rg <span class="token operator">=</span> tmp2<span class="token punctuation">.</span><span class="token function">getValues</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> pos <span class="token operator">=</span> rg<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> end <span class="token operator">=</span> rg<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token punctuation">;</span> pos <span class="token operator">!=</span> end<span class="token punctuation">;</span> <span class="token operator">++</span>pos <span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token keyword">auto</span> elem <span class="token operator">=</span> <span class="token operator">*</span>pos<span class="token punctuation">;</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span> 
</code></pre><p><span>In the wording of these proposals, it says that the temporaries persist until the completion of the range based for statement. In other words, the previous example should be revised to show the additional scope.</span></p><pre><code class="cpp hljs"><span class="token punctuation">{</span>
    <span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> tmp1 <span class="token operator">=</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lifetime of all temporaries extended</span>
    <span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> tmp2 <span class="token operator">=</span> tmp1<span class="token punctuation">.</span><span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lifetime of all temporaries extended</span>
    <span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> rg <span class="token operator">=</span> tmp2<span class="token punctuation">.</span><span class="token function">getValues</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">auto</span> pos <span class="token operator">=</span> rg<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">auto</span> end <span class="token operator">=</span> rg<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token punctuation">;</span> pos <span class="token operator">!=</span> end<span class="token punctuation">;</span> <span class="token operator">++</span>pos <span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">auto</span> elem <span class="token operator">=</span> <span class="token operator">*</span>pos<span class="token punctuation">;</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p><span>This is nothing more than </span><code>block scope</code><span> where the block in question is the additional block added via the revisions to the range based for loop. Notice too that each temporary was promoted to being an anonymously named variable. In short, this proposal’s simplified verbiage covers all existing lifetime extensions.</span></p><p><span>The only real concern is what would this proposal break. Instances still get destroyed in a deterministic RAII fashion, however, temporary instances will live longer in order to fix dangling. The biggest category of types impacted by this would be by </span><strong><span>lock</span></strong><span> objects. However, this only occurs when locks are used as a temporary instead of recommended usage of a named instance. This was the same problem for the </span><code>range based for loop fix</code><span> and was set aside for the greater good of fixing dangling defects in the </span><code>C++</code><span> language. The rationale is recorded in the following sections in that paper.</span></p><ul>
<li><code>Is there code that might be broken with the fix?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:3">[5:3]</a></sup></li>
<li><code>So, how much code is broken in practice?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:4">[5:4]</a></sup></li>
<li><code>What are the drawbacks of such a fix?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:5">[5:5]</a></sup></li>
</ul><p><span>That paper also answers these questions.</span></p><ul>
<li><code>Is there a performance penalty?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:6">[5:6]</a></sup></li>
<li><code>But don’t we break the zero‐overhead principle?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:7">[5:7]</a></sup></li>
<li><code>But don’t we have tools to detect such lifetime problems?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:8">[5:8]</a></sup></li>
<li><code>Shouldn’t we fix lifetime extension for references in general?</code><span> </span><sup class="footnote-ref"><a href="#fn5" id="fnref5:9">[5:9]</a></sup></li>
</ul><p><span>Even if it is decided not to fix dangling by changing the default automatically, the paper </span><code>temporary storage class specifiers</code><span> </span><sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup><span> does propose allowing programmers to opt in to this change via a module level attribute. This would allow the vast majority of code bases to do away with most dangling and allow those who need more time to adjust to have the </span><code>statement scope</code><span> default. It would also serve as a vehicle to allow the standard to change over time. Granted this paper is all about fixing dangling as it is the best option and is inline with past decisions made for the </span><code>range based for loop fix</code><span>.</span></p><h2 id="Proposed-Wording" data-id="Proposed-Wording"><a class="anchor hidden-xs" href="#Proposed-Wording" title="Proposed-Wording"><span class="octicon octicon-link"></span></a><span>Proposed Wording</span></h2><p><strong><span>6.7.7 Temporary objects</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). Temporary objects are destroyed </span><ins><span>via automatic storage duration (6.7.5.4) associated with the enclosing block of the expression as if the compiler was naming the temporaries anonymously or via automatic storage duration associated with the enclosing block of the variable to which the temporary is assigned, whichever is greater lifetime.</span></ins><s><span>as the last step in evaluating the full-expression (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 effects of destroying a temporary object are associated only with the full-expression, not with any specifc subexpression.</span></s></p><p><s><sub><span>5</span></sub><span> There are three contexts in which temporaries are destroyed at a different point than the end of the full expression. The first context is when a default constructor is called to initialize an element of an array with no corresponding initializer (9.4). The second context is when a copy constructor is called to copy an element of an array while the entire array is copied (7.5.5.3, 11.4.5.3). In either case, if the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any.</span></s></p><p><s><sub><span>6</span></sub><span> The third context is when a reference binds to a temporary object.</span><sup><span>29</span></sup><span> The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:</span></s></p><p><s><sub><span>(6.1)</span></sub><span> —- a temporary materialization conversion (7.3.5),</span></s></p><p><s><sub><span>(6.2)</span></sub><span> — ( expression ), where expression is one of these expressions,</span></s></p><p><s><sub><span>(6.3)</span></sub><span> — subscripting (7.6.1.2) of an array operand, where that operand is one of these expressions,</span></s></p><p><s><sub><span>(6.4)</span></sub><span> — a class member access (7.6.1.5) using the . operator where the left operand is one of these expressions and the right operand designates a non-static data member of non-reference type,</span></s></p><p><s><sub><span>(6.5)</span></sub><span> — a pointer-to-member operation (7.6.4) using the .* operator where the left operand is one of these expressions and the right operand is a pointer to data member of non-reference type,</span></s></p><p><s><sub><span>(6.6)</span></sub><span> — a</span></s></p><p><s><sub><span>(6.6.1)</span></sub><span> — const_cast (7.6.1.11),</span></s></p><p><s><sub><span>(6.6.2)</span></sub><span> — static_cast (7.6.1.9),</span></s></p><p><s><sub><span>(6.6.3)</span></sub><span> — dynamic_cast (7.6.1.7), or</span></s></p><p><s><sub><span>(6.6.4)</span></sub><span> — reinterpret_cast (7.6.1.10)</span></s></p><p><s><span>converting, without a user-defned conversion, a glvalue operand that is one of these expressions to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof,</span></s></p><p><s><sub><span>(6.7)</span></sub><span> — a conditional expression (7.6.16) that is a glvalue where the second or third operand is one of these expressions, or</span></s></p><p><s><sub><span>(6.8)</span></sub><span> — a comma expression (7.6.20) that is a glvalue where the right operand is one of these expressions.</span></s></p><p><s><span>[Example 2:</span></s></p><s>
<pre><code class="cpp hljs"><span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">&gt;</span> <span class="token keyword">using</span> id <span class="token operator">=</span> T<span class="token punctuation">;</span>

<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> a <span class="token operator">=</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// temporary array has same lifetime as a</span>
<span class="token keyword">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> b <span class="token operator">=</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><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></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// temporary int has same lifetime as b</span>
<span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> c <span class="token operator">=</span> cond <span class="token operator">?</span> id<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">:</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&amp;&amp;</span><span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// exactly one of the two temporaries is lifetime-extended</span>
</code></pre>
</s><p><s><span>— end example]</span></s></p><p><s><span>[Note 5: An explicit type conversion (7.6.1.4, 7.6.3) is interpreted as a sequence of elementary casts, covered above.</span></s></p><p><s><span>[Example 3:</span></s></p><s>
<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 punctuation">(</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 number">1</span><span class="token punctuation">;</span> <span class="token comment">// temporary for value 1 has same lifetime as x</span>
</code></pre>
</s><p><s><span>— end example]</span></s></p><p><s><span>— end note]</span></s></p><p><s><span>[Note 6: If a temporary object has a reference member initialized by another temporary object, lifetime extension applies recursively to such a member’s initializer.</span></s></p><p><s><span>[Example 4:</span></s></p><s>
<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">const</span> <span class="token keyword">int</span><span class="token operator">&amp;</span> m<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> S<span class="token operator">&amp;</span> s <span class="token operator">=</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 comment">// both S and int temporaries have lifetime of s</span>
</code></pre>
</s><p><s><span>— end example]</span></s></p><p><s><span>— end note]</span></s></p><p><s><span>The exceptions to this lifetime rule are:</span></s></p><p><s><sub><span>(6.9)</span></sub><span> — A temporary object bound to a reference parameter in a function call (7.6.1.3) persists until the completion of the full-expression containing the call.</span></s></p><p><s><sub><span>(6.10)</span></sub><span> — A temporary object bound to a reference element of an aggregate of class type initialized from a parenthesized expression-list (9.4) persists until the completion of the full-expression containing the expression-list.</span></s></p><p><s><sub><span>(6.11)</span></sub><span> — The lifetime of a temporary bound to the returned value in a function return statement (8.7.4) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.</span></s></p><p><s><sub><span>(6.12)</span></sub><span> — A temporary bound to a reference in a new-initializer (7.6.2.8) persists until the completion of the full-expression containing the new-initializer.</span></s></p><p><s><span>[Note 7: This might introduce a dangling reference. — end note]</span></s></p><p><s><span>[Example 5:</span></s></p><s>
<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>
</s><p><s><span>— end example]</span></s></p><p><s><sub><span>7</span></sub><span> The destruction of a temporary whose lifetime is not extended by being bound to a reference is sequenced before the destruction of every temporary which is constructed earlier in the same full-expression. If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their construction. In addition, the destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static, thread, or automatic storage duration (6.7.5.2, 6.7.5.3, 6.7.5.4); that is, if obj1 is an object with the same storage duration as the temporary and created before the temporary is created the temporary shall be destroyed before obj1 is destroyed; if obj2 is an object with the same storage duration as the temporary and created after the temporary is created the temporary shall be destroyed after obj2 is destroyed.</span></s></p><p><s><sub><span>8</span></sub><span> [Example 6:</span></s></p><s>
<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 function">S</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><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">friend</span> S <span class="token keyword">operator</span><span class="token operator">+</span><span class="token punctuation">(</span><span class="token keyword">const</span> S<span class="token operator">&amp;</span><span class="token punctuation">,</span> <span class="token keyword">const</span> S<span class="token operator">&amp;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token operator">~</span><span class="token function">S</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
S obj1<span class="token punctuation">;</span>
<span class="token keyword">const</span> S<span class="token operator">&amp;</span> cr <span class="token operator">=</span> <span class="token function">S</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token function">S</span><span class="token punctuation">(</span><span class="token number">23</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
S obj2<span class="token punctuation">;</span>
</code></pre>
</s><p><s><span>The expression S(16) + S(23) creates three temporaries: a frst temporary T1 to hold the result of the expression S(16), a second temporary T2 to hold the result of the expression S(23), and a third temporary T3 to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference cr. It is unspecifed whether T1 or T2 is created frst. On an implementation where T1 is created before T2, T2 shall be destroyed before T1. The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the end of the full-expression containing the call to operator+. The temporary T3 bound to the reference cr is destroyed at the end of cr’s lifetime, that is, at the end of the program. In addition, the order in which T3 is destroyed takes into account the destruction order of other objects with static storage duration. That is, because obj1 is constructed before T3, and T3 is constructed before obj2, obj2 shall be destroyed before T3, and T3 shall be destroyed before obj1.</span></s></p><p><s><span>— end example]</span></s></p><p><span>…</span></p><p><span style="color:red"><strong><span>NOTE: Wording still need to capture that these temporaries are no longer temporaries and that their value category is </span><code>lvalue</code><span>.</span></strong></span></p><h2 id="Details" data-id="Details"><a class="anchor hidden-xs" href="#Details" title="Details"><span class="octicon octicon-link"></span></a><span>Details</span></h2><h3 id="Other-Anonymous-Things" data-id="Other-Anonymous-Things"><a class="anchor hidden-xs" href="#Other-Anonymous-Things" title="Other-Anonymous-Things"><span class="octicon octicon-link"></span></a><span>Other Anonymous Things</span></h3><p><span>The pain of immediate dangling associated with temporaries are especially felt when working with other anonymous language features of </span><code>C++</code><span> such as lambda functions.</span></p><h4 id="Lambda-functions" data-id="Lambda-functions"><a class="anchor hidden-xs" href="#Lambda-functions" title="Lambda-functions"><span class="octicon octicon-link"></span></a><span>Lambda functions</span></h4><p><span>Whenever a lambda function captures a reference to a temporary it immediately dangles before an opportunity is given to call it, unless it is a immediately invoked lambda/function expression.</span></p><pre><code class="cpp hljs"><span class="token punctuation">[</span><span class="token operator">&amp;</span>c1 <span class="token operator">=</span> <span class="token string">"hello"</span>s<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> s<span class="token punctuation">)</span><span class="token comment">// OK</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> c1 <span class="token operator">+</span> <span class="token string">" "</span>s <span class="token operator">+</span> s<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token string">"world"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// immediately invoked lambda/function expression</span>

<span class="token keyword">auto</span> lambda <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&amp;</span>c1 <span class="token operator">=</span> <span class="token string">"hello"</span>s<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> s<span class="token punctuation">)</span><span class="token comment">// immediate dangling</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> c1 <span class="token operator">+</span> <span class="token string">" "</span>s <span class="token operator">+</span> s<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// ...</span>
<span class="token function">lambda</span><span class="token punctuation">(</span><span class="token string">"world"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><span>This problem is resolved when the scope of temporaries is to the enclosing block instead of the containing expression. This is the same had the temporary been named.</span></p><pre><code class="cpp hljs"><span class="token keyword">auto</span> anonymous <span class="token operator">=</span> <span class="token string">"hello"</span>s<span class="token punctuation">;</span>
<span class="token keyword">auto</span> lambda <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&amp;</span>c1 <span class="token operator">=</span> anonymous<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&amp;</span> s<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> c1 <span class="token operator">+</span> <span class="token string">" "</span>s <span class="token operator">+</span> s<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// ...</span>
<span class="token function">lambda</span><span class="token punctuation">(</span><span class="token string">"world"</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><span>Unless resolved, this problem will continue to be a problem for future </span><code>C++</code><span> features, type erased or not, anonymous or not, where there are a separate construction and execution steps.</span></p><h3 id="Value-Categories" data-id="Value-Categories"><a class="anchor hidden-xs" href="#Value-Categories" title="Value-Categories"><span class="octicon octicon-link"></span></a><span>Value Categories</span></h3><p><span>If temporaries can be changed to have block scope, variable scope or global scope than how does it affect their value categories? Currently, if the literal is a string than it is a </span><code>lvalue</code><span> and it has global scope. For all the other literals, they tend to be a </span><code>prvalue</code><span> and have statement scope.</span></p><table>
<tbody><tr>
<td></td>
<td>
<p><strong><span>movable</span></strong></p>
</td>
<td>
<p><strong><span>unmovable</span></strong></p>
</td>
</tr>
<tr>
<td>
<p><strong><span>named</span></strong></p>
</td>
<td>xvalue</td>
<td>lvalue</td>
</tr>
<tr>
<td>
<p><strong><span>unnamed</span></strong></p>
</td>
<td>prvalue</td>
<td>?</td>
</tr>
</tbody></table><p><span>Throughout this paper, I have shown that it makes sense for temporaries [references and pointers] should have variable scope, unless they can be made global scope. From the programmers perspective, temporaries are just anonymously named variables. When they are passed as arguments, they have life beyond the life of the function that it is given to. As such the expression is not movable. As such, the desired behavior described throughout the paper is that they are </span><code>lvalues</code><span> which makes sense from a anonymously named standpoint. However, it must be said that technically they are unnamed which places them into the value category that </span><code>C++</code><span> currently does not have; the unmovable unnamed. The point is, this is simple whether it is worded as a </span><code>lvalue</code><span> or an unambiguous new value category that behaves like a </span><code>lvalue</code><span>. Regardless of which, there are some advantages that must be pointed out.</span></p><h3 id="Avoids-superfluous-moves" data-id="Avoids-superfluous-moves"><a class="anchor hidden-xs" href="#Avoids-superfluous-moves" title="Avoids-superfluous-moves"><span class="octicon octicon-link"></span></a><span>Avoids superfluous moves</span></h3><p><span>The proposed avoids superfluous moves. Copying pointers and lvalue references are cheaper than performing a move which is cheaper than performing any non trivial value copy.</span></p><h3 id="Undo-forced-naming" data-id="Undo-forced-naming"><a class="anchor hidden-xs" href="#Undo-forced-naming" title="Undo-forced-naming"><span class="octicon octicon-link"></span></a><span>Undo forced naming</span></h3><p><span>The proposed makes using types that delete their </span><code>rvalue</code><span> reference constructor easier to use. For instance, </span><code>std::reference_wrapper</code><span> can not be created/reassigned with a </span><code>rvalue</code><span> reference, i.e. temporaries. Rather, it must be created/reassigned with a </span><code>lvalue</code><span> reference created on a seperate line. This requires superfluous naming which increases the chances of dangling. Further, according to the </span><code>C++ Core Guidelines</code><span>, it is developers practice to do the following:</span></p><ul>
<li><em><span>ES.5: Keep scopes small</span></em><span> [^cppcges5]</span></li>
<li><em><span>ES.6: Declare names in for-statement initializers and conditions to limit scope</span></em><span> [^cppcges6]</span></li>
</ul><pre><code class="cpp hljs"><span class="token comment">// currently not permitted; works as proposed</span>
std<span class="token double-colon punctuation">::</span>reference_wrapper<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span> <span class="token function">rwi1</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// current forced usage</span>
<span class="token keyword">int</span> value1 <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>reference_wrapper<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span> <span class="token function">rwi2</span><span class="token punctuation">(</span>value1<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">int</span> value2 <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span><span class="token comment">// ES.5, ES.6</span>
    rwi2 <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span>value2<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// dangles with block scope</span>
    rwi2 <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// ok, safe and easy with variable scope proposal</span>
    rwi2 <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span><span class="token comment">// might make sense to add back direct assignment operator</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> value3 <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span><span class="token comment">// ES.5, ES.6</span>
    rwi2 <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span>value3<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// dangles with block scope</span>
    rwi2 <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// ok, safe and easy with variable scope proposal</span>
    rwi2 <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span><span class="token comment">// might make sense to add back direct assignment operator</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Since the variable </span><code>value2</code><span> and </span><code>value3</code><span> is likely to be created manually at block scope instead of variable scope, it can accidentally introduce more dangling. Constructing and reassigning with a </span><code>variable scoped</code><span> </span><code>lvalue</code><span> temporary avoids these common dangling possibilities along with simplifying the code.</span></p><p><span>Consider too another example of forced naming.</span></p><pre><code class="cpp hljs"><span class="token keyword">int</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">&amp;</span> i<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">// clang</span>
    <span class="token comment">// error: no matching function for call to 'do_something_with_ref'</span>
    <span class="token comment">// note: candidate function not viable: expects an lvalue for 1st argument</span>
    <span class="token comment">// msvc</span>
    <span class="token comment">// error C2664: 'int do_something_with_ref(int &amp;)': cannot convert argument 1 from 'int' to 'int &amp;'</span>
    <span class="token comment">// gcc</span>
    <span class="token comment">// error: cannot bind non-const lvalue reference of type 'int&amp;' to an rvalue of type 'int</span>
    <span class="token keyword">return</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>The previous code fails because the </span><code>do_something_with_ref</code><span> function is expecting a </span><code>lvalue</code><span>. However, the literal </span><code>0</code><span> is an </span><code>rvalue</code><span> when the temporary is scoped to the statement. This requires one of two possibilities, either the library writer has to overload the function such that </span><code>i</code><span> is </span><code>int&amp;&amp;</code><span> or library user has to name the variable.</span></p><p><strong><span>library writer overloads method</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">int</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">&amp;</span> i<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">&amp;&amp;</span> i<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>or</span></p><p><strong><span>library user names the temporary</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">int</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">&amp;</span> i<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">int</span> result <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>Templating the </span><code>do_something_with_ref</code><span> function with a universal reference would save the library writer from having to write the function twice but even that is an added complication.</span></p><p><strong><span>library writer templatize method with universal reference</span></strong></p><pre><code class="cpp hljs"><span class="token keyword">template</span><span class="token operator">&lt;</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">&gt;</span>
T <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span>T<span class="token operator">&amp;&amp;</span> i<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>However, if the temporary </span><code>0</code><span> was scoped to the block and anonymously named than it would no longer be a </span><code>rvalue</code><span> and instead would be a </span><code>lvalue</code><span>.</span></p><pre><code class="cpp hljs"><span class="token keyword">int</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">&amp;</span> i<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">do_something_with_ref</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><span>No templating needed. No duplicate functions. No superfluous naming. Just more anonymous and concise, easy to understand code.</span></p><h3 id="Allows-more-anonymous-variables" data-id="Allows-more-anonymous-variables"><a class="anchor hidden-xs" href="#Allows-more-anonymous-variables" title="Allows-more-anonymous-variables"><span class="octicon octicon-link"></span></a><span>Allows more anonymous variables</span></h3><p><span>The </span><code>C++ Core Guidelines</code><span> [^cppcgcp44] excourages programmers “to name your lock_guards and unique_locks” because “a temporary” “immediately goes out of scope”.</span></p><ul>
<li><em><span>CP.44: Remember to name your lock_guards and unique_locks</span></em><span> [^cppcgcp44]</span></li>
</ul><pre><code class="cpp hljs"><span class="token comment">// useless when statement scoped</span>
<span class="token generic-function"><span class="token function">unique_lock</span><span class="token generic class-name"><span class="token operator">&lt;</span>mutex<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>m1<span class="token punctuation">)</span><span class="token punctuation">;</span>
lock_guard<span class="token operator">&lt;</span>mutex<span class="token operator">&gt;</span> <span class="token punctuation">{</span>m2<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// current recommended usage</span>
unique_lock<span class="token operator">&lt;</span>mutex<span class="token operator">&gt;</span> <span class="token function">ul</span><span class="token punctuation">(</span>m1<span class="token punctuation">)</span><span class="token punctuation">;</span>
lock_guard<span class="token operator">&lt;</span>mutex<span class="token operator">&gt;</span>  lg<span class="token punctuation">{</span>m2<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// even more useful when variable or block scoped</span>
<span class="token comment">// this behaves the same had it been named</span>
<span class="token comment">// one less name to return or worry about</span>
<span class="token generic-function"><span class="token function">unique_lock</span><span class="token generic class-name"><span class="token operator">&lt;</span>mutex<span class="token operator">&gt;</span></span></span><span class="token punctuation">(</span>m1<span class="token punctuation">)</span><span class="token punctuation">;</span>
lock_guard<span class="token operator">&lt;</span>mutex<span class="token operator">&gt;</span> <span class="token punctuation">{</span>m2<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre><p><span>With this proposal these instances do not immediately go out of scope. As such we get the locking benefits without having to make up a name. Again, not having a name means their is less to return and potentially dangle.</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 to </span><code>C++</code><span> with adopting this proposal is manifold.</span></p><ul>
<li><span>Safer</span>
<ul>
<li><span>Eliminate immediate dangling</span></li>
<li><span>Eliminate non return direct dangling that can occur in the body of a function</span></li>
<li><span>Eliminate returning indirect reference dangling when the instance was provided as an argument from the caller’s scope</span></li>
<li><span>Reduce all remaining dangling</span></li>
<li><span>Reduce unitialized and delayed initialization errors</span></li>
</ul>
</li>
<li><span>Simpler</span>
<ul>
<li><span>Encourages the use of temporaries</span>
<ul>
<li><span>Reduce lines of code</span></li>
<li><span>Reduce naming; fewer names to return dangle</span></li>
</ul>
</li>
<li><span>Increases anonymously named </span><code>lvalues</code><span> and decreases </span><code>rvalues</code><span> in the code.</span>
<ul>
<li><span>Reduce lines of code</span></li>
<li><span>Reduce naming; fewer names to return dangle</span></li>
</ul>
</li>
<li><span>Simplify </span><code>C++</code><span> temporary lifetime extension rules</span></li>
<li><span>Reduce the gap between </span><code>C++</code><span> and </span><code>C99</code><span> compound literals</span></li>
<li><span>Improve the potential contribution of </span><code>C++</code><span>'s dangling resolutions back to </span><code>C</code></li>
<li><span>Simplify the language to match existing practice</span></li>
<li><span>Consequently, a “cleanup”, i.e. adoption of simpler, more general rules/guidelines</span></li>
</ul>
</li>
</ul><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="Is-variable_scope-easy-to-teach" data-id="Is-variable_scope-easy-to-teach"><a class="anchor hidden-xs" href="#Is-variable_scope-easy-to-teach" title="Is-variable_scope-easy-to-teach"><span class="octicon octicon-link"></span></a><span>Is </span><code>variable_scope</code><span> easy to teach?</span></h3><table>
<tbody><tr>
<td>
<p><strong><span>values</span></strong></p>
</td>
<td>
<p><strong><span>pointers with </span><code>C99</code><span> &amp;</span></strong></p>
</td>
<td>
<p><strong><span>proposed </span><code>C++</code></strong></p>
</td>
</tr>
<tr>
<td>
<pre><code class="cpp hljs"><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>whatever<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  i <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span>
  i <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// use i</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs"><span class="token keyword">int</span><span class="token operator">*</span> i <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token number">5</span><span class="token punctuation">;</span><span class="token comment">// or uninitialized</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>whatever<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  i <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token number">7</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span>
  i <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token number">9</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// use i</span>
</code></pre>
</td>
<td>
<pre><code class="cpp hljs">std<span class="token double-colon punctuation">::</span>reference_wrapper<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span> i<span class="token punctuation">{</span><span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>whatever<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  i <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">ref</span><span class="token punctuation">(</span><span class="token number">7</span><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>
  i <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">ref</span><span class="token punctuation">(</span><span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// use i</span>
</code></pre>
</td>
</tr>
</tbody></table><p><span>In the </span><code>values</code><span> example, there is no dangling. Programmers trust the compiler to allocate and deallocate instances on the stack. They have to because the programmer has little to no control over deallocation. </span><!--Neither of the `pointers` or `references` examples compile without utility functions to convert from reference to pointer and immediately invoked lambda functions to do complex initialization of references since they have to be initialized and their references can't currently be reassigned no matter how useful that would be. That boiler plate exist in an earlier example in this proposal and has been removed for clarity.--><span> With the current </span><code>C++</code><span> statement scope rules or the </span><code>C99</code><span> block scope rule, both the </span><code>pointers</code><span> and </span><code>references</code><span> examples dangle. In other words, the compilers who are primarily responsible for the stack has rules that needlessly causes dangling and embarrassing worse, immediate dangling. This violates the programmer’s trust in their compiler. Variable scope is better because it restores the programmer’s trust in their compiler/language by causing temporaries to match the value semantics of variables. Further, it avoids dangling throughout the body of the function whether it is anything that introduces new blocks/scopes be that </span><code>if</code><span>, </span><code>switch</code><span>, </span><code>while</code><span>, </span><code>for</code><span> statements and the nesting of these constructs.</span></p><h3 id="Won’t-this-break-a-lot-of-existing-code" data-id="Won’t-this-break-a-lot-of-existing-code"><a class="anchor hidden-xs" href="#Won’t-this-break-a-lot-of-existing-code" title="Won’t-this-break-a-lot-of-existing-code"><span class="octicon octicon-link"></span></a><span>Won’t this break a lot of existing code?</span></h3><p><span>Little, if any. To the contrary, code that is broken is now fixed. Code that would be invalid is now valid, makes sense and can be rationally explained.</span></p><p><span>When programmers use temporaries, unnamed variables, instead of named variables, then they give up control of the initialization order.</span></p><table>
<tbody><tr>
<td>
<p><code>Working Draft, Standard for Programming Language C++</code><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10:1">[10:1]</a></sup></p>
<p><strong><span>“</span><em><span>7.6.1.3 Function call [expr.call]</span></em><span>”</span></strong></p>
<p><span>“</span><em><span>8 The postfx-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side eﬀect, is </span><strong><span>indeterminately</span></strong><span> sequenced with respect to that of any other parameter.</span></em><span>”</span></p>
<p><span>“</span><em><span>[Note 8: All side eﬀects of argument evaluations are sequenced before the function is entered (see 6.9.1). — end note]</span></em><span>”</span></p>
</td>
</tr>
</tbody></table><p><span>Consequently, this indeterminiteness remains regards of whether the temporary was scoped to the statement or the block. In this proposal, while the point of creation remains the same, the point of deletion gets extended just enough to remove </span><strong><span>immediate</span></strong><span> dangling. Since the temporary variable is by definition unnamed, any chance of breakage is greatly minimized because other than the parameter it was directly passed to, nothing else has a reference to it.</span></p><p><span>The proposed lifetimes matches or exceeds those of the current temporary lifetime extension rules in </span><code>C++</code><span>. In all of the standard examples the temporary lifetime is extended to the assigned variable. However, in reality, since all of these initial assignments are to the block then the real lifetime is to the block that contains the expression that contains the temporary. This is the same as this proposal. However, when the initialization statement is passed directly as an argument of a function call than it is the current statement lifetime since the argument is the variable. In other words, no additional life was given. This proposal improves the consistency by giving these argument temporaries the same block lifetime in order to eliminate immediate dangling and reduce further dangling. This proposal examines the </span><code>?:</code><span> ternary operator example and asks the question shouldn’t this work for variables that are delayed initialized or reinitialized inside of the </span><code>if</code><span> and </span><code>else</code><span> clauses of </span><code>if/else</code><span> statements? Shouldn’t the block of the variable declared above a </span><code>if/else</code><span> statement be used over the blocks of </span><code>if</code><span> and </span><code>else</code><span> clause where the temporary was assigned? This seems reasonable and would fix even more dangling. Consequently, all direct dangling is fixed within any given function and all we are left with are the indirect dangling which tends to be more complicated and easily avoided with simpler code.</span></p><h3 id="Who-would-even-use-these-features-Their-isn’t-sufficient-use-to-justify-these-changes" data-id="Who-would-even-use-these-features-Their-isn’t-sufficient-use-to-justify-these-changes"><a class="anchor hidden-xs" href="#Who-would-even-use-these-features-Their-isn’t-sufficient-use-to-justify-these-changes" title="Who-would-even-use-these-features-Their-isn’t-sufficient-use-to-justify-these-changes"><span class="octicon octicon-link"></span></a><span>Who would even use these features? Their isn’t sufficient use to justify these changes.</span></h3><p><span>Everyone … Quite a bit, actually</span></p><p><span>Consider all the examples littered throughout our history, these are what gets fixed.</span></p><ul>
<li><span>dangling reported on normal use of the </span><code>STL</code></li>
<li><span>dangling examples reported in the </span><code>C++</code><span> standard</span></li>
<li><span>real world dangling reported in NAD, not a defect, reports</span></li>
</ul><p><span>This doesn’t even include the countless examples found in numerous articles comparing </span><code>C++</code><span> with other nameless programming languages which would be fixed.</span></p><p><span>One of biggest gripes with the </span><code>Bind Returned/Initialized Objects to the Lifetime of Parameters</code><span> </span><sup class="footnote-ref"><a href="#fn4" id="fnref4:1">[4:1]</a></sup><span> proposal was that it would require a viral attribution effort. While that may be inevitable in order to fix indirect dangling in the language, that viral effort helps to identify the magnitude of </span><code>C++</code><span> </span><code>STL</code><span> functions that has the potential of dangling in the first place and with this feature would no longer immediately dangle which is the most shocking type of dangling to end programmers.</span></p><h3 id="Why-not-just-use-a-static-analyzer" data-id="Why-not-just-use-a-static-analyzer"><a class="anchor hidden-xs" href="#Why-not-just-use-a-static-analyzer" title="Why-not-just-use-a-static-analyzer"><span class="octicon octicon-link"></span></a><span>Why not just use a static analyzer?</span></h3><p><span>Typically a static analyzer doesn’t fix code. Instead, it just produces warnings and errors. It is the programmer’s responsibility to fix code by deciding whether the incident was a false positive or not and making the corresponding code changes. This proposal does fix most direct dangling but other, more indirect dangling goes unresolved and unidentified. As such this proposal and static analyzers are complimentary. Combined this proposal can fix most dangling and a static analyzer could be used to identify what is remaining. As such those who still ask, “why not just use a static analyzer”, might really be saying </span><strong><span>this proposal’s language enhancements might break their static analyzer</span></strong><span>. To which I say, the standard dictates the analyzer, not the other way around. That is true for all tools. However, let’s explore the potential impact of this proposal on static analyzers.</span></p><p><span>The </span><code>C++</code><span> language is complex. It stands to reason that our tools would have some degree of complexity, since they would need to take some subset of our language’s rules into consideration. In any proposal, mine included, fixes to any dangling would result in potential dangling incidents becoming false positives between those identified by a static analyzer that overlap with said proposal. The false positives would join those that a static analyzer already has for not factoring existing language rules into consideration just as it would for any new language rules.</span></p><p><span>Static analyzers need to understand the lifetimes of variables with automatic storage duration, regardless. Not quantifying the current life of any given instance and determining whether it even needs to be extended would result in false positives. This already requires tracking braces/blocks/scopes. As such, tracking the statement that contains a temporary is not significantly more complicated than tracking the block that contains said expression and temporary. In all likelihood, that is already being performed. Further, the proposed rules are significantly simpler than the current rules. This was identified by the numerous removals in the “Proposed Wording” section. That’s why this proposal would actually aid </span><code>static analyzers</code><span>.</span></p><h3 id="Can-this-even-be-implemented" data-id="Can-this-even-be-implemented"><a class="anchor hidden-xs" href="#Can-this-even-be-implemented" title="Can-this-even-be-implemented"><span class="octicon octicon-link"></span></a><span>Can this even be implemented?</span></h3><p><code>C++</code><span> is already doing this for variable and for some instances of temporaries. What is proposed is that all temporaries should consistently benefit from this feature and even for temporaries to be made consistent with variables.</span></p><p><span>This proposal is simple. A compiler already knows when any variable is destroyed. So for this feature to work the compiler just needs a index on a per function basis to allow looking up the point of variable destruction given the variable again assuming this isn’t already a part of the variable metadata in the compiler. Best case this is a member access. Worst case it is a map.</span></p><p><span>This cost, additional or not, pails in comparison to proposals that fix dangling generally. Those have quadratic or exponential costs resolving variable dependency graphs. So it is a little hard to object to this proposal’s cost without swearing off fixing dangling in the language altogether. Further, </span><code>C++</code><span> is already doing something similar with the </span><code>?:</code><span> ternary temporary lifetime extension example; </span><em><span>6.7.7 Temporary objects</span></em><span> </span><sup class="footnote-ref"><a href="#fn10" id="fnref10:2">[10:2]</a></sup><span>.</span></p><h3 id="Doesn’t-this-make-C-harder-to-teach" data-id="Doesn’t-this-make-C-harder-to-teach"><a class="anchor hidden-xs" href="#Doesn’t-this-make-C-harder-to-teach" title="Doesn’t-this-make-C-harder-to-teach"><span class="octicon octicon-link"></span></a><span>Doesn’t this make C++ harder to teach?</span></h3><p><span>Until the day that all dangling gets fixed, any incremental fixes to dangling still would require programmers to be able to identify any remaining dangling and know how to fix it specific to the given scenario, as there are multiple solutions. Since dangling occurs even for things as simple as constants and immediate dangling is so naturally easy to produce, </span><!--than--><span> dangling resolution still have to be taught, even to beginners. As this proposal fixes a lot of dangling, it makes teaching </span><code>C++</code><span> easier because it makes </span><code>C++</code><span> easier.</span></p><p><span>So, what do we teach now and what bearing does these teachings, the </span><code>C++</code><span> standard and this proposal have on one another.</span></p><p><strong><span>C++ Core Guidelines</span></strong><br><strong><span>F.42: Return a </span><code>T*</code><span> to indicate a position (only)</span></strong><span> </span><sup class="footnote-ref"><a href="#fn7" id="fnref7:1">[7:1]</a></sup><br><em><strong><span>Note</span></strong><span> Do not return a pointer to something that is not in the caller’s scope; see F.43.</span></em><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8:1">[8:1]</a></sup></p><p><span>Returning references to something in the caller’s scope is only natural. It is a part of our reference delegating programming model. A function when given a reference does not know how the instance was created and it doesn’t care as long as it is good for the life of the function call (and beyond).  Unfortunately, scoping temporary arguments to the statement instead of the containing block doesn’t just create immediate dangling but it provides to functions references to instances that are near death. These instances are almost dead on arrival. Having the ability to return a reference to a caller’s instance or a sub-instance thereof assumes, correctly, that reference from the caller’s scope would still be alive after this function call. The fact that temporary rules shortened the life to the statement is at odds with what we teach. This proposal restores to temporaries the lifetime of anonymously named variables which is not only natural but also consistent with what programmers already know. It is also in line with what we teach as was codified in the C++ Core Guidelines.</span></p><p><span>Other types of dangling can still occur. One simple type is directly called out in the C++ Core Guidelines.</span></p><p><strong><span>C++ Core Guidelines</span></strong><br><strong><span>F.43: Never (directly or indirectly) return a pointer or a reference to a local object</span></strong><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8:2">[8:2]</a></sup></p><p><em><strong><span>Reason</span></strong><span> To avoid the crashes and data corruption that can result from the use of such a dangling pointer.</span></em><span> </span><sup class="footnote-ref"><a href="#fn8" id="fnref8:3">[8:3]</a></sup></p><p><span>This proposal does not solve nor contradict this teaching. If anything, by cleaning up the other dangling it makes the remaining more visible. Also by hollowing out the majority and most common dangling in the middle, programmers are left with only indirect variants of the ultra trivial, such as indirect F.43 </span><sup class="footnote-ref"><a href="#fn8" id="fnref8:4">[8:4]</a></sup><span>, or the ultra rare and ultimately more complex dangling, which is naturally avoided by keeping one’s code simple.</span></p><p><span>Further, what is proposed is easy to teach because we already teach it and it makes </span><code>C++</code><span> even easier to teach.</span></p><ul>
<li><span>We already teach RAII and that local variables are scoped to the block that contains them. This proposal just extends the concept to temporaries. This increases good consistency and removes or reduces multiple bifurcations that are currently taught;</span>
<ul>
<li><span>that certain temporaries gets extended when assigned to a block but not when assigned to a argument</span></li>
<li><span>that variables and temporaries are all that different</span></li>
<li><span>that named and unnamed variables are different</span></li>
</ul>
</li>
<li><span>Somehow, we already teach the temporary lifetime extension rules which consist of numerous paragraphs and exception examples. These get replaced or greatly reduced to a few lines of verbage derived from </span><code>C</code><span>’s rule, which is only a couple of sentences.</span></li>
</ul><p><span>All of this can be done without adding any new keywords or any new attributes. We just use variable concepts that beginners are already familiar with.</span></p><h2 id="References" data-id="References"><a class="anchor hidden-xs" href="#References" title="References"><span class="octicon octicon-link"></span></a><span>References</span></h2><hr class="footnotes-sep"><section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2658r0.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2658r0.html</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/2022/p2623r2.html" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2623r2.html</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/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="#fnref3" class="footnote-backref">↩︎</a> <a href="#fnref3:1" class="footnote-backref">↩︎</a> <a href="#fnref3:2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0936r0.pdf" target="_blank" rel="noopener"><span>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0936r0.pdf</span></a> <a href="#fnref4" class="footnote-backref">↩︎</a> <a href="#fnref4:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2012r2.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2012r2.pdf</span></a> <a href="#fnref5" class="footnote-backref">↩︎</a> <a href="#fnref5:1" class="footnote-backref">↩︎</a> <a href="#fnref5:2" class="footnote-backref">↩︎</a> <a href="#fnref5:3" class="footnote-backref">↩︎</a> <a href="#fnref5:4" class="footnote-backref">↩︎</a> <a href="#fnref5:5" class="footnote-backref">↩︎</a> <a href="#fnref5:6" class="footnote-backref">↩︎</a> <a href="#fnref5:7" class="footnote-backref">↩︎</a> <a href="#fnref5:8" class="footnote-backref">↩︎</a> <a href="#fnref5:9" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2644r0.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2644r0.pdf</span></a> <a href="#fnref6" class="footnote-backref">↩︎</a> <a href="#fnref6:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn7" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f42-return-a-t-to-indicate-a-position-only" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f42-return-a-t-to-indicate-a-position-only</span></a> <a href="#fnref7" class="footnote-backref">↩︎</a> <a href="#fnref7:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn8" class="footnote-item"><p><a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f43-never-directly-or-indirectly-return-a-pointer-or-a-reference-to-a-local-object" target="_blank" rel="noopener"><span>https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f43-never-directly-or-indirectly-return-a-pointer-or-a-reference-to-a-local-object</span></a> <a href="#fnref8" class="footnote-backref">↩︎</a> <a href="#fnref8:1" class="footnote-backref">↩︎</a> <a href="#fnref8:2" class="footnote-backref">↩︎</a> <a href="#fnref8:3" class="footnote-backref">↩︎</a> <a href="#fnref8:4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn9" class="footnote-item"><p><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2731.pdf" target="_blank" rel="noopener"><span>https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2731.pdf</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/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="#fnref10" class="footnote-backref">↩︎</a> <a href="#fnref10:1" class="footnote-backref">↩︎</a> <a href="#fnref10:2" 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="#variable-scope" title="variable scope">variable scope</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="#R0" title="R0">R0</a></li>
</ul>
</li>
<li><a href="#Abstract" title="Abstract">Abstract</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a><ul class="nav">
<li><a href="#indirect-dangling-of-caller’s-local" title="indirect dangling of caller’s local">indirect dangling of caller’s local</a></li>
<li><a href="#immediate-dangling" title="immediate dangling">immediate dangling</a></li>
<li><a href="#towards-a-less-complicated-standard" title="towards a less complicated standard">towards a less complicated standard</a></li>
</ul>
</li>
<li><a href="#Proposed-Wording" title="Proposed Wording">Proposed Wording</a></li>
<li><a href="#Details" title="Details">Details</a><ul class="nav">
<li><a href="#Other-Anonymous-Things" title="Other Anonymous Things">Other Anonymous Things</a></li>
<li><a href="#Value-Categories" title="Value Categories">Value Categories</a></li>
<li><a href="#Avoids-superfluous-moves" title="Avoids superfluous moves">Avoids superfluous moves</a></li>
<li><a href="#Undo-forced-naming" title="Undo forced naming">Undo forced naming</a></li>
<li><a href="#Allows-more-anonymous-variables" title="Allows more anonymous variables">Allows more anonymous variables</a></li>
</ul>
</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="#Is-variable_scope-easy-to-teach" title="Is variable_scope easy to teach?">Is variable_scope easy to teach?</a></li>
<li><a href="#Won’t-this-break-a-lot-of-existing-code" title="Won’t this break a lot of existing code?">Won’t this break a lot of existing code?</a></li>
<li><a href="#Who-would-even-use-these-features-Their-isn’t-sufficient-use-to-justify-these-changes" title="Who would even use these features? Their isn’t sufficient use to justify these changes.">Who would even use these features? Their isn’t sufficient use to justify these changes.</a></li>
<li><a href="#Why-not-just-use-a-static-analyzer" title="Why not just use a static analyzer?">Why not just use a static analyzer?</a></li>
<li><a href="#Can-this-even-be-implemented" title="Can this even be implemented?">Can this even be implemented?</a></li>
<li><a href="#Doesn’t-this-make-C-harder-to-teach" title="Doesn’t this make C++ harder to teach?">Doesn’t this make C++ harder to teach?</a></li>
</ul>
</li>
<li><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="#variable-scope" title="variable scope">variable scope</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="#R0" title="R0">R0</a></li>
</ul>
</li>
<li><a href="#Abstract" title="Abstract">Abstract</a></li>
<li><a href="#Motivation" title="Motivation">Motivation</a><ul class="nav">
<li><a href="#indirect-dangling-of-caller’s-local" title="indirect dangling of caller’s local">indirect dangling of caller’s local</a></li>
<li><a href="#immediate-dangling" title="immediate dangling">immediate dangling</a></li>
<li><a href="#towards-a-less-complicated-standard" title="towards a less complicated standard">towards a less complicated standard</a></li>
</ul>
</li>
<li><a href="#Proposed-Wording" title="Proposed Wording">Proposed Wording</a></li>
<li><a href="#Details" title="Details">Details</a><ul class="nav">
<li><a href="#Other-Anonymous-Things" title="Other Anonymous Things">Other Anonymous Things</a></li>
<li><a href="#Value-Categories" title="Value Categories">Value Categories</a></li>
<li><a href="#Avoids-superfluous-moves" title="Avoids superfluous moves">Avoids superfluous moves</a></li>
<li><a href="#Undo-forced-naming" title="Undo forced naming">Undo forced naming</a></li>
<li><a href="#Allows-more-anonymous-variables" title="Allows more anonymous variables">Allows more anonymous variables</a></li>
</ul>
</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="#Is-variable_scope-easy-to-teach" title="Is variable_scope easy to teach?">Is variable_scope easy to teach?</a></li>
<li><a href="#Won’t-this-break-a-lot-of-existing-code" title="Won’t this break a lot of existing code?">Won’t this break a lot of existing code?</a></li>
<li><a href="#Who-would-even-use-these-features-Their-isn’t-sufficient-use-to-justify-these-changes" title="Who would even use these features? Their isn’t sufficient use to justify these changes.">Who would even use these features? Their isn’t sufficient use to justify these changes.</a></li>
<li><a href="#Why-not-just-use-a-static-analyzer" title="Why not just use a static analyzer?">Why not just use a static analyzer?</a></li>
<li><a href="#Can-this-even-be-implemented" title="Can this even be implemented?">Can this even be implemented?</a></li>
<li><a href="#Doesn’t-this-make-C-harder-to-teach" title="Doesn’t this make C++ harder to teach?">Doesn’t this make C++ harder to teach?</a></li>
</ul>
</li>
<li><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>
