CINXE.COM

Sutter’s Mill – Herb Sutter on software development

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="profile" href="http://gmpg.org/xfn/11"> <title>Sutter’s Mill &#8211; Herb Sutter on software development</title> <script type="text/javascript"> WebFontConfig = {"google":{"families":["Alegreya+Sans:r:latin,latin-ext","Noticia+Text:r,i,b,bi:latin,latin-ext"]},"api_url":"https:\/\/fonts-api.wp.com\/css"}; (function() { var wf = document.createElement('script'); wf.src = 'https://s0.wp.com/wp-content/plugins/custom-fonts/js/webfont.js'; wf.type = 'text/javascript'; wf.async = 'true'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(wf, s); })(); </script><style id="jetpack-custom-fonts-css">.wf-active code, .wf-active kbd, .wf-active pre, .wf-active samp{font-family:"Noticia Text",serif}.wf-active body{font-family:"Noticia Text",serif}.wf-active button, .wf-active input, .wf-active select{font-family:"Noticia Text",serif}.wf-active textarea{font-family:"Noticia Text",serif}.wf-active blockquote{font-family:"Noticia Text",serif}.wf-active code, .wf-active kbd, .wf-active pre, .wf-active tt, .wf-active var{font-family:"Noticia Text",serif}.wf-active .button, .wf-active .more-link, .wf-active button:not(.menu-toggle), .wf-active input[type="button"], .wf-active input[type="reset"], .wf-active input[type="submit"], .wf-active .posts-navigation .nav-links a, .wf-active #content #infinite-handle span button{font-family:"Noticia Text",serif}.wf-active input[type="email"], .wf-active input[type="password"], .wf-active input[type="search"], .wf-active input[type="text"], .wf-active input[type="url"], .wf-active textarea{font-family:"Noticia Text",serif}.wf-active .post-navigation{font-family:"Noticia Text",serif}.wf-active .main-navigation{font-family:"Noticia Text",serif}.wf-active .entry-content, .wf-active .entry-summary, .wf-active .page-content{font-family:"Noticia Text",serif}.wf-active .entry-content .subtitle{font-family:"Noticia Text",serif}.wf-active #comments{font-family:"Noticia Text",serif}.wf-active .comment-form label{font-family:"Noticia Text",serif}.wf-active .comment-form span.required{font-family:"Noticia Text",serif}.wf-active .widget_recent_entries span.post-date{font-family:"Noticia Text",serif}.wf-active .site-description{font-family:"Noticia Text",serif}.wf-active .site-posted-on time{font-family:"Noticia Text",serif}.wf-active .page-header:not(.page-header-light) .taxonomy-description{font-family:"Noticia Text",serif}.wf-active .light-text{font-family:"Noticia Text",serif}.wf-active .site-info{font-family:"Noticia Text",serif}.wf-active .sticky-label{font-family:"Noticia Text",serif}.wf-active .post-details, .wf-active .post-details a{font-family:"Noticia Text",serif}.wf-active .page-links{font-family:"Noticia Text",serif}.wf-active .post-edit-link{font-family:"Noticia Text",serif}.wf-active .post-author-card .author-description{font-family:"Noticia Text",serif}.wf-active #tinymce h1, .wf-active #tinymce h2, .wf-active #tinymce h3, .wf-active #tinymce h4, .wf-active #tinymce h5, .wf-active #tinymce h6, .wf-active .comment-content h1, .wf-active .comment-content h2, .wf-active .comment-content h3, .wf-active .comment-content h4, .wf-active .comment-content h5, .wf-active .comment-content h6, .wf-active .entry-content h1, .wf-active .entry-content h2, .wf-active .entry-content h3, .wf-active .entry-content h4, .wf-active .entry-content h5, .wf-active .entry-content h6, .wf-active .entry-summary h1, .wf-active .entry-summary h2, .wf-active .entry-summary h3, .wf-active .entry-summary h4, .wf-active .entry-summary h5, .wf-active .entry-summary h6, .wf-active .widget_text h1, .wf-active .widget_text h2, .wf-active .widget_text h3, .wf-active .widget_text h4, .wf-active .widget_text h5, .wf-active .widget_text h6{font-family:"Alegreya Sans",sans-serif;font-style:normal;font-weight:400}.wf-active h1{font-style:normal;font-weight:400}.wf-active h2{font-style:normal;font-weight:400}.wf-active h3{font-style:normal;font-weight:400}.wf-active h4{font-style:normal;font-weight:400}.wf-active h5{font-style:normal;font-weight:400}.wf-active h6{font-style:normal;font-weight:400}.wf-active blockquote h1, .wf-active blockquote h2, .wf-active blockquote h3, .wf-active blockquote h4{font-family:"Alegreya Sans",sans-serif;font-weight:400;font-style:normal}.wf-active div#jp-relatedposts h3.jp-relatedposts-headline em{font-family:"Alegreya Sans",sans-serif;font-style:normal;font-weight:400}.wf-active .comment-reply-title, .wf-active .comments-title{font-family:"Alegreya Sans",sans-serif;font-weight:400;font-style:normal}.wf-active .image-post-title{font-family:"Alegreya Sans",sans-serif;font-weight:400;font-style:normal}.wf-active .page-header:not(.page-header-light) h1{font-style:normal;font-weight:400}.wf-active .entry-title{font-family:"Alegreya Sans",sans-serif;font-style:normal;font-weight:400}.wf-active #post-cover-image .cover-meta .single-post-title{font-family:"Alegreya Sans",sans-serif;font-style:normal;font-weight:400}.wf-active #hero-header .site-title{font-family:"Alegreya Sans",sans-serif;font-style:normal;font-weight:400}.wf-active .site-header .site-title{font-style:normal;font-weight:400}.wf-active .site-header .site-description{font-style:normal;font-weight:400}</style> <meta name='robots' content='max-image-preview:large' /> <!-- Async WordPress.com Remote Login --> <script id="wpcom_remote_login_js"> var wpcom_remote_login_extra_auth = ''; function wpcom_remote_login_remove_dom_node_id( element_id ) { var dom_node = document.getElementById( element_id ); if ( dom_node ) { dom_node.parentNode.removeChild( dom_node ); } } function wpcom_remote_login_remove_dom_node_classes( class_name ) { var dom_nodes = document.querySelectorAll( '.' + class_name ); for ( var i = 0; i < dom_nodes.length; i++ ) { dom_nodes[ i ].parentNode.removeChild( dom_nodes[ i ] ); } } function wpcom_remote_login_final_cleanup() { wpcom_remote_login_remove_dom_node_classes( "wpcom_remote_login_msg" ); wpcom_remote_login_remove_dom_node_id( "wpcom_remote_login_key" ); wpcom_remote_login_remove_dom_node_id( "wpcom_remote_login_validate" ); wpcom_remote_login_remove_dom_node_id( "wpcom_remote_login_js" ); wpcom_remote_login_remove_dom_node_id( "wpcom_request_access_iframe" ); wpcom_remote_login_remove_dom_node_id( "wpcom_request_access_styles" ); } // Watch for messages back from the remote login window.addEventListener( "message", function( e ) { if ( e.origin === "https://r-login.wordpress.com" ) { var data = {}; try { data = JSON.parse( e.data ); } catch( e ) { wpcom_remote_login_final_cleanup(); return; } if ( data.msg === 'LOGIN' ) { // Clean up the login check iframe wpcom_remote_login_remove_dom_node_id( "wpcom_remote_login_key" ); var id_regex = new RegExp( /^[0-9]+$/ ); var token_regex = new RegExp( /^.*|.*|.*$/ ); if ( token_regex.test( data.token ) && id_regex.test( data.wpcomid ) ) { // We have everything we need to ask for a login var script = document.createElement( "script" ); script.setAttribute( "id", "wpcom_remote_login_validate" ); script.src = '/remote-login.php?wpcom_remote_login=validate' + '&wpcomid=' + data.wpcomid + '&token=' + encodeURIComponent( data.token ) + '&host=' + window.location.protocol + '//' + window.location.hostname + '&postid=5845' + '&is_singular='; document.body.appendChild( script ); } return; } // Safari ITP, not logged in, so redirect if ( data.msg === 'LOGIN-REDIRECT' ) { window.location = 'https://wordpress.com/log-in?redirect_to=' + window.location.href; return; } // Safari ITP, storage access failed, remove the request if ( data.msg === 'LOGIN-REMOVE' ) { var css_zap = 'html { -webkit-transition: margin-top 1s; transition: margin-top 1s; } /* 9001 */ html { margin-top: 0 !important; } * html body { margin-top: 0 !important; } @media screen and ( max-width: 782px ) { html { margin-top: 0 !important; } * html body { margin-top: 0 !important; } }'; var style_zap = document.createElement( 'style' ); style_zap.type = 'text/css'; style_zap.appendChild( document.createTextNode( css_zap ) ); document.body.appendChild( style_zap ); var e = document.getElementById( 'wpcom_request_access_iframe' ); e.parentNode.removeChild( e ); document.cookie = 'wordpress_com_login_access=denied; path=/; max-age=31536000'; return; } // Safari ITP if ( data.msg === 'REQUEST_ACCESS' ) { console.log( 'request access: safari' ); // Check ITP iframe enable/disable knob if ( wpcom_remote_login_extra_auth !== 'safari_itp_iframe' ) { return; } // If we are in a "private window" there is no ITP. var private_window = false; try { var opendb = window.openDatabase( null, null, null, null ); } catch( e ) { private_window = true; } if ( private_window ) { console.log( 'private window' ); return; } var iframe = document.createElement( 'iframe' ); iframe.id = 'wpcom_request_access_iframe'; iframe.setAttribute( 'scrolling', 'no' ); iframe.setAttribute( 'sandbox', 'allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-top-navigation-by-user-activation' ); iframe.src = 'https://r-login.wordpress.com/remote-login.php?wpcom_remote_login=request_access&origin=' + encodeURIComponent( data.origin ) + '&wpcomid=' + encodeURIComponent( data.wpcomid ); var css = 'html { -webkit-transition: margin-top 1s; transition: margin-top 1s; } /* 9001 */ html { margin-top: 46px !important; } * html body { margin-top: 46px !important; } @media screen and ( max-width: 660px ) { html { margin-top: 71px !important; } * html body { margin-top: 71px !important; } #wpcom_request_access_iframe { display: block; height: 71px !important; } } #wpcom_request_access_iframe { border: 0px; height: 46px; position: fixed; top: 0; left: 0; width: 100%; min-width: 100%; z-index: 99999; background: #23282d; } '; var style = document.createElement( 'style' ); style.type = 'text/css'; style.id = 'wpcom_request_access_styles'; style.appendChild( document.createTextNode( css ) ); document.body.appendChild( style ); document.body.appendChild( iframe ); } if ( data.msg === 'DONE' ) { wpcom_remote_login_final_cleanup(); } } }, false ); // Inject the remote login iframe after the page has had a chance to load // more critical resources window.addEventListener( "DOMContentLoaded", function( e ) { var iframe = document.createElement( "iframe" ); iframe.style.display = "none"; iframe.setAttribute( "scrolling", "no" ); iframe.setAttribute( "id", "wpcom_remote_login_key" ); iframe.src = "https://r-login.wordpress.com/remote-login.php" + "?wpcom_remote_login=key" + "&origin=aHR0cHM6Ly9oZXJic3V0dGVyLmNvbQ%3D%3D" + "&wpcomid=3379246" + "&time=1740481391"; document.body.appendChild( iframe ); }, false ); </script> <link rel='dns-prefetch' href='//s1.wp.com' /> <link rel='dns-prefetch' href='//s2.wp.com' /> <link rel='dns-prefetch' href='//s0.wp.com' /> <link rel="alternate" type="application/rss+xml" title="Sutter’s Mill &raquo; Feed" href="https://herbsutter.com/feed/" /> <link rel="alternate" type="application/rss+xml" title="Sutter’s Mill &raquo; Comments Feed" href="https://herbsutter.com/comments/feed/" /> <script type="text/javascript"> /* <![CDATA[ */ function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function () { oldonload(); func(); } } } /* ]]> */ </script> <script type="text/javascript"> /* <![CDATA[ */ window._wpemojiSettings = {"baseUrl":"https:\/\/s0.wp.com\/wp-content\/mu-plugins\/wpcom-smileys\/twemoji\/2\/72x72\/","ext":".png","svgUrl":"https:\/\/s0.wp.com\/wp-content\/mu-plugins\/wpcom-smileys\/twemoji\/2\/svg\/","svgExt":".svg","source":{"concatemoji":"https:\/\/s2.wp.com\/wp-includes\/js\/wp-emoji-release.min.js?m=1719498190i&ver=6.7.2-RC1-59780"}}; /*! This file is auto-generated */ !function(i,n){var o,s,e;function c(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function p(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data),r=(e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0),new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data));return t.every(function(e,t){return e===r[t]})}function u(e,t,n){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\uddfa\ud83c\uddf3","\ud83c\uddfa\u200b\ud83c\uddf3")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!n(e,"\ud83d\udc26\u200d\u2b1b","\ud83d\udc26\u200b\u2b1b")}return!1}function f(e,t,n){var r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):i.createElement("canvas"),a=r.getContext("2d",{willReadFrequently:!0}),o=(a.textBaseline="top",a.font="600 32px Arial",{});return e.forEach(function(e){o[e]=t(a,e,n)}),o}function t(e){var t=i.createElement("script");t.src=e,t.defer=!0,i.head.appendChild(t)}"undefined"!=typeof Promise&&(o="wpEmojiSettingsSupports",s=["flag","emoji"],n.supports={everything:!0,everythingExceptFlag:!0},e=new Promise(function(e){i.addEventListener("DOMContentLoaded",e,{once:!0})}),new Promise(function(t){var n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"}),a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=function(e){c(n=e.data),a.terminate(),t(n)})}catch(e){}c(n=f(s,u,p))}t(n)}).then(function(e){for(var t in e)n.supports[t]=e[t],n.supports.everything=n.supports.everything&&n.supports[t],"flag"!==t&&(n.supports.everythingExceptFlag=n.supports.everythingExceptFlag&&n.supports[t]);n.supports.everythingExceptFlag=n.supports.everythingExceptFlag&&!n.supports.flag,n.DOMReady=!1,n.readyCallback=function(){n.DOMReady=!0}}).then(function(){return e}).then(function(){var e;n.supports.everything||(n.readyCallback(),(e=n.source||{}).concatemoji?t(e.concatemoji):e.wpemoji&&e.twemoji&&(t(e.twemoji),t(e.wpemoji)))}))}((window,document),window._wpemojiSettings); /* ]]> */ </script> <link crossorigin='anonymous' rel='stylesheet' id='all-css-0-1' href='https://s2.wp.com/wp-content/mu-plugins/jetpack-plugin/moon/modules/infinite-scroll/infinity.css?m=1685131895i&cssminify=yes' type='text/css' media='all' /> <style id='wp-emoji-styles-inline-css'> img.wp-smiley, img.emoji { display: inline !important; border: none !important; box-shadow: none !important; height: 1em !important; width: 1em !important; margin: 0 0.07em !important; vertical-align: -0.1em !important; background: none !important; padding: 0 !important; } </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-2-1' href='https://s1.wp.com/_static/??-eJyljkEKwyAQRS9UMxoCWZWeRc1gTY3KzNjg7Zt2U+gq0OXn8R4f9qp8yYJZoKYWYmYI7ZgOKRyEEJ6jHvQwgmsxLeBS8Q+VoiNLHVh6wsEzX+C/kNxxOxP6WAwrSrVv3fbSRAWKy+kvPwmyEnPgr37brmaetNaTMfP6AnHzajo=&cssminify=yes' type='text/css' media='all' /> <style id='wp-block-library-inline-css'> .has-text-align-justify { text-align:justify; } .has-text-align-justify{text-align:justify;} </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-4-1' href='https://s2.wp.com/_static/??-eJzTLy/QzcxLzilNSS3WzyrWz01NyUxMzUnNTc0rQeEU5CRWphbp5qSmJyZX6uVm5uklFxfr6OPTDpRD5sM02efaGpoZmFkYGRuZGmQBAHPvL0Y=&cssminify=yes' type='text/css' media='all' /> <style id='jetpack-sharing-buttons-style-inline-css'> .jetpack-sharing-buttons__services-list{display:flex;flex-direction:row;flex-wrap:wrap;gap:0;list-style-type:none;margin:5px;padding:0}.jetpack-sharing-buttons__services-list.has-small-icon-size{font-size:12px}.jetpack-sharing-buttons__services-list.has-normal-icon-size{font-size:16px}.jetpack-sharing-buttons__services-list.has-large-icon-size{font-size:24px}.jetpack-sharing-buttons__services-list.has-huge-icon-size{font-size:36px}@media print{.jetpack-sharing-buttons__services-list{display:none!important}}.editor-styles-wrapper .wp-block-jetpack-sharing-buttons{gap:0;padding-inline-start:0}ul.jetpack-sharing-buttons__services-list.has-background{padding:1.25em 2.375em} </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-6-1' href='https://s2.wp.com/wp-content/plugins/coblocks/2.18.1-simple-rev.4/dist/coblocks-style.css?m=1681832297i&cssminify=yes' type='text/css' media='all' /> <style id='classic-theme-styles-inline-css'> /*! This file is auto-generated */ .wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none} </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-8-1' href='https://s1.wp.com/_static/??/wp-content/mu-plugins/core-compat/wp-mediaelement.css,/wp-content/mu-plugins/wpcom-bbpress-premium-themes.css?m=1432920480j&cssminify=yes' type='text/css' media='all' /> <style id='global-styles-inline-css'> :root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #fff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--color--medium-blue: #0087be;--wp--preset--color--bright-blue: #00aadc;--wp--preset--color--dark-gray: #4d4d4b;--wp--preset--color--light-gray: #b3b3b1;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--font-family--albert-sans: 'Albert Sans', sans-serif;--wp--preset--font-family--alegreya: Alegreya, serif;--wp--preset--font-family--arvo: Arvo, serif;--wp--preset--font-family--bodoni-moda: 'Bodoni Moda', serif;--wp--preset--font-family--bricolage-grotesque: 'Bricolage Grotesque', sans-serif;--wp--preset--font-family--cabin: Cabin, sans-serif;--wp--preset--font-family--chivo: Chivo, sans-serif;--wp--preset--font-family--commissioner: Commissioner, sans-serif;--wp--preset--font-family--cormorant: Cormorant, serif;--wp--preset--font-family--courier-prime: 'Courier Prime', monospace;--wp--preset--font-family--crimson-pro: 'Crimson Pro', serif;--wp--preset--font-family--dm-mono: 'DM Mono', monospace;--wp--preset--font-family--dm-sans: 'DM Sans', sans-serif;--wp--preset--font-family--dm-serif-display: 'DM Serif Display', serif;--wp--preset--font-family--domine: Domine, serif;--wp--preset--font-family--eb-garamond: 'EB Garamond', serif;--wp--preset--font-family--epilogue: Epilogue, sans-serif;--wp--preset--font-family--fahkwang: Fahkwang, sans-serif;--wp--preset--font-family--figtree: Figtree, sans-serif;--wp--preset--font-family--fira-sans: 'Fira Sans', sans-serif;--wp--preset--font-family--fjalla-one: 'Fjalla One', sans-serif;--wp--preset--font-family--fraunces: Fraunces, serif;--wp--preset--font-family--gabarito: Gabarito, system-ui;--wp--preset--font-family--ibm-plex-mono: 'IBM Plex Mono', monospace;--wp--preset--font-family--ibm-plex-sans: 'IBM Plex Sans', sans-serif;--wp--preset--font-family--ibarra-real-nova: 'Ibarra Real Nova', serif;--wp--preset--font-family--instrument-serif: 'Instrument Serif', serif;--wp--preset--font-family--inter: Inter, sans-serif;--wp--preset--font-family--josefin-sans: 'Josefin Sans', sans-serif;--wp--preset--font-family--jost: Jost, sans-serif;--wp--preset--font-family--libre-baskerville: 'Libre Baskerville', serif;--wp--preset--font-family--libre-franklin: 'Libre Franklin', sans-serif;--wp--preset--font-family--literata: Literata, serif;--wp--preset--font-family--lora: Lora, serif;--wp--preset--font-family--merriweather: Merriweather, serif;--wp--preset--font-family--montserrat: Montserrat, sans-serif;--wp--preset--font-family--newsreader: Newsreader, serif;--wp--preset--font-family--noto-sans-mono: 'Noto Sans Mono', sans-serif;--wp--preset--font-family--nunito: Nunito, sans-serif;--wp--preset--font-family--open-sans: 'Open Sans', sans-serif;--wp--preset--font-family--overpass: Overpass, sans-serif;--wp--preset--font-family--pt-serif: 'PT Serif', serif;--wp--preset--font-family--petrona: Petrona, serif;--wp--preset--font-family--piazzolla: Piazzolla, serif;--wp--preset--font-family--playfair-display: 'Playfair Display', serif;--wp--preset--font-family--plus-jakarta-sans: 'Plus Jakarta Sans', sans-serif;--wp--preset--font-family--poppins: Poppins, sans-serif;--wp--preset--font-family--raleway: Raleway, sans-serif;--wp--preset--font-family--roboto: Roboto, sans-serif;--wp--preset--font-family--roboto-slab: 'Roboto Slab', serif;--wp--preset--font-family--rubik: Rubik, sans-serif;--wp--preset--font-family--rufina: Rufina, serif;--wp--preset--font-family--sora: Sora, sans-serif;--wp--preset--font-family--source-sans-3: 'Source Sans 3', sans-serif;--wp--preset--font-family--source-serif-4: 'Source Serif 4', serif;--wp--preset--font-family--space-mono: 'Space Mono', monospace;--wp--preset--font-family--syne: Syne, sans-serif;--wp--preset--font-family--texturina: Texturina, serif;--wp--preset--font-family--urbanist: Urbanist, sans-serif;--wp--preset--font-family--work-sans: 'Work Sans', sans-serif;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}.has-albert-sans-font-family{font-family: var(--wp--preset--font-family--albert-sans) !important;}.has-alegreya-font-family{font-family: var(--wp--preset--font-family--alegreya) !important;}.has-arvo-font-family{font-family: var(--wp--preset--font-family--arvo) !important;}.has-bodoni-moda-font-family{font-family: var(--wp--preset--font-family--bodoni-moda) !important;}.has-bricolage-grotesque-font-family{font-family: var(--wp--preset--font-family--bricolage-grotesque) !important;}.has-cabin-font-family{font-family: var(--wp--preset--font-family--cabin) !important;}.has-chivo-font-family{font-family: var(--wp--preset--font-family--chivo) !important;}.has-commissioner-font-family{font-family: var(--wp--preset--font-family--commissioner) !important;}.has-cormorant-font-family{font-family: var(--wp--preset--font-family--cormorant) !important;}.has-courier-prime-font-family{font-family: var(--wp--preset--font-family--courier-prime) !important;}.has-crimson-pro-font-family{font-family: var(--wp--preset--font-family--crimson-pro) !important;}.has-dm-mono-font-family{font-family: var(--wp--preset--font-family--dm-mono) !important;}.has-dm-sans-font-family{font-family: var(--wp--preset--font-family--dm-sans) !important;}.has-dm-serif-display-font-family{font-family: var(--wp--preset--font-family--dm-serif-display) !important;}.has-domine-font-family{font-family: var(--wp--preset--font-family--domine) !important;}.has-eb-garamond-font-family{font-family: var(--wp--preset--font-family--eb-garamond) !important;}.has-epilogue-font-family{font-family: var(--wp--preset--font-family--epilogue) !important;}.has-fahkwang-font-family{font-family: var(--wp--preset--font-family--fahkwang) !important;}.has-figtree-font-family{font-family: var(--wp--preset--font-family--figtree) !important;}.has-fira-sans-font-family{font-family: var(--wp--preset--font-family--fira-sans) !important;}.has-fjalla-one-font-family{font-family: var(--wp--preset--font-family--fjalla-one) !important;}.has-fraunces-font-family{font-family: var(--wp--preset--font-family--fraunces) !important;}.has-gabarito-font-family{font-family: var(--wp--preset--font-family--gabarito) !important;}.has-ibm-plex-mono-font-family{font-family: var(--wp--preset--font-family--ibm-plex-mono) !important;}.has-ibm-plex-sans-font-family{font-family: var(--wp--preset--font-family--ibm-plex-sans) !important;}.has-ibarra-real-nova-font-family{font-family: var(--wp--preset--font-family--ibarra-real-nova) !important;}.has-instrument-serif-font-family{font-family: var(--wp--preset--font-family--instrument-serif) !important;}.has-inter-font-family{font-family: var(--wp--preset--font-family--inter) !important;}.has-josefin-sans-font-family{font-family: var(--wp--preset--font-family--josefin-sans) !important;}.has-jost-font-family{font-family: var(--wp--preset--font-family--jost) !important;}.has-libre-baskerville-font-family{font-family: var(--wp--preset--font-family--libre-baskerville) !important;}.has-libre-franklin-font-family{font-family: var(--wp--preset--font-family--libre-franklin) !important;}.has-literata-font-family{font-family: var(--wp--preset--font-family--literata) !important;}.has-lora-font-family{font-family: var(--wp--preset--font-family--lora) !important;}.has-merriweather-font-family{font-family: var(--wp--preset--font-family--merriweather) !important;}.has-montserrat-font-family{font-family: var(--wp--preset--font-family--montserrat) !important;}.has-newsreader-font-family{font-family: var(--wp--preset--font-family--newsreader) !important;}.has-noto-sans-mono-font-family{font-family: var(--wp--preset--font-family--noto-sans-mono) !important;}.has-nunito-font-family{font-family: var(--wp--preset--font-family--nunito) !important;}.has-open-sans-font-family{font-family: var(--wp--preset--font-family--open-sans) !important;}.has-overpass-font-family{font-family: var(--wp--preset--font-family--overpass) !important;}.has-pt-serif-font-family{font-family: var(--wp--preset--font-family--pt-serif) !important;}.has-petrona-font-family{font-family: var(--wp--preset--font-family--petrona) !important;}.has-piazzolla-font-family{font-family: var(--wp--preset--font-family--piazzolla) !important;}.has-playfair-display-font-family{font-family: var(--wp--preset--font-family--playfair-display) !important;}.has-plus-jakarta-sans-font-family{font-family: var(--wp--preset--font-family--plus-jakarta-sans) !important;}.has-poppins-font-family{font-family: var(--wp--preset--font-family--poppins) !important;}.has-raleway-font-family{font-family: var(--wp--preset--font-family--raleway) !important;}.has-roboto-font-family{font-family: var(--wp--preset--font-family--roboto) !important;}.has-roboto-slab-font-family{font-family: var(--wp--preset--font-family--roboto-slab) !important;}.has-rubik-font-family{font-family: var(--wp--preset--font-family--rubik) !important;}.has-rufina-font-family{font-family: var(--wp--preset--font-family--rufina) !important;}.has-sora-font-family{font-family: var(--wp--preset--font-family--sora) !important;}.has-source-sans-3-font-family{font-family: var(--wp--preset--font-family--source-sans-3) !important;}.has-source-serif-4-font-family{font-family: var(--wp--preset--font-family--source-serif-4) !important;}.has-space-mono-font-family{font-family: var(--wp--preset--font-family--space-mono) !important;}.has-syne-font-family{font-family: var(--wp--preset--font-family--syne) !important;}.has-texturina-font-family{font-family: var(--wp--preset--font-family--texturina) !important;}.has-urbanist-font-family{font-family: var(--wp--preset--font-family--urbanist) !important;}.has-work-sans-font-family{font-family: var(--wp--preset--font-family--work-sans) !important;} :where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;} :root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;} :where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;} </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-10-1' href='https://s2.wp.com/_static/??-eJydj70OgzAMhF+oqfsDZar6KFUxFgQSx8KOUN++AXXo0InldDd8dzpYxGFiIzaI2UnIvWeFkUxeOH0zxJQYnp4RemKafSH0vz2i6gF+Sm2gSAqSW/DckVARNldy8DrQ7C6g9g60BywItCHhtGt2vbNNu0UwxbXiEe/n5trcqvpUV+MHNwBp7g==&cssminify=yes' type='text/css' media='all' /> <style id='independent-publisher-2-style-inline-css'> .cat-links, .post-tags, .tags-links { clip: rect(1px, 1px, 1px, 1px); height: 1px; position: absolute; overflow: hidden; width: 1px; } </style> <style id='akismet-widget-style-inline-css'> .a-stats { --akismet-color-mid-green: #357b49; --akismet-color-white: #fff; --akismet-color-light-grey: #f6f7f7; max-width: 350px; width: auto; } .a-stats * { all: unset; box-sizing: border-box; } .a-stats strong { font-weight: 600; } .a-stats a.a-stats__link, .a-stats a.a-stats__link:visited, .a-stats a.a-stats__link:active { background: var(--akismet-color-mid-green); border: none; box-shadow: none; border-radius: 8px; color: var(--akismet-color-white); cursor: pointer; display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen-Sans', 'Ubuntu', 'Cantarell', 'Helvetica Neue', sans-serif; font-weight: 500; padding: 12px; text-align: center; text-decoration: none; transition: all 0.2s ease; } /* Extra specificity to deal with TwentyTwentyOne focus style */ .widget .a-stats a.a-stats__link:focus { background: var(--akismet-color-mid-green); color: var(--akismet-color-white); text-decoration: none; } .a-stats a.a-stats__link:hover { filter: brightness(110%); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06), 0 0 2px rgba(0, 0, 0, 0.16); } .a-stats .count { color: var(--akismet-color-white); display: block; font-size: 1.5em; line-height: 1.4; padding: 0 13px; white-space: nowrap; } </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-12-1' href='https://s1.wp.com/_static/??-eJzTLy/QTc7PK0nNK9HPLdUtyClNz8wr1i9KTcrJTwcy0/WTi5G5ekCujj52Temp+bo5+cmJJZn5eSgc3bScxMwikFb7XFtDE1NLExMLc0OTLACohS2q&cssminify=yes' type='text/css' media='all' /> <link crossorigin='anonymous' rel='stylesheet' id='print-css-13-1' href='https://s1.wp.com/wp-content/mu-plugins/global-print/global-print.css?m=1465851035i&cssminify=yes' type='text/css' media='print' /> <style id='jetpack-global-styles-frontend-style-inline-css'> :root { --font-headings: unset; --font-base: unset; --font-headings-default: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; --font-base-default: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;} </style> <link crossorigin='anonymous' rel='stylesheet' id='all-css-16-1' href='https://s2.wp.com/wp-content/themes/h4/global.css?m=1420737423i&cssminify=yes' type='text/css' media='all' /> <script type="text/javascript" id="wpcom-actionbar-placeholder-js-extra"> /* <![CDATA[ */ var actionbardata = {"siteID":"3379246","postID":"0","siteURL":"https:\/\/herbsutter.com","xhrURL":"https:\/\/herbsutter.com\/wp-admin\/admin-ajax.php","nonce":"99d0951eff","isLoggedIn":"","statusMessage":"","subsEmailDefault":"instantly","proxyScriptUrl":"https:\/\/s0.wp.com\/wp-content\/js\/wpcom-proxy-request.js?ver=20211021","i18n":{"followedText":"New posts from this site will now appear in your <a href=\"https:\/\/wordpress.com\/reader\">Reader<\/a>","foldBar":"Collapse this bar","unfoldBar":"Expand this bar","shortLinkCopied":"Shortlink copied to clipboard."}}; /* ]]> */ </script> <script type="text/javascript" id="jetpack-mu-wpcom-settings-js-before"> /* <![CDATA[ */ var JETPACK_MU_WPCOM_SETTINGS = {"assetsUrl":"https:\/\/s1.wp.com\/wp-content\/mu-plugins\/jetpack-mu-wpcom-plugin\/moon\/jetpack_vendor\/automattic\/jetpack-mu-wpcom\/src\/build\/"}; /* ]]> */ </script> <script crossorigin='anonymous' type='text/javascript' src='https://s1.wp.com/wp-content/js/rlt-proxy.js?m=1720530689i'></script> <script type="text/javascript" id="rlt-proxy-js-after"> /* <![CDATA[ */ rltInitialize( {"token":null,"iframeOrigins":["https:\/\/widgets.wp.com"]} ); /* ]]> */ </script> <link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://herbsutter.wordpress.com/xmlrpc.php?rsd" /> <meta name="generator" content="WordPress.com" /> <link rel='shortlink' href='https://wp.me/eb5Y' /> <!-- Jetpack Open Graph Tags --> <meta property="og:type" content="website" /> <meta property="og:title" content="Sutter’s Mill" /> <meta property="og:description" content="Herb Sutter on software development" /> <meta property="og:url" content="https://herbsutter.com/" /> <meta property="og:site_name" content="Sutter’s Mill" /> <meta property="og:image" content="https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=200&#038;ts=1740481391" /> <meta property="og:image:width" content="200" /> <meta property="og:image:height" content="200" /> <meta property="og:image:alt" content="" /> <meta property="og:locale" content="en_US" /> <!-- End Jetpack Open Graph Tags --> <link rel="shortcut icon" type="image/x-icon" href="https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=32" sizes="16x16" /> <link rel="icon" type="image/x-icon" href="https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=32" sizes="16x16" /> <link rel="apple-touch-icon" href="https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=114" /> <link rel='openid.server' href='https://herbsutter.com/?openidserver=1' /> <link rel='openid.delegate' href='https://herbsutter.com/' /> <link rel="search" type="application/opensearchdescription+xml" href="https://herbsutter.com/osd.xml" title="Sutter’s Mill" /> <link rel="search" type="application/opensearchdescription+xml" href="https://s1.wp.com/opensearch.xml" title="WordPress.com" /> <style type="text/css"> .recentcomments a { display: inline !important; padding: 0 !important; margin: 0 !important; } table.recentcommentsavatartop img.avatar, table.recentcommentsavatarend img.avatar { border: 0px; margin: 0; } table.recentcommentsavatartop a, table.recentcommentsavatarend a { border: 0px !important; background-color: transparent !important; } td.recentcommentsavatarend, td.recentcommentsavatartop { padding: 0px 0px 1px 0px; margin: 0px; } td.recentcommentstextend { border: none !important; padding: 0px 0px 2px 10px; } .rtl td.recentcommentstextend { padding: 0px 10px 2px 0px; } td.recentcommentstexttop { border: none; padding: 0px 0px 0px 10px; } .rtl td.recentcommentstexttop { padding: 0px 10px 0px 0px; } </style> <meta name="description" content="Herb Sutter on software development" /> </head> <body class="home blog wp-embed-responsive customizer-styles-applied has-sidebar jetpack-reblog-enabled categories-hidden tags-hidden"> <div id="page" class="hfeed site"> <a class="skip-link screen-reader-text" href="#content">Skip to content</a> <div id="hero-header" class="site-hero-section"> <header id="masthead" class="site-header" role="banner"> <div class="inner"> <div class="site-branding"> <a class="site-logo-link" href="https://herbsutter.com/"> <img alt='' src='https://0.gravatar.com/avatar/928f5830f12d8977791539452bfc25c92912322476f0725253697ee1c45ce036?s=80&#038;d=identicon&#038;r=G' srcset='https://0.gravatar.com/avatar/928f5830f12d8977791539452bfc25c92912322476f0725253697ee1c45ce036?s=80&#038;d=identicon&#038;r=G 1x, https://0.gravatar.com/avatar/928f5830f12d8977791539452bfc25c92912322476f0725253697ee1c45ce036?s=120&#038;d=identicon&#038;r=G 1.5x, https://0.gravatar.com/avatar/928f5830f12d8977791539452bfc25c92912322476f0725253697ee1c45ce036?s=160&#038;d=identicon&#038;r=G 2x, https://0.gravatar.com/avatar/928f5830f12d8977791539452bfc25c92912322476f0725253697ee1c45ce036?s=240&#038;d=identicon&#038;r=G 3x, https://0.gravatar.com/avatar/928f5830f12d8977791539452bfc25c92912322476f0725253697ee1c45ce036?s=320&#038;d=identicon&#038;r=G 4x' class='avatar avatar-80 site-logo-image' height='80' width='80' loading='eager' decoding='async' /> </a><!-- .site-logo-link --> <h1 class="site-title"><a href="https://herbsutter.com/" rel="home">Sutter’s Mill</a></h1> <p class="site-description">Herb Sutter on software development</p> </div><!-- .site-branding --> </div><!-- .inner --> </header><!-- #masthead --> </div> <div id="content-wrapper" class="content-wrapper"> <div id="content" class="site-content"> <div id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <article id="post-5845" class="post-5845 post type-post status-publish format-standard hentry category-c"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2025/02/17/trip-report-february-2025-iso-c-standards-meeting-hagenberg-austria/" rel="bookmark">Trip report: February 2025 ISO C++ standards meeting (Hagenberg,&nbsp;Austria)</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>On Saturday, the ISO C++ committee completed the second-last design meeting of C++26, held in Hagenberg, Austria. There is just one meeting left before the C++26 feature set is finalized in June 2025 and draft C++26 is sent out for its international comment ballot (aka “Committee Draft” or “CD”), and C++26 is on track to be technically finalized two more meetings after that in early 2026.</p> <p>This meeting was hosted by the <strong>University of Applied Sciences of Upper Austria</strong>, <strong>RISC Software GmbH</strong>, <strong>Softwarepark Hagenberg Upper Austria</strong>, <strong>Dynatrace</strong>, and <strong>Count It Group</strong>. Our hosts arranged for high-quality facilities at the University for our six-day meeting from Monday through Saturday. We had over 200 attendees, about two-thirds in-person and the others remote via Zoom, formally representing 31 nations. At each meeting we regularly have new guest attendees who have never attended before, and this time there were 36 new first-time guest attendees, mostly in-person, in addition to new attendees who are official national body representatives. To all of them, once again welcome!</p> <p><a href="https://isocpp.org/std/the-committee">The committee</a> currently has 23 active subgroups, 13 of which met in 7 parallel tracks throughout the week. Some groups ran all week, and others ran for a few days or a part of a day, depending on their workloads. We also had combined informational evening sessions to inform the committee broadly about progress on one key topic this week: reflection wording review, and concurrent queues. You can find a brief summary of ISO procedures <a href="https://isocpp.org/std/iso-iec-jtc1-procedures">here</a>.</p> <h2 class="wp-block-heading">Highlights</h2> <p>This time, the committee adopted the next set of features for C++26, and made significant progress on other features that are now expected to be complete in time for C+26.</p> <p>In addition to features already approved for C++26 at previous meetings, at this meeting three major features made strong progress. In the core language:</p> <ul class="wp-block-list"> <li><strong>P2900 Contracts</strong> was adopted for C++26</li> <li><strong>P2786 Trivial Relocatability</strong> was adopted for C++26</li> <li><strong>P1967 #embed</strong> was adopted for C++26</li> </ul> <p>In the standard library:</p> <ul class="wp-block-list"> <li><strong>P3471 Standard Library Hardening</strong> (which is also the first use of contracts) was adopted for C++26</li> <li><strong>P0447 std::hive</strong> was adopted for C++26</li> </ul> <p>Other noteworthy progress:</p> <ul class="wp-block-list"> <li><strong>P2996 Reflection</strong> is almost done its specification wording review aiming for C++26, and is expected to come up for vote for inclusion in C++26 at the June meeting</li> <li>[ETA:] <strong>Profiles</strong> papers received a lot of discussion time in EWG (language evolution working group) and feedback to improve consensus, and EWG encouraged pursuing a white paper to systematically address <strong>undefined behavior </strong>that could be concurrent with C++26 (some UB is already addressed in C++26; see below for more)</li> </ul> <h2 class="wp-block-heading">Language safety and software security improvements adopted for C++26</h2> <p>C++26 adopted two major features that improve language/library safety and software security: contracts [ETA: which help making programs functionally safe and can be a tool for specifying language/library safety checks], and a security-hardened standard library that has already delivered actual important security improvements just by recompiling/relinking existing C++ code (see references below) [ETA: which uses contracts to add some library safety guarantees for software security].</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Note: For definitions of “language safety” and “software security” and similar terms, see my 2024 essay <a href="https://herbsutter.com/2024/03/11/safety-in-context/">“C++ safety, in context.”</a></p> </blockquote> <h3 class="wp-block-heading">C++26 Contracts</h3> <p>First, years in the making, we adopted <a href="https://wg21.link/P2900"><strong>P2900R14 “Contracts for C++”</strong></a> by <strong>Joshua Berne, Timur Doumler, and Andrzej Krzemieński, </strong>with<strong> Gašper Ažman, Peter Bindels, Louis Dionne, Tom Honermann, Lori Hughes, John Lakos, Lisa Lippincott, Jens Maurer, Ryan McDougall, Jason Merrill, Oliver J. Rosten, Iain Sandoe, </strong>and <strong>Ville Voutilainen</strong>. This is a huge paper (119 pages) that adds preconditions, postconditions, and <code>contract_assert</code> (a major improvement that brings C’s “assert” macro into the language, with improvements). For an overview, see Timur Doumler’s blog post <a href="https://timur.audio/contracts_explained_in_5_mins">“Contracts for C++ explained in 5 minutes.”</a> The main change last week is that the committee decided to postpone supporting contracts on virtual functions; work will continue on that and other extensions. Thanks to the coauthors, and to everyone in Study Group 21 (SG21) and the language evolution working group (EWG) and everyone who commented and gave feedback, for their hard work on this feature for many years!</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p><em>Note: This is the second time contracts has been voted into draft standard C++. It was briefly part of draft C++20, but was then removed for further work.</em></p> </blockquote> <p>Relatedly, <a href="https://wg21.link/P1494"><strong>P1494R4 “Partial program correctness”</strong></a> by <strong>Davis Herring</strong> adds the idea of “observable checkpoints” that limit the ability of undefined behavior to perform time-travel optimizations. This helps to eliminate some optimization pitfalls that range from not actually executing an enforced contract (see contracts, above) to security vulnerabilities. The paper also provides <code>std::observable()</code> as a manual way of adding such a checkpoint in code.</p> <h3 class="wp-block-heading">C++26 hardened standard library</h3> <p>The second is another big step for language and library safety in C++26. Recall that:</p> <ul class="wp-block-list"> <li>C++23 already eliminated returning a dangling reference to a local object at compile time  (did you know that? <a href="https://godbolt.org/z/j8ojhn5cs">try it now on Godbolt</a>), which has already removed one common source of silent dangling.</li> <li>C++26 has already eliminated undefined behavior from uninitialized variables.</li> <li>And now in C++26…</li> </ul> <p><strong>… </strong><a href="https://wg21.link/P3471"><strong>P3471R4 “Standard library hardening”</strong></a> by <strong>Konstantin Varlamov </strong>and<strong> Louis Dionne</strong> provides <strong>initial portable, cross-platform security guarantees for the C++ standard library</strong> too as part of C++26. It turns some common and frequently-exploited instances of undefined behavior in the C++ standard library into a contract violation (note: that makes it also the first user of the just-adopted contracts language feature, above! yes, WG21 does try to coordinate its delivered features).</p> <p>[Corrected:] In particular, only three (3) programming language weaknesses made the top 15 most dangerous software weaknesses in the <a href="https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html">MITRE 2024 CWE Top 25 Most Dangerous Software Weaknesses</a> — and the top two are <strong>Out-of-Bounds Write (#2)</strong> and <strong>Out-of-Bounds Read (#6)</strong>.</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>This is why I keep repeating that, yes, we need to improve C (especially) and C++ memory safety, but that is far from the only thing we as an industry need to do. As we harden one area, attackers just shift to the next slowest animal in the herd. Already, above, we are seeing more and more of the MITRE Top 25 be <em>not</em> programming language memory safety issues&#8230; in 2024, it&#8217;s down to just 3 of the top 15. Sure we need to fix those issues and others like them, but let&#8217;s never forget that we need to fix the other 12 of the top 15 too! For more on this, again please see my <a href="https://herbsutter.com/2024/03/11/safety-in-context/">&#8220;C++ safety, in context&#8221;</a> essay.</p> </blockquote> <p>This continues to demonstrate what I’ve explained many times: Bounds safety is the lowest-hanging fruit in terms of things we need to address first. The <a href="https://security.googleblog.com/2024/11/retrofitting-spatial-safety-to-hundreds.html">Google security article</a> linked below points out that bounds (spatial) safety vulnerabilities represent 40% of in-the-wild serious memory safety exploits over the past decade. That’s why it’s a big deal that, as of Saturday, the C++26 hardened standard library focuses on bounds safety and requires that the all of following are guaranteed to be bounds-checked:</p> <ul class="wp-block-list"> <li>In std::span: operator[], front, back, first, last, subspan, and constructors</li> <li>In the std::string_views: operator[], front, back, remove_prefix, remove_suffix</li> <li>In all sequence containers (e.g., std::vector, std::array): operator[], front, back, pop_front, pop_back</li> <li>In the std::strings: operator[], front, back, pop_back</li> <li>In the multidimensional std::mdspan: operator[], and constructors</li> <li>In std::bitset: operator[]</li> <li>In std::valarray: operator[]</li> <li>In std::optional: operator-&gt;, operator*</li> <li>In std::expected: operator-&gt;, operator*, error</li> </ul> <p>And that’s just a start, that has already made a real impact on hardening production code including on popular platforms.</p> <p>Importantly, <em>user code gets this benefit just by building with a hardened C++26 standard library — without any code changes</em>. If you’ve seen any of my recent talks, you know this is close to my heart… see especially</p> <ul class="wp-block-list"> <li><a href="https://youtu.be/nXcswVW0-Wk?si=ZNsI1yshFsjnDNpE&amp;t=1736">this short clip</a> in my code::dive (Nov 2024) talk about why C++26 removing undefined behavior for uninitialized locals is a model for adoptability; and also </li> <li><a href="https://youtu.be/nXcswVW0-Wk?si=CRmzhnv_gLu_ISJy&amp;t=3475">this short clip</a> in the Q&amp;A of that talk about the societal value of improving C++.</li> </ul> <p>I think that Konstantin and Louis express that value proposition beautifully in their paper’s Motivation section, and I’ll quote most of their appeal here (<strong><em>emphasis</em></strong> original)… they “get it”:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p><em>“There has been significantly increased attention to safety and security in C++ over the last few years, as exemplified by the well-known White House report and numerous recent security-related proposals.</em></p> <p><em>“While it is important to explore ways to make <strong>new</strong> code safer, we believe that the highest priority to deliver immediate real-world value should be to make <strong>existing</strong> code safer with minimal or no effort on behalf of users. Indeed, the amount of existing security-critical C++ code is so large that rewriting it or modifying it is both economically unviable and dangerous given the risk of introducing new issues.</em></p> <p><em>“There have been a few proposals accepted recently that eliminate some cases of undefined behavior in the core language. The standard library also contains many instances of undefined behavior, some of which is a direct source of security vulnerabilities; addressing those is often trivial, can be done with low overhead and almost no work on behalf of users.</em></p> <p><em>“In fact, at the moment all three major library implementations have some notion of a hardened or debug mode. This clearly shows interest, both from users and from implementers, in having a safer mode for the standard library. However, we believe these efforts would be vastly more useful if they were standardized and provided portable, cross-platform guarantees to users; as it stands, implementations differ in levels of coverage, performance guarantees and ways to enable the safer mode.</em></p> <p><em>“Finally, leaving security of the library to be a pure vendor extension fails to position ISO C++ as providing a credible solution for code bases with formal security requirements. We believe that formally requiring the basic safety guarantees that most implementations already provide in one way or another could make a significant difference from the point of view of anyone writing or following safety and security coding standards and guidelines.”</em></p> </blockquote> <p>In the next section, they demonstrate that this isn’t some theoretical improvement — it’s an improvement that is standardizing what is already shipping and significantly hardening existing C++ code today (<strong><em>emphasis </em></strong>added):</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p><em>“All three major implementations provide vendor-specific ways of enabling library assertions as proposed in this paper, today.</em></p> <ul class="wp-block-list"> <li><em>We have experience deploying hardening on Apple platforms in several existing codebases.</em></li> <li><em>Google recently published </em><a href="https://security.googleblog.com/2024/11/retrofitting-spatial-safety-to-hundreds.html"><em>an article</em></a><em> where they describe their experience with <strong>deploying this very technology to hundreds of millions of lines of code</strong>. They reported a <strong>performance impact as low as 0.3% and finding over 1000 bugs</strong>, including security-critical ones.</em></li> <li><em>Google Andromeda published </em><a href="https://bughunters.google.com/blog/6368559657254912/llvm-s-rfc-c-buffer-hardening-at-google"><em>an article</em></a><em> ~1 year ago about their successful experience enabling hardening.</em></li> <li><em>The libc++ maintainers have received numerous informal reports of hardening being turned on and helping find bugs in codebases.</em></li> </ul> <p><em><strong>Overall, standard library hardening has been a huge success, in fact we never expected so much success. The reception has been overwhelmingly positive</strong> and while the quality of implementation will never be perfect, we are working hard to expand the scope of hardening in libc++, to improve its performance and the user experience.</em></p> </blockquote> <p>This further demonstrates that not only is C++ making serious progress to improve, but that <strong>many of the language safety and software security improvements are already shipping without waiting for standardization</strong>. Standardization is still important, of course, because it makes these improvements available portably, with portable guarantees for C++ code on all platforms.</p> <h2 class="wp-block-heading">More things adopted for C++26: Core language changes/features</h2> <p>Note: These links are to the most recent public version of each paper. If a paper was tweaked at the meeting before being approved, the link tracks and will automatically find the updated version as soon as it’s uploaded to the public site.</p> <p>In addition to fixing a list of defect reports, the core language adopted 8 papers, including contracts (above) and the following…</p> <p><a href="https://wg21.link/P2786"><strong>P2786R13 “Trivial relocatability for C++26”</strong></a> by <strong>Alisdair Meredith, Mungo Gill, Joshua Berne, Corentin Jabot, Pablo Halpern</strong>, and <strong>Lori Hughes</strong> adds stronger support for optimizing the copying of memcpy-able types in the C++ language. This removes a source of “undefined behavior” that many container libraries rely on because it happens to be useful and probably-benign, and not only guarantees it is well-defined but also makes the optimizations more widely available for more types. Thank you, Alisdair and your collaborators, and thanks also to the authors of other trivial-relocation proposals that were not adopted! All of the input has made the result better, and we appreciate all the continued feedback.</p> <p><a href="https://wg21.link/P1967"><strong>P1967R14 “#embed &#8211; a scannable, tooling-friendly binary resource inclusion mechanism”</strong></a> by <strong>JeanHeyd Meneide</strong> enables “#include for binary data” — a portable way to pull binary data into a program without external tools and build system support. The introduction is clear and crisp:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p><em>“For well over 40 years, people have been trying to plant data into executables for varying reasons. Whether it is to provide a base image with which to flash hardware in a hard reset, icons that get packaged with an application, or scripts that are intrinsically tied to the program at compilation time, there has always been a strong need to couple and ship binary data with an application.</em></p> <p><em>“Neither C nor C++ makes this easy for users to do, resulting in many individuals reaching for utilities such as&nbsp;xxd, writing python scripts, or engaging in highly platform-specific linker calls to set up&nbsp;extern&nbsp;variables pointing at their data. Each of these approaches come with benefits and drawbacks. For example, while working with the linker directly allows injection of very large amounts of data (5 MB and upwards), it does not allow accessing that data at any other point except runtime. Conversely, doing all of these things portably across systems and additionally maintaining the dependencies of all these resources and files in build systems both like and unlike&nbsp;make&nbsp;is a tedious task.</em></p> <p><em>“Thusly, we propose a new preprocessor directive whose sole purpose is to be&nbsp;#include, but for binary data:&nbsp;#embed.”</em></p> </blockquote> <p>Note that this feature has already been approved for inclusion in the next revision of C as well. See the proposal paper, especially sections 3.3 and 4.1, for more delightful background and design alternative discussion.</p> <p><a href="https://wg21.link/P2841"><strong>P2841R7 “Concept and variable-template template-parameters”</strong></a> by <strong>Corentin Jabot, Gašper Ažman, James Touton</strong>, and <strong>Hubert Tong</strong> adds the ability of passing concepts and variable templates as template parameters. Thank you, Corentin and your coauthors!</p> <h2 class="wp-block-heading">More things adopted for C++26: Standard library changes/features</h2> <p>In addition to fixing a list of defect reports, the standard library adopted 15 papers, including the following…</p> <p><a href="https://wg21.link/p0447"><strong>P0447R28 “Introduction of std::hive to the standard library”</strong></a> by <strong>Matthew Bentley</strong> is a major library addition that formalizes a widely-used high-performance data structure. From the paper’s overview:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p><em>“Hive is a formalisation, extension and optimization of what is typically known as a &#8216;bucket array&#8217; or &#8216;object pool&#8217; container in game programming circles. Thanks to all the people who&#8217;ve come forward in support of the paper over the years, I know that similar structures exist in various incarnations across many fields including high-performance computing, high performance trading, 3D simulation, physics simulation, robotics, server/client application and particle simulation fields (see&nbsp;</em><a href="https://groups.google.com/a/isocpp.org/g/sg14/c/1iWHyVnsLBQ/m/tEJfuJMvCQAJ"><em>this google groups discussion</em></a><em>, the&nbsp;</em><a href="https://isocpp.org/files/papers/P3011R0.pdf"><em>hive supporting paper #1</em></a><em>&nbsp;and&nbsp;</em><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0447r28.html#external_prior_art"><em>appendix links to prior art</em></a><em>).</em></p> <p><em>“The concept of a bucket array is: you have multiple memory blocks of elements, and a boolean token for each element which denotes whether or not that element is &#8216;active&#8217; or &#8216;erased&#8217; &#8211; commonly known as a skipfield. If it is &#8216;erased&#8217;, it is skipped over during iteration. When all elements in a block are erased, the block is removed, so that iteration does not lose performance by having to skip empty blocks. If an insertion occurs when all the blocks are full, a new memory block is allocated.</em></p> <p><em>“The advantages of this structure are as follows: because a skipfield is used, no reallocation of elements is necessary upon erasure. Because the structure uses multiple memory blocks, insertions to a full container also do not trigger reallocations. This means that element memory locations stay stable and iterators stay valid regardless of erasure/insertion. This is highly desirable, for example,&nbsp;</em><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0447r28.html#sg14gameengine"><em>in game programming</em></a><em>&nbsp;because there are usually multiple elements in different containers which need to reference each other during gameplay, and elements are being inserted or erased in real time. The only non-associative standard library container which also has this feature is std::list, but it is undesirable for performance and memory-usage reasons. This does not stop it being used in&nbsp;</em><a href="https://isocpp.org/files/papers/P3012R0.pdf"><em>many open-source projects</em></a><em>&nbsp;due to this feature and its splice operations.</em></p> <p><em>“Problematic aspects of a typical bucket array are that they tend to have a fixed memory block size, tend to not re-use memory locations from erased elements, and utilize a boolean skipfield. The fixed block size (as opposed to block sizes with a growth factor) and lack of erased-element re-use leads to far more allocations/deallocations than is necessary, and creates memory waste when memory blocks have many erased elements but are not entirely empty. Given that allocation is a costly operation in most operating systems, this becomes important in performance-critical environments. The boolean skipfield makes iteration time complexity at worst O(n) in&nbsp;capacity(), as there is no way of knowing ahead of time how many erased elements occur between any two non-erased elements. This can create variable latency during iteration. It also requires branching code for each skipfield node, which may cause performance issues on processors with deep pipelines and poor branch-prediction failure performance.</em></p> <p><em>“A hive uses a non-boolean method for skipping erased elements, which allows for more-predictable iteration performance than a bucket array and O(1) iteration time complexity; the latter of which means it meets the C++ standard requirements for iterators, which a boolean method doesn&#8217;t. It has an (optional &#8211; on by default) growth factor for memory blocks and reuses erased element locations upon insertion, which leads to fewer allocations/reallocations. Because it reuses erased element memory space, the exact location of insertion is undefined. Insertion is therefore considered unordered, but the container is sortable. Lastly, because there is no way of predicting in advance where erasures (&#8216;skips&#8217;) may occur between non-erased elements, an O(1) time complexity [ ] operator is not possible and thereby the container is bidirectional but not random-access.”</em></p> </blockquote> <p>Continuing the “making more things constexpr (and consteval)” drumbeat that allows more and more of the full C++ language and standard library be usable in constexpr code, we approved a set of constexpr extensions:</p> <ul class="wp-block-list"> <li><a href="https://wg21.link/P3372"><strong>P3372R3 “constexpr containers and adaptors”</strong></a> by <strong>Hana Dusíková</strong> makes all containers and adapters constexpr (except for the new std::hive, above).</li> <li><a href="https://wg21.link/P3378"><strong>P3378R2 “constexpr exception types”</strong></a> by <strong>Hana Dusíková</strong> makes all exception types used with constexpr code be constexpr too.</li> </ul> <p>Thanks, Hana! These are just the latest of a continued stream of Hana’s papers for constexpr-ing the C++ world; much appreciated — děkuju and arigato!</p> <p>You may recall that at our last meeting we merged <a href="https://wg21.link/p1928"><strong>std::simd by</strong> <strong>Matthias Kretz</strong></a> for high-throughput parallel/vector programming into draft C++26. On Saturday we approved a set of further extensions and refinements, including:</p> <ul class="wp-block-list"> <li><a href="https://wg21.link/P3441"><strong>P3441R2 “Rename simd_split to simd_chunk”</strong></a> by <strong>Daniel Towner</strong> and <strong>Ruslan Arutyunyan</strong> not only does what it says on the tin, but also adds new convenience overloads.</li> <li><a href="https://wg21.link/P2663"><strong>P2663R7 “Interleaved complex values support in std::simd”</strong></a> by <strong>Daniel Towner</strong> and <strong>Ruslan Arutyunyan</strong> adds interleaved complex values support.</li> <li><a href="https://wg21.link/P2933"><strong>P2933R4 “Extend &lt;bit&gt; header function with overloads for std::simd”</strong></a> by (you guessed it!) <strong>Daniel Towner</strong> and <strong>Ruslan Arutyunyan</strong>.</li> </ul> <p>Not to be outdone, <a href="https://wg21.link/P2976"><strong>P2976R1 “Freestanding library: algorithm, numeric, and random”</strong></a> by <strong>Ben Craig</strong> continues Ben’s march toward making a huge amount of C++ available on freestanding implementations. Thanks, Ben!</p> <p>Last but not least, <a href="https://wg21.link/p3019"><strong>P3019R14 “indirect and polymorphic: Vocabulary types for composite class design”</strong></a> by <strong>Jonathan Coe, Antony Peacock, </strong>and<strong> Sean Parent</strong> adds value-semantic types for polymorphic objects to the standard library. This makes polymorphic types much easier to treat as values in value-like algorithms and use cases. Thanks very much, Jonathan and Antony and Sean!</p> <h2 class="wp-block-heading">What’s next</h2> <p>Thank you to all the experts who worked all week in all the subgroups to achieve so much this week!</p> <p>Our next meeting will be this June in <a href="https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4991.pdf"><strong>Sofia, Bulgaria</strong></a> hosted by<strong> Chaos Group</strong> and <strong>C++ Alliance</strong>.</p> <p>Thank you again to the over 200 experts who attended on-site and on-line at this week’s meeting, and the many more who participate in standardization through their national bodies!</p> <p>But we’re not slowing down… in case you think C++“26” sounds very far away, it sure isn’t… we’re only one meeting away before the C++26 freeze in June, and even before that compilers are already aggressively implementing C++26, with GCC and Clang having already implemented about two-thirds of C++26’s language features adopted so far! C++ is a living language and moving fast. Thank you again to everyone reading this for your interest and support for C++ and its standardization.</p> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2025/02/17/trip-report-february-2025-iso-c-standards-meeting-hagenberg-austria/" rel="bookmark"><time class="entry-date published" datetime="2025-02-17T23:01:15-08:00">2025-02-17</time><time class="updated" datetime="2025-02-19T13:29:38-08:00">2025-02-19</time></a> </span> <span class="word-count">14 Minutes</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5837" class="post-5837 post type-post status-publish format-standard hentry category-c"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2025/01/16/codedive-2024-interview-video-posted/" rel="bookmark">code::dive 2024 interview video&nbsp;posted</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>After my code::dive talk in November, the organizers also recorded an extra 9-minute interview that covered these questions:</p> <ul class="wp-block-list"> <li>What role do you think AI will play in shaping programming languages?</li> <li>Do you have any rituals or routines before going on stage?</li> <li>What do you find most exciting about C++?</li> <li>What advice would you give to the code::dive community?</li> </ul> <p>Here it is&#8230;</p> <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"> <div class="embed-youtube"><iframe title="code::dive 2024 Interview - Herb Sutter" width="1100" height="619" src="https://www.youtube.com/embed/tqAcJZCUbxc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div> </div></figure> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2025/01/16/codedive-2024-interview-video-posted/" rel="bookmark"><time class="entry-date published updated" datetime="2025-01-16T21:08:46-08:00">2025-01-16</time></a> </span> <span class="word-count">1 Minute</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5822" class="post-5822 post type-post status-publish format-standard hentry category-c tag-ai tag-c tag-cyber-security tag-cybersecurity tag-infrastructure tag-safety tag-security tag-technology"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2025/01/16/new-u-s-executive-order-on-cybersecurity/" rel="bookmark">New U.S. executive order on&nbsp;cybersecurity</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>The Biden administration just issued <a href="https://www.whitehouse.gov/briefing-room/presidential-actions/2025/01/16/executive-order-on-strengthening-and-promoting-innovation-in-the-nations-cybersecurity/">another executive order (EO) on hardening U.S. cybersecurity</a>. This is all great stuff. (*) (**)</p> <p><em><strong>A lot</strong> </em>of this EO is repeating the same things I urged in my essay nearly a year ago, <a href="https://herbsutter.com/2024/03/11/safety-in-context/">&#8220;C++ safety &#8212; in context&#8221;</a>&#8230; here&#8217;s a cut-and-paste of my &#8220;Call(s) to action&#8221; conclusion section I published back then, and I think you&#8217;ll see a heavy overlap with this week&#8217;s new EO&#8230;</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <h2 class="wp-block-heading" id="call-to-action">Call(s) to action</h2> <p>As an industry generally, we must make a major improvement in programming language memory safety — and we will.</p> <p>In C++ specifically, we should first target the four key safety categories that are our perennial empirical attack points (type, bounds, initialization, and lifetime safety), and drive vulnerabilities in these four areas down to the noise for new/updated C++ code — and we can.</p> <p>But we must also recognize that programming language safety is not a silver bullet to achieve cybersecurity and software safety. It’s one battle (not even the biggest) in a long war: Whenever we harden one part of our systems and make that more expensive to attack, attackers always switch to the next slowest animal in the herd. Many of 2023’s worst data breaches did not involve malware, but were caused by inadequately stored credentials (e.g.,&nbsp;<a href="https://blog.aquasec.com/the-ticking-supply-chain-attack-bomb-of-exposed-kubernetes-secrets">Kubernetes Secrets</a>&nbsp;on public GitHub repos), misconfigured servers (e.g.,&nbsp;<a href="https://cybernews.com/security/darkbeam-data-leak/#google_vignette">DarkBeam</a>,&nbsp;<a href="https://cybernews.com/security/kidsecurity-parental-control-data-leak/">Kid Security</a>), lack of testing, supply chain vulnerabilities, social engineering, and other problems that are independent of programming languages.&nbsp;<a href="https://www.apple.com/newsroom/pdfs/The-Continued-Threat-to-Personal-Data-Key-Factors-Behind-the-2023-Increase.pdf">Apple’s white paper</a>&nbsp;about 2023’s rise in cybercrime emphasizes improving the handling, not of program code, but of the data: “it’s imperative that organizations consider limiting the amount of personal data they store in readable format while making a greater effort to protect the sensitive consumer data that they do store [including by using] end-to-end [E2E] encryption.”</p> <p>No matter what programming language we use, security hygiene is essential:</p> <ul class="wp-block-list"> <li><strong>Do</strong>&nbsp;use your language’s static analyzers and sanitizers. Never pretend using static analyzers and sanitizers is unnecessary “because I’m using a safe language.” If you’re using C++, Go, or Rust, then use those languages’ supported analyzers and sanitizers. If you’re a manager, don’t allow your product to be shipped without using these tools. (Again: This doesn’t mean running all sanitizers all the time; some sanitizers conflict and so can’t be used at the same time, some are expensive and so should be used periodically, and some should be run only in testing and never in production including because their presence can create new security vulnerabilities.)</li> <li><strong>Do</strong>&nbsp;keep all your tools updated. Regular patching is not just for iOS and Windows, but also for your compilers, libraries, and IDEs.</li> <li><strong>Do</strong>&nbsp;secure your software supply chain.&nbsp;<strong>Do</strong>&nbsp;use package management for library dependencies.&nbsp;<strong>Do</strong>&nbsp;track a software bill of materials for your projects.</li> <li><strong>Don’t</strong>&nbsp;store secrets in code. (Or, for goodness’ sake, on GitHub!)</li> <li><strong>Do</strong>&nbsp;configure your servers correctly, especially public Internet-facing ones. (Turn authentication on! Change the default password!)</li> <li><strong>Do</strong>&nbsp;keep non-public data encrypted, both when at rest (on disk) and when in motion (ideally E2E… and oppose proposed legislation that tries to neuter E2E encryption with ‘backdoors only good guys will use’ because there’s no such thing).</li> <li><strong>Do</strong>&nbsp;keep investing long-term in keeping your threat modeling current, so that you can stay adaptive as your adversaries keep trying different attack methods.</li> </ul> <p>We need to improve software security and software safety across the industry, especially by improving programming language safety in C and C++, and in C++ a 98% improvement in the four most common problem areas is achievable in the medium term. But if we focus on programming language safety alone, we may find ourselves fighting yesterday’s war and missing larger past and future security dangers that affect software written in any language.</p> <p>Sadly, there are too many bad actors. For the foreseeable future, our software and data will continue to be under attack, written in any language and stored anywhere. But we can defend our programs and systems, and we will.</p> </blockquote> <hr class="wp-block-separator has-alpha-channel-opacity" /> <p>(*) My main disappointment is that some of the provisions have deadlines that are too far away. Specifically: Why would it take until 2030 to migrate to TLS 1.3? It&#8217;s not just more secure, it&#8217;s also faster and has been published for seven years already&#8230; maybe I&#8217;m just not aware enough of TLS 1.3 adoptability issues though, as I&#8217;m not a TLS expert.</p> <p>(**) Here in the United States, we&#8217;ll have to see whether the incoming administration will continue this EO, or amend/replace/countermand it. In the United States, that&#8217;s a drawback of using an EO compared to passing an actual law with Congressional approval&#8230; an EO is &#8220;quick&#8221; because the President can issue it without getting legislative approval (for things that are in the Presidential remit), but for the same reason an EO also isn&#8217;t &#8220;durable&#8221; or guaranteed to outlive its administration. Because the next President can just order something different, an EO&#8217;s default shelf life is just 1-4 years.</p> <p>So far, all the major U.S. cybersecurity EOs that could affect C++ have been issued since 2021, which means so far they have all come from one President&#8230; and so we&#8217;re all going to learn a lot this year, one way or another, about their permanence. (In both the U.S. and the E.U., actual laws are also in progress to shift software liability from consumer to software producers, and <em>those </em>will have real teeth. But here we&#8217;re talking about the U.S. EOs from 2021 to date.)</p> <p>That said, what I see in these EOs is common sense pragmatism that&#8217;s forcing the software industry to eat our vegetables, so I&#8217;m cautiously optimistic that we&#8217;ll continue to maintain something like these EOs and build on them further as we continue to work hard to secure the infrastructure that our comfortable free lifestyle (and, possibly someday, our lives) depends on. This isn&#8217;t about whether we love a given programming language, it&#8217;s about how we can achieve the greatest hardening at the greatest possible scale for our civilization&#8217;s infrastructure, and for those of us whose remit includes the C++ language that means doing everything we can to harden as much of the existing C and C++ code out there as possible &#8212; all the programmers in the world can only write so much new/rewritten code every year, and for us in C++ by far the maximum contribution we can make to overall security issues related to programming languages (i.e., the subset of security issues that fall into our remit) is to find ways to improve existing C and C++ code with no manual source code changes &#8212; that won&#8217;t always be possible, but where it&#8217;s possible it will maximize our effectiveness in improving security at enormous scale. <a href="https://youtu.be/nXcswVW0-Wk?si=CTjWhcRVPfWb2UZk&amp;t=3473">See also this 2-minute answer I gave</a> in post-talk Q&amp;A in Poland two months ago.</p> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="comments-link"><a href="https://herbsutter.com/2025/01/16/new-u-s-executive-order-on-cybersecurity/#comments">2 Comments</a></span><!-- .comments-link --> <span class="published-on"> <a href="https://herbsutter.com/2025/01/16/new-u-s-executive-order-on-cybersecurity/" rel="bookmark"><time class="entry-date published" datetime="2025-01-16T20:51:56-08:00">2025-01-16</time><time class="updated" datetime="2025-01-16T21:12:22-08:00">2025-01-16</time></a> </span> <span class="word-count">5 Minutes</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5817" class="post-5817 post type-post status-publish format-standard hentry category-c tag-c tag-reflection tag-safety tag-security tag-speaking tag-waterloo"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2025/01/07/speaking-at-university-of-waterloo-on-january-15/" rel="bookmark">Speaking at University of Waterloo on January&nbsp;15</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>Next week, on January 15, I&#8217;ll be speaking <a href="https://uwaterloo.ca/women-in-computer-science/tech-talk-next-decade-c-herb-sutter-and-fireside-chat"><strong>at the University of Waterloo</strong></a>, my alma mater. There&#8217;ll be a tech talk on key developments in C++ and why I think the language&#8217;s future over the next decade will be exciting, with lots of time allocated to a &#8220;fireside chat / interview&#8221; session for Q&amp;A. The session is hosted by Waterloo&#8217;s Women in Computer Science (WiCS) group, and dinner and swag by <a href="https://www.citadelsecurities.com/">Citadel Securities</a>, where I work.</p> <p>This talk is open to Waterloo students only (<strong>registration required</strong>). The organizers are arranging an option to watch remotely for the half of you who are away from campus on your co-op work terms right now &#8212; I vividly remember those! Co-op is a great experience.</p> <p>I look forward to meeting many current students next week, and comparing notes about co-op work terms, pink ties (I still have mine) and MathSoc and C&amp;D food (if Math is your faculty), WATSFIC, and &#8220;Water<sup>∞</sup>loo&#8221; jokes (I realize doing this in January is tempting the weather/travel gods, but I do know how to drive in snow&#8230;).</p> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2025/01/07/speaking-at-university-of-waterloo-on-january-15/" rel="bookmark"><time class="entry-date published" datetime="2025-01-07T10:55:07-08:00">2025-01-07</time><time class="updated" datetime="2025-01-07T10:56:45-08:00">2025-01-07</time></a> </span> <span class="word-count">1 Minute</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5809" class="post-5809 post type-post status-publish format-standard hentry category-c"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2025/01/02/speaking-at-new-york-c-meetup-on-january-13/" rel="bookmark">Speaking at New York C++ meetup on January&nbsp;13</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>Less than two weeks from now, on January 13 I&#8217;ll be speaking at <a href="https://www.meetup.com/new-york-c-c-meetup-group/events/305184499/?eventOrigin=group_upcoming_events&amp;_gl=1*1pny1yq*_up*MQ..*_ga*MTY0NjIyNzAwMC4xNzM1ODU4ODMx*_ga_NP82XMKW0P*MTczNTg1ODgzMC4xLjAuMTczNTg1ODgzMC4wLjAuMA.."><strong>the New York C++ meetup in Midtown East</strong></a> (Clinton Hall at 230 E 51st Street). I&#8217;ll be giving a condensed update of my recent &#8220;Peering forward: C++&#8217;s next decade&#8221; talk, so that there&#8217;ll be plenty of time for Q&amp;A &#8212; please have your questions ready about all the cool things happening right now in the ISO C++ world.</p> <p>The meetup is sponsored by <a href="https://www.citadelsecurities.com/">Citadel Securities</a>, where I work. Food and drink will be served! Registration is free, but <strong>preregistration RSVP is required</strong> so please use the form at the link about to reserve your spot. A waitlist is available if space runs out.</p> <p>I hope to see many of you there!</p> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2025/01/02/speaking-at-new-york-c-meetup-on-january-13/" rel="bookmark"><time class="entry-date published updated" datetime="2025-01-02T15:17:21-08:00">2025-01-02</time></a> </span> <span class="word-count">1 Minute</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5777" class="post-5777 post type-post status-publish format-standard hentry category-c category-concurrency category-cpp2-cppfront tag-lock-free tag-safety tag-scalable tag-union tag-wait-free"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2025/01/02/my-little-new-years-week-project-and-maybe-one-for-you/" rel="bookmark">My little New Year&#8217;s Week project (and maybe one for&nbsp;you?)</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <div class="wp-block-jetpack-markdown"><p><em>[Updates: Clarified that an intrusive discriminator would be far beyond what most people mean by “C++ ABI break.” Mentioned unique addresses and common initial sequences. Added “unknown” state for passing to opaque functions.]</em></p> <p>Here is my little New Year’s Week project: Trying to write a small library to enable compiler support for automatic raw <code>union</code> member access checking.</p> <h2>The problem, and what’s needed</h2> <p>During 2024, I started thinking: <strong>What would it take to make C/C++ <code>union</code> accesses type-checked?</strong> Obviously, the ideal is to change naked <code>union</code> types to something safe.<strong>(*)</strong> But because it will take time and effort for the world to adopt any solution that requires making source code changes, I wondered how much of the safety we might be able to get, at what overhead cost, just by recompiling existing code in a way that instruments ordinary <code>union</code> objects?</p> <blockquote> <p>Note: I describe this in my C++26 Profiles proposal, <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3081r0.pdf">P3081R0</a> section 3.7. The following experiment is trying to validate/invalidate the hypothesis that this can be done efficiently enough to warrant including in an ISO C++ opt-in type safety profile. Also, I’m sure this has been tried before; if you know of a recent (last 10 years?) similar attempt that measured its results, please share it in the comments.</p> </blockquote> <p>What do we need? Obviously, an extra discriminator field to track the currently active member of each C/C++ <code>union</code> object. But we can’t just add a discriminator field intrusively inside each C/C++ <code>union</code> object, because that would change the size and layout of the object and be a massive link/ABI incompatibility even with C compilers and C code on the same platform which would all need to be identically updated at the same time, and it would break most OSes whose link compatibility (existing apps, device drivers, …) rely on C ABIs and APIs and use unions in stable interfaces; breaking that is much more than people usually mean by “C++ taking an ABI break” which is more about evolving C++ standard library types.</p> <p>So we have to store it… extrinsically? … as-if in a global internally-synchronized <code>map&lt;void* /*union obj address*/, uintNN_t /*discriminator*/&gt;</code>…? But that sounds stupid scary: global thread safety lions, data locality tigers, and even some branches bears, O my! Could such extrinsic storage and additional checking possibly be efficient enough?</p> <h2>My little experiment</h2> <p>I didn’t know, so earlier this year I wrote some code to find out, and this week I cleaned it up and it’s now posted here:</p> <ul> <li><a href="https://github.com/hsutter/cppfront/tree/main/experimental"><strong><code>https://github.com/hsutter/cppfront/tree/main/experimental</code></strong></a></li> </ul> <p><a href="https://github.com/hsutter/cppfront/blob/main/experimental/extrinsic_storage.h#L83-L102">The workhorse is <code>extrinsic_storage&lt;Data&gt;</code></a>, a fast and scalable lock-free data structure to nonintrusively store additional <code>Data</code> for each pointer key. It’s wait-free for nearly all operations (not just lock-free!), and I’ve never written <code>memory_order_relaxed</code> this often in my life. It’s designed to be cache- and prefetcher-friendly, such as using SOA to store keys separately so that default hash buckets contain 4 contiguous cache lines of keys. Here I use it for union discriminators, but it’s a general tool that could be considered for any situation where a type needs to store additional data members but can’t store them internally.</p> <h2>If you’re looking for a little New Year’s experiment…</h2> <p>If you’re looking for a little project over the next few days to start off the year, may I suggest one of these:</p> <ul> <li> <p><strong>Little Project Suggestion #1:</strong> Find a bug or improvement in my little lock-free data structure! I’d be happy to learn how to make it better, fire away! Extra points for showing how to fix the bug or make it run better, such as in a PR or your cloned repo.</p> </li> <li> <p><strong>Little Project Suggestion #2:</strong> Minimally extend a C++ compiler (Clang and GCC are open source) as described below, so that every construction/access/destruction of a <code>union</code> type injects a call to my little library’s <code>union_registry&lt;&gt;::</code> functions which will automatically flag type-unsafe accesses. If you try this, please let me know in the comments what happens when you use the modified compiler on some real world source! I’m curious whether you find true positive union violations in the <code>union-violations.log</code> file – of course it will also contain false positives, because real code does sometimes use unions to do type punning on purpose, but you should be able to eliminate batches of those at a time by their similar text in the log file.</p> </li> </ul> <p>To make #2 easier, <a href="https://github.com/hsutter/cppfront/blob/main/experimental/union_test.cpp#L16-L44">here’s a simple API I’ve provided as <code>union_registry&lt;&gt;</code></a>, which wraps the above in a compiler-intgration-targeted API. I’ll paste the comment documentation here:</p> </div> <div class="wp-block-syntaxhighlighter-code "><pre class="brush: cpp; gutter: false; title: ; notranslate" title=""> // For an object U of union type that // has a unique address, when Inject a call to this (zero-based alternative #s) // // U is created initialized on_set_alternative(&amp;U,0) = the first alternative# is active // // U is created uninitialized on_set_alternative(&amp;U,invalid) // // U.A = xxx (alt A is assigned to) on_set_alternative(&amp;U,#A) // // U or U.A is passed to a function by on_set_alternative(&amp;U,unknown) // pointer/reference to non-const // and we don&#039;t know the function // is compiled in this mode // // U.A (alt A is otherwise used) on_get_alternative(&amp;U,#A) // and A is not a common initial // sequence // // U is destroyed / goes out of scope on_destroy(&amp;U) // // That&#039;s it. Here&#039;s an example: // { // union Test { int a; double b; }; // Test t = {42}; union_registry&lt;&gt;::on_set_alternative(&amp;u,0); // std::cout &lt;&lt; t.a; union_registry&lt;&gt;::on_get_alternative(&amp;u,0); // t.b = 3.14159; union_registry&lt;&gt;::on_set_alternative(&amp;u,1); // std::cout &lt;&lt; t.b; union_registry&lt;&gt;::on_get_alternative(&amp;u,1); // } union_registry&lt;&gt;::on_destroy(&amp;u); // // For all unions with up to 254 alternatives, use union_registry&lt;&gt; // For all unions with between 255 and 16k-2 alternatives, use union_registry&lt;uint16_t&gt; // If you find a union with &gt;16k-2 alternatives, email me the story and use union_registry&lt;uint32_t&gt; </pre></div> <div class="wp-block-jetpack-markdown"><h2>Rough initial microbenchmark performance</h2> <p>My test environment:</p> <ul> <li>CPU: 2.60 GHz i9-13900H (14 physical cores, 20 logical cores)</li> <li>OSes: Windows 11, running MSVC natively and GCC and Clang via Fedora in WSL2</li> </ul> <p>My <a href="https://github.com/hsutter/cppfront/blob/main/experimental/union_test.cpp#L66">test harness provided here</a>:</p> <ul> <li>14 test runs: Each successively uses { 1, 2, 4, 8, 16 32, 64, 1, 2, 4, 8, 16, 32, 64 } threads <ul> <li>Each run tests 1 million union objects, 10,000 at a time, 10 operations on each union; the test type is <code>union Union { char alt0; int alt1; long double alt2; };</code></li> <li>Each run injects 1 deliberate “type error” failure to trigger detection, which results in a line of text written to <code>union-violations.log</code> that records the bad union access including the source line that committed it (so there’s a little file I/O here too)</li> </ul> </li> <li>Totals: <ul> <li>14 million union objects created/destroyed</li> <li>140 million union object accesses (10 per object, includes construct/set/get/destroy)</li> </ul> </li> </ul> <p>On my machine, here is total the run-time overhead (“total checked” time using this checking, minus “total raw” time using only ordinary raw union access), for a typical run of the whole 140M unit accesses:</p> <table> <thead> <tr> <th>Compiler</th> <th>total raw (ms)</th> <th>total checked (ms)</th> <th>total overhead (ms)</th> <th>Notes</th> </tr> </thead> <tbody> <tr> <td>MSVC 19.40 <code>-O2</code></td> <td>~190</td> <td>~1020</td> <td>~830</td> <td>Compared to <code>-O2</code>, <code>-Ox</code> checked was the same or very slightly slower, and <code>-Os</code> checked was 3x slower</td> </tr> <tr> <td>GCC 14 <code>-O3</code></td> <td>~170</td> <td>~800</td> <td>~630</td> <td>Compared to <code>-O3</code>, <code>-O2</code> overall was only slightly slower</td> </tr> <tr> <td>Clang 18 <code>-O3</code></td> <td>~170</td> <td>~510</td> <td>~340</td> <td>Compared to <code>-O3</code>, <code>-O2</code> checked was about 40% slower</td> </tr> </tbody> </table> <p>Dividing that by 140 million accesses, the per-access overhead is:</p> <table> <thead> <tr> <th>Compiler</th> <th>total overhead (ns) / total accesses</th> <th>average overhead / access (ns)</th> </tr> </thead> <tbody> <tr> <td>MSVC</td> <td>830M ns / 140M accesses</td> <td>5.9 ns / access</td> </tr> <tr> <td>GCC (midpoint)</td> <td>630M ns / 140M accesses</td> <td>4.5 ns / access</td> </tr> <tr> <td>Clang</td> <td>340M ns / 140M accesses</td> <td>2.4 ns / access</td> </tr> </tbody> </table> <p>Finally, recall we’re running on a 2.6 GHhz processor = 2.6 clock cycles per ns, so in CPU clock cycles the per-access overhead is:</p> <table> <thead> <tr> <th>Compiler</th> <th>average overhead / access (cycles)</th> </tr> </thead> <tbody> <tr> <td>MSVC</td> <td>15 cycles / access</td> </tr> <tr> <td>GCC</td> <td>11.7 cycles / access</td> </tr> <tr> <td>Clang</td> <td>6.2 cycles / access</td> </tr> </tbody> </table> <p>This… seems too good to be true. I may well be making a silly error (or several) but I’ll post anyway so we can all have fun correcting them! Maybe there’s a silly bug in my code, or I moved a decimal point, or I converted units wrong, but I invite everyone to have fun pointing out the flaw(s) in my New Year’s Day code and/or math – please fire away in the comments.</p> <p>Elaborating on why this seems too good to be true: Recall that one “access” means to check the global hash table to create/find/destroy the union object’s discriminator tag (using <code>std::atomic</code>s liberally) and then also set or check either the tag (if setting or using one of the union’s members) and/or the key (if constructing or destroying the union object). But even a single L2 cache access is usually around 10-14 cycles! This would mean this microbenchmark is hitting L1 cache almost always, even while iterating over 10,000 active unions at a time, often with more hot threads than there are physical or logical cores pounding on the same global data structure, and occasionally doing a little file I/O to report violations.</p> <p>Even if I didn’t make any coding/calculation errors, one explanation is that this microbenchmark has great L1 cache locality because the program isn’t doing any other work, and in a real whole program it won’t get to run hot in L1 that often – that’s a valid possibility and concern, and that’s exactly why I’m suggesting Little Project #2, above, if anyone would like to give that little project a try.</p> <p>In any event, thank you all for all your interest and support for C++ and its evolution and standardization, and I wish all of you and your families a happier and more peaceful 2025!</p> <hr> <p><strong>(*)</strong> Today we have <code>std::variant</code> which safely throws an exception if you access the wrong alternative, but <code>variant</code> isn’t as easy to use as <code>union</code> today, and not as type-safe in some ways. For example, the <code>variant</code> members are anonymous so you have to access them by index or by type; and every <code>variant&lt;int,string&gt;</code> in the program is also anonymous == the same type, so we can’t distinguish/overload unrelated variants that happen to have similar alternatives. I think the ideal answer – and it looks like ISO C++ is just 1-2 years from being powerful enough to do this! – will be something like the <a href="https://github.com/hsutter/cppfront/blob/main/source/reflect.h2#L1451">safe <code>union</code> metaclass using reflection</a> that I’ve implemented in cppfront, which is as easy to use as <code>union</code> and as safe as <code>variant</code> – see <a href="https://youtu.be/8U3hl8XMm8c?si=fWAITgfVlEIVtjke&amp;t=2356">my CppCon 2023 keynote starting at 39:16</a> for a 4-minute discussion of <code>union</code> vs. <code>variant</code> vs a safe <code>union</code> metafunction that uses reflection.</p> </div> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a>, <a href="https://herbsutter.com/category/concurrency/" rel="category tag">Concurrency</a>, <a href="https://herbsutter.com/category/cpp2-cppfront/" rel="category tag">Cpp2, cppfront</a> </span><!-- .cat-links --> <span class="comments-link"><a href="https://herbsutter.com/2025/01/02/my-little-new-years-week-project-and-maybe-one-for-you/#comments">16 Comments</a></span><!-- .comments-link --> <span class="published-on"> <a href="https://herbsutter.com/2025/01/02/my-little-new-years-week-project-and-maybe-one-for-you/" rel="bookmark"><time class="entry-date published" datetime="2025-01-02T00:30:40-08:00">2025-01-02</time><time class="updated" datetime="2025-01-02T22:20:50-08:00">2025-01-02</time></a> </span> <span class="word-count">7 Minutes</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5757" class="post-5757 post type-post status-publish format-standard hentry category-c tag-c tag-reflection tag-safety tag-security"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2024/12/11/my-codedive-talk-video-is-available-new-qa/" rel="bookmark">My code::dive talk video is available: New&nbsp;Q&amp;A</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>Two weeks ago, Bjarne and I and lots of ISO committee members had a blast at the <strong>code::dive C++ conference</strong> held on November 25, just two days after the end of <a href="https://herbsutter.com/2024/11/24/wg21-2024-11/">the Wrocław ISO C++ meeting</a>. Thanks again to Nokia for hosting the ISO meeting, and for inviting us all to speak at their conference! My talk was an updated-and-shortened version of my CppCon keynote (which I also gave at Meeting C++; I&#8217;ll post a link to that video too once it&#8217;s posted):</p> <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"> <div class="embed-youtube"><iframe title="Herb Sutter - Peering forward C++’s next decade" width="1100" height="619" src="https://www.youtube.com/embed/nXcswVW0-Wk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div> </div></figure> <p>If you already saw the CppCon talk, you can skip to these &#8220;new parts at the end&#8221; where the Q&amp;A got into very interesting topics:</p> <ul class="wp-block-list"> <li><a href="https://youtu.be/nXcswVW0-Wk?si=zA39y7f4jILGNrhr&amp;t=2688">44:48 Summary: Why 2024 has turned into a pivotal year for C++</a> (* transcript at bottom of this post)</li> <li><a href="https://youtu.be/nXcswVW0-Wk?si=McdQG8ac48DJupDA&amp;t=2820">47:00 Erroneous behavior in C++: What&#8217;s the run-time cost and can we opt out when needed?</a></li> <li><a href="https://youtu.be/nXcswVW0-Wk?si=PWQjppd0Vr8HA1MS&amp;t=2880">48:00 My new paper proposing taking safety-related undefined behavior and turning it all off by default: I have a dream</a></li> <li><a href="https://youtu.be/nXcswVW0-Wk?si=0dLtOzcwi00WLdcR&amp;t=3060">51:00 This new ^^ reflection operator: Will it litter our code?</a></li> <li><a href="https://youtu.be/nXcswVW0-Wk?si=phwY-CC5EUoDo3pV&amp;t=3254">54:14 What do you think of evolving/extending C++ vs. directions like cppfront vs. C++ alternatives like Carbon?</a></li> </ul> <p>Finally, I&#8217;m glad I got a chance to give this last answer to cap things off, and thanks again for the audience question that led to it: </p> <ul class="wp-block-list"> <li><a href="https://youtu.be/nXcswVW0-Wk?si=CRmzhnv_gLu_ISJy&amp;t=3475">57:55 Why I think the most impactful way I can contribute toward improving our society is through improving existing C++ code</a> (** transcript at bottom of this post)</li> </ul> <p>That morning, on our route while traveling from the hotel to the conference site, at one point we noticed that up ahead there was a long line of people all down the length of a block and wrapped around the corner. It took me a few beats to realize that was where we were going, and those were the people still waiting to get in to the conference (at that time there were already over 1,000 people inside the building). Here&#8217;s one photo that appeared in the local news showing part of the queue:</p> <figure class="wp-block-image size-large"><img src="https://www.wroclaw.pl/cdn-cgi/image/w=1200,h=600,fit=crop,f=avif/beta2/files/news/690515/main/konferencja.jpg" alt="" /></figure> <p>In all, I&#8217;m told 1,800 people attended on-site, and 8,000 attended online. Thank you again to our Nokia hosts for hosting the ISO C++ meeting and inviting us to code::dive, and thank you to all the C++ developers (and, I&#8217;m sure, a few C++-curious) who came from Poland and beyond to spend a day together talking about our favorite programming language!</p> <hr class="wp-block-separator has-alpha-channel-opacity" /> <p class="has-text-align-left">(*) Here&#8217;s a transcript of what I said in that closing summary:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>&#8230; Reflection and safety improvements as what I see are the two big drivers of our next decade of C++.</p> <p>So I&#8217;m excited about C++. I really think that this was a turning point year, because we&#8217;ve been talking about safety for a decade, the Core Guidelines are a decade old, we&#8217;ve been talking about reflection for 20 years in the C++ committee — but this is the year that it&#8217;s starting to get real. This is the year we put erroneous behavior [in] and eliminated uninitialized locals in the standard, this is the year that we design-approved reflection for the standard — both for C++26 and hopefully they&#8217;ll both get in. We are starting to finally see these proposals land, and this is going to create a beautiful new decade, open up a new fresh era of C++. Bjarne [&#8230;.] when C++11 came out, he said, you know, there&#8217;s been so many usability improvements here that C++11, even though it&#8217;s fully compatible with C++98, it feels like a new language. I think we&#8217;re about to do that again, and to make C++26 feel like a new language. And then just as we built on C++11 and finished it with C++14, 17, 20, the same thing with this generation. That&#8217;s how I view it. I&#8217;m very hopeful for a bright future for C++. Our language and our community continues to grow, and it&#8217;s great to see us addressing the problems we most need to address, so we have an answer for safety, we have an answer for simpler build systems and reducing the number of side languages to make C++ work in practice. And I&#8217;m looking forward to the ride for the next decade and more.</p> </blockquote> <p>And at the end of the Q&amp;A, the final part of my answer about why I&#8217;m focused on C++ rather than other efforts:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Why am I spending all this time in ISO C++? Not just because I&#8217;m some C++-lover on a fanatical level — you may accuse me of that too — but it&#8217;s just because I want to have an impact. I&#8217;m a user of this world&#8217;s society and civilization. I use this world&#8217;s banking system. I rely on this world&#8217;s hospital system. I rely on this world&#8217;s power grid. And darnit I don&#8217;t want that compromised, I want to harden it against attack. And if I put all my energy into some new programming language, I will have some impact, but it&#8217;s going to be much smaller because I can only write so much new code. If I can find a way to just recompile — that&#8217;s why you keep hearing me say that — to just recompile the billions of lines of C++ code that exist today, and make them even 10% safer, and I hope to make them much more than that safer, I will have had an outsized effect on securing our civilization. And I don&#8217;t mean to speak too grandiosely, but look at all the C++ code that needs fixing. If you can find a way to do that, it will have an outsized impact and benefit to society. And that&#8217;s why I think it&#8217;s important, because C++ is important — and not leaving all that code behind, helping that code too as well as new code, I think is super important, and that&#8217;s kind of my motivation.</p> </blockquote> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2024/12/11/my-codedive-talk-video-is-available-new-qa/" rel="bookmark"><time class="entry-date published updated" datetime="2024-12-11T08:26:25-08:00">2024-12-11</time></a> </span> <span class="word-count">4 Minutes</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5692" class="post-5692 post type-post status-publish format-standard hentry category-c"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2024/11/24/wg21-2024-11/" rel="bookmark">Trip report: November 2024 ISO C++ standards meeting (Wrocław,&nbsp;Poland)</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>On Saturday, the ISO C++ committee completed the third-last design meeting of C++26, held in Wrocław, Poland. There are just two meetings left before the C++26 feature freeze in June 2025, and C++26 is on track to be completed two more meetings after that in early 2026. Implementations are closely tracking draft C++26; GCC and Clang already support about two-thirds of C++26 features right now.</p> <p>Our host, <strong>Nokia</strong>, arranged for high-quality facilities for our six-day meeting from Monday through Saturday. We had over 220 attendees, about two-thirds in-person and the others remote via Zoom, formally representing 31 nations. At each meeting we regularly have new attendees who have never attended before, and this time there were 37 new first-time attendees, mostly in-person. To all of them, once again welcome!</p> <p><a href="https://isocpp.org/std/the-committee">The committee</a> currently has 23 active subgroups, 15 of which met in parallel tracks throughout the week. Some groups ran all week, and others ran for a few days or a part of a day, depending on their workloads. We also had two combined informational evening sessions to inform the committee broadly about progress on key topics: one on contracts, the other on relocatability. You can find a brief summary of ISO procedures <a href="https://isocpp.org/std/iso-iec-jtc1-procedures">here</a>.</p> <p>This time, the committee adopted the next set of features for C++26, and made significant progress on other features that are now expected to be complete in time for C+26.</p> <p>In addition to features already approved for C++26 at previous meetings, at this meeting three major features made strong progress:</p> <ul class="wp-block-list"> <li><strong>P2996 Reflection</strong> is in specification wording review aiming for C++26.</li> <li><strong>P2900 Contracts</strong> continues to have a chance of being in C++26 – probably more time was spent on contracts this week in various subgroups than on any other feature.</li> <li><strong>P3081 Safety Profiles</strong> and <strong>P3471R0 Standard library hardening</strong> made progress into the Evolution group and have a chance of being an initial set of profiles for C++26.</li> </ul> <h2 class="wp-block-heading">Adopted for C++26: Core language changes/features</h2> <p>Note: These links are to the most recent public version of each paper. If a paper was tweaked at the meeting before being approved, the link tracks and will automatically find the updated version as soon as it’s uploaded to the public site.</p> <p>In addition to fixing a list of defect reports, the core language adopted 8 papers, including the following…</p> <p><strong><a href="https://wg21.link/p2686">P2686R5 “constexpr structured bindings and references to constexpr variables”</a></strong> by <strong>Corentin Jabot</strong> and <strong>Brian Bi</strong>. The paper itself contains a great explanation, pasting from page 8:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p class="has-text-align-left">You can now declare structured bindings <code>constexpr</code>. Because structured bindings behave like references, <code>constexpr</code> structured bindings are subject to similar restrictions as <code>constexpr</code> references, and supporting this feature required relaxing the previous rule that a <code>constexpr</code> reference must bind to a variable with static storage duration. Now, <code>constexpr</code> references and structured bindings may also bind to a variable with automatic storage duration, but only when that variable has an address that is constant relative to the stack frame in which the reference or structured binding lives.</p> </blockquote> <p>Thanks, Corentin and Brian!<strong><u></u></strong></p> <p><a href="https://wg21.link/p3068"><strong>P3068R6 “Allowing exception throwing in constant evaluation”</strong></a> by <strong>Hana Dusíková</strong> continues the very-welcome and quite-inexorable march toward allowing more and more of C++ to run at compile time. “Compile-time C++, now with exceptions so you can use normal C++ without rewriting your error handling to return codes/<code>std::expected</code>s!” is the nutshell synopsis. Thank you, Hana!</p> <h2 class="wp-block-heading">Adopted for C++26: Standard library changes/features</h2> <p>In addition to fixing a list of defect reports, the standard library adopted 19 papers, including the following…</p> <p><a href="https://wg21.link/p3370"><strong>P3370R1 “Add new library headers from C23”</strong></a> by <strong>Jens Maurer</strong> is an example of how C++ continues trying to align with C. As the paper states: “C23 added the <code>&lt;stdbit.h&gt;</code> and <code>&lt;stdchkint.h&gt;</code> headers. This paper [adds] these headers to C++ to increase the subset of code that compiles with C and C++. […] Type-generic macros and type-generic functions do not exist in C++, but function templates can provide the same call interface. Thus, the use of the former in C is replaced by the latter in C++.” Thank you Jens!</p> <p>(For those who don’t know of Jens, he’s one of the committee’s unsung Energizer Bunnies: He chairs the Core language specification working group all week long at every meeting, he’s the key logistics person who makes every meeting run smoothly from organizing room layouts and A/V to break drinks/snacks, he organizes every meeting’s space allocations for all the subgroups and evening sessions, and after all that he clearly still has time left over to write standard library papers too! We don’t know how he does it all, but the unconfirmed rumor is that there’s a secret clone involved; investigation is still pending.)</p> <p>Because Hana (already mentioned above) can’t stop adding to <code>constexpr</code>, <a href="https://wg21.link/p3309"><strong>P3309R3 “constexpr atomic&lt;T&gt; and atomic_ref&lt;T&gt;”</strong></a> by <strong>Hana Dusíková</strong> does what it says on the tin. If you’re wondering whether this is important (after all, we don’t support threads in <code>constexpr</code> code… yet… and usually <code>atomic&lt;T&gt;</code> is about concurrency), the paper explains:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>This paper […] allows implementing other types (<code>std::shared_ptr&lt;T&gt;</code>, persistent data structures with atomic pointers) and algorithms (thread safe data-processing, like scanning data with atomic counter) with just sprinkling&nbsp;<code>constexpr</code>&nbsp;to their specification.</p> </blockquote> <p>So perhaps a good synopsis would be: “removing the last excuse not to make <code>shared_ptr</code> available in <code>constexpr</code> code!” Thanks, Hana!</p> <p><a href="https://wg21.link/p1928"><strong>P1928R15 “std::simd — merge data-parallel types from the Parallelism TS 2”</strong></a> by <strong>Matthias Kretz</strong> adopts the data-parallel <code>basic_simd</code> types from the TS into C++26 as <code>std::basic_simd</code>. Two notes: (1) The “changes since the TS” section has a “<code>constexpr</code> everything” section, because that’s just how we roll in WG21 these days (cf: Hana’s papers above). (2) Note the “R” revision number, which indicates the 15 revisions of this proposal that were needed to get it to land — thank you for the determined hard work, Matthias, and once again congratulations from us all: When this proposal was adopted, a sustained round of loud applause filled the room!</p> <p>Last but not least, <a href="https://wg21.link/p3325"><strong>P3325R5 “A utility for creating execution environments”</strong></a> by <strong>Eric Niebler</strong> builds on the huge new <code>std::execution</code> concurrency and parallelism library that was adopted at our previous meeting this summer (see my <a href="https://herbsutter.com/2024/07/02/trip-report-summer-iso-c-standards-meeting-st-louis-mo-usa/">summer 2024 trip report</a>) to additionally make it easier to create and merge loci of execution. Definitely read section 4 of the paper for a full description of the motivation and use cases. Thanks very much, Eric!</p> <h2 class="wp-block-heading">Other progress</h2> <p>All subgroups continued progress, more of which will no doubt be covered in other trip reports. Here are a few more highlights…</p> <p>SG1 (Concurrency): Concurrent queues “might” make C++26, and this is one of the most compelling demonstrations of the “sender/receiver” design pattern in the new <code>std::execution</code> that was adopted at our previous meeting. Concurrent queues would also be (finally) the first concurrent data structure in the standard. Also, although SG1 has been trying to fix/specify <code>memory_order_consume</code> since C++11, this has not succeeded, so the feature has now been removed.</p> <p>SG7 (Compile-Time Programming): Made progress on several papers. Perhaps the most visible decision was to decide on a reflection syntax, <code>^^</code>, which apparently some people are lobbying hard to call the “unibrow operator.&#8221;</p> <p>SG15 (Tooling): Progressed work on the Ecosystem IS (International Standard), which achieved the milestone of being approved to be forwarded to the main design subgroups.</p> <p>SG20 (Education): Progressed work on creating C++ teaching guidelines about topics that should be taught in C++ educational settings. Encouraged paper authors and chairs to send papers to SG20 for teachability feedback.</p> <p>SG21 (Contracts): Spent Wednesday in the Core working group (instead of meeting separately) because EWG sent contracts to Core aiming for C++26, so the contracts experts went to Core to help with wording review. Continued work on trying to increase consensus on some design details.</p> <p>SG23 (Safety and Security): Approved several papers to progress, including to reduce undefined behavior in the language and specifically time travel optimizations, and to send an initial set of core safety profiles to EWG aiming for C++26. The proposal <strong><a href="http://wg21.link/p3390">P3390 &#8220;Safe C++&#8221;</a></strong> by <strong>Sean Baxter </strong>was seen and received support as a direction that can be pursued in addition to and complementary with Profiles, where Profiles are useful to define subsets of current C++ and its features and reducing its undefined behaviors to reduce unsafety in current C++, and proposals like Safe C++ can be useful to propose new extensions for an expanded C++ to try to achieve larger/stronger safety guarantees not possible in just a subset/constrained C++. The SG23 vote on which to prioritize was <strong>19:11:6:9 for Profiles:Both:Neutral:SafeC++</strong>.</p> <p>EWG (Language Evolution Working Group) forwarded contracts aiming for C++26, understanding however that there are still a few unresolved contentious design points; the groups are working on increasing consensus between now and the next meeting. Adopted the <code>^^</code> operator for reflection. Pattern matching is still trying to make C++26. Three safety papers progressed: P3081 core safety profiles (see below; for detailed telecon review between meetings and aiming for approval at our next meeting), <strong><a href="http://wg21.link/p3471">P3471R0 &#8220;Standard library hardening&#8221;</a></strong> by <strong>Konstantin Varlamov</strong> and <strong>Louis Dionne</strong> which passed unanimously (no one even neutral!), and <strong><a href="http://wg21.link/p2719">P2719 &#8220;Type-aware allocation and deallocation functions&#8221;</a></strong> by <strong>Louis Dionne</strong> and <strong>Oliver Hunt</strong> which offers safety mitigation building blocks. The group also approved trivial relocatability for C++26.</p> <p>LEWG (Library Evolution Working Group) reviewed 30 papers this week. LEWG is specifically prioritizing its time on these topics as papers are available: relocatability, parallel algorithms, concurrent queues, <code>constexpr</code> containers, safety profiles, and pattern matching.</p> <p>Thank you to all the experts who worked all week in all the subgroups to achieve so much this week!</p> <h2 class="wp-block-heading">What’s next</h2> <p>Our next meeting will be in <a href="https://isocpp.org/files/papers/N4997.pdf"><strong>Hagenberg, Austria</strong></a> hosted by <strong>University of Applied Sciences Upper Austria, RISC Software GmbH, and Softwarepark Hagenberg</strong>.</p> <p>Thank you again to the over 220 experts who attended on-site and on-line at this week’s meeting, and the many more who participate in standardization through their national bodies!</p> <p>C++ is a living language and moving fast. Thank you again to everyone reading this for your interest and support for C++ and its standardization.</p> <hr class="wp-block-separator has-alpha-channel-opacity" /> <hr class="wp-block-separator has-alpha-channel-opacity" /> <hr class="wp-block-separator has-alpha-channel-opacity" /> <h2 class="wp-block-heading">Coda: My papers at this meeting</h2> <p>My papers aren’t what’s most important, but since this is my trip report I should mention my papers.</p> <p>I had eight papers at this meeting, of which seven were seen at the meeting and one will be seen in an upcoming telecon. Here they are in the rough order they were seen…</p> <h3 class="wp-block-heading">P3437R0 “Principles: Reflection and generation of source code”</h3> <p>On Monday, in the SG7 (Compile-Time Programming) subgroup I presented <a href="https://wg21.link/p3437"><strong>P3437R0 “Principles: Reflection and generation of source code.”</strong></a></p> <p>In a nutshell, P3437 advocates for the principle that reflection and generation are primarily for automating reading and writing source code, the way a human programmer would do but so the human doesn’t have to do it by hand. I argue that this view implies that, at least by default:</p> <ul class="wp-block-list"> <li>reflecting a class (or other entity) in <code>consteval</code> compile-time code should be able to see everything a human could know from reading the source code of the class’s definition; and, </li> <li>similarly, generating a class in <code>consteval</code> code should be able to write anything the human programmer could write (including things like adding specializations to <code>std</code>) and have the same language meaning as if the programmer wrote it by hand (including normal name lookup and access control).</li> </ul> <p>Non-default modes might do more or different things, but I argued that “as if the human read/wrote the source code” should be the default semantics and get the “nice” syntax that C++ programmers would naturally expect unless they were doing something special.</p> <p>The group agreed and approved the paper, <strong>15:8:3 in favor:neutral:against</strong>.</p> <h3 class="wp-block-heading">P3439 “Chained comparisons: Safe, correct, efficient”</h3> <p>On Tuesday, I presented <a href="https://wg21.link/p3439"><strong>P3439 “Chained comparisons: Safe, correct, efficient”</strong></a> in the language evolution working group (EWG). This paper proposes that comparison chains like <code>a &lt;= b &lt; c</code> actually work. (I’ve already implemented this in <a href="https://github.com/hsutter/cppfront/">cppfront</a>.) Today, people try to write such code, and the standard says it’s required to compile but do the wrong thing, which is not great, and all major compilers will warn about it but then compile it anyway because they must. Adopting this proposal would fix real bugs, including security bugs, just by recompiling existing code. This change would also make the language simpler, because with this feature we could write <code>a &lt;= b &amp;&amp; b &lt; c</code> as just <code>a &lt;= b &lt; c</code>. And that would also make the language slightly faster, by naturally avoiding multiple evaluation of middle terms like <code>b</code>.</p> <p>This is the only part of my original paper <a href="https://wg21.link/p0515r0">P0515R0 “Consistent comparisons”</a> (aka the operator spaceship <code>&lt;=&gt;</code> paper) that has not yet been adopted into the standard. It was rejected before the pandemic when Barry Revzin and I tried a second time to get it adopted, but I felt it was appropriate to bring it back now because there’s new urgency and new information. A few highlights from the paper:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Today, comparison chains like <code>min &lt;= index_expression &lt; max</code> are valid code that do the wrong thing; for example, <code>0 &lt;= 100 &lt; 10</code> means <code>true &lt; 10</code> which means <code>true</code>, certainly a bug. <mark style="background-color:rgba(0, 0, 0, 0);color:#8c0303" class="has-inline-color">Yet that is exactly a natural bounds check; for indexes, such subscript chains’ current meaning is <strong>always</strong> a potentially exploitable out-of-bounds violation.</mark></p> <p>[<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0893r1.html">P0893R1</a>] reported that code searches performed by Barry Revzin with Nicolas Lesser and Titus Winters found:</p> <ul class="wp-block-list"> <li>Lots of instances of such bugs in the wild: in real-world code “of the&nbsp;<code>assert(0&nbsp;&lt;=&nbsp;ratio&nbsp;&lt;=&nbsp;1.0);</code>&nbsp;variety,” and “in questions on StackOverflow&nbsp;<a href="https://stackoverflow.com/q/8889522/2069064"><sup>[1]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/5939077/2069064"><sup>[2]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/14433884/2069064"><sup>[3]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/46806239/2069064"><sup>[4]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/25965157/2069064"><sup>[5]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/38643022/2069064"><sup>[6]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/45385837/2069064"><sup>[7]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/20989496/2069064"><sup>[8]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/35564553/2069064"><sup>[9]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/42335710/2069064"><sup>[10]</sup></a><sup>&nbsp;</sup><a href="https://stackoverflow.com/q/37470518/2069064"><sup>[11]</sup></a>.”</li> <li>“<strong>A few thousand</strong> instances over just a few code bases” (<strong>emphasis</strong> original) where programmers today write more-brittle and less-efficient long forms such as <code>min &lt;= index_expression &amp;&amp; index_expression &lt; max</code> because they must, but with multiple evaluation of <code>index_expression</code> and with bugs because of having to write the boilerplate and sometimes getting it wrong.</li> </ul> </blockquote> <p>See the paper for more new information that warrants considering this anew.</p> <p>The group voted <strong>30:2:2 in favor:neutral:against</strong> for me to bring this back with standardese wording to the February meeting, and if things go well there it might make C++26.</p> <h3 class="wp-block-heading">Next: Three safety/security proposals for me at this meeting</h3> <p>Although the chained-comparisons proposal had a safety and security aspect, I don’t consider it principally a “safety proposal.” However, I did present three actual safety and security proposals at this meeting, and here they are… (Note: There were other such proposals by others too, not just by me! And I’m excited about them too. These are just <em>my</em> three…)</p> <p>Of the four main language safety categories we have to improve (type, bounds, initialization, and lifetime), the first three are easier and are the focus of <strong>P3436</strong> and <strong>P3081</strong>. Lifetime is the hardest to improve in C++, and requires more effort, in my proposal&#8217;s case writing a static analysis rule engine; but I think major improvement is possible without heavy annotation of existing code, and this is the subject of <strong>P3465</strong> (promoting P1179).</p> <h3 class="wp-block-heading">Safety #1 of 3: P3436R0 “Removing safety-related undefined behavior by default”</h3> <p>On Wednesday morning in SG23 (Safety and Security), I presented <a href="https://wg21.link/p3436"><strong>P3436R0 “Removing safety-related undefined behavior (UB) by default.”</strong></a> This would be a pretty big deal… as I mentioned in the presentation, I firmly believe that most observers of C++, even friendly ones, do not expect us to be able to “do something significant” about UB in C++. UB is after all a fundamental part of C++, right? … Right?</p> <p>My conjecture is “no it isn’t, and the point of this paper is easy to summarize:</p> <ul class="wp-block-list"> <li><strong>C++ already bans undefined behavior in a huge subset of the language: <code>constexpr</code> evaluation.</strong> A lot of people do not realize that, yes, we already did that&#8230; we already snuck <em>a lot</em> of safety into the language while no one was paying particular attention. Those who say UB is endemic throughout C++ have already started to fall behind the times, since we added and then gradually expanded <code>constexpr</code>.</li> <li><strong>Let’s enumerate each such case of UB already prevented in <code>constexpr</code> evaluation, and prevent it in normal execution too:</strong> either always (if it’s cheap and easy, as we just did with uninitialized local variables), or else under a Profile (so any overhead has an easy way to opt-in/opt-out when you do/don’t want the safety).</li> </ul> <p>I think most people don’t expect that C++ could make a major dent in undefined behavior and still be true to C++. But P3436 makes the bold conjecture that maybe we can not only make a dent, but actually eliminate UB in C++ by default when safety Profiles are enabled, by combining (a) that we already do it in <code>constexpr</code> code, with (b) that we plan to have Profiles as a tool to opt in/out of safety modes that require source changes or execution overheads.</p> <p>The group agreed and voted <strong>unanimously 25:3:0 in favor:neutral:against</strong>.</p> <p>Important reality check here: This is the start, not the end&#8230; this doesn’t mean the proposal is done, it means the group said “we like the idea, now go do the hard work of actually listing all the UB cases and how you propose to handle each one and writing up standard specification wording for all that.” Most “encouragement” polls in the committee actually mean “yes please go do more work.” (This takes a lot of getting used to for new participants.)</p> <h3 class="wp-block-heading">Safety #2 of 3: P3465R0 “Pursue P1179 as a Lifetime TS”</h3> <p>On Wednesday after lunch in SG23 (Safety and Security), I made the first-ever presentation in WG21 of the C++ Core Guidelines Lifetime safety static analysis profile, of which I’m the primary designer (with lots of expert help; big thanks again everyone listed in P1179!). This analysis <strong>catches many common lifetime dangling issues</strong> (not just for pointers, but for generalized Pointers including iterators and views), usually with <strong>little or no source annotation</strong>. This is a full portable “static analysis specification” which means a detailed spec of state and state transitions that an implementation should do in a function body, so that different implementations will give the same answers.</p> <p>I first publicly presented this work, with live demos of the first prototype, <a href="https://youtu.be/hEx5DNLWGgA?si=JxOBM_060Rsalchy&amp;t=1828">in my CppCon 2015 talk (starting at 30:28)</a>. I then published the detailed specification on GitHub and cc’d/FYI’d ISO via the paper <a href="https://wg21.link/p1179"><strong>P1179 “Lifetime safety: Preventing common dangling”</strong></a> back in 2019, but at that point I was just giving the committee an FYI… I never asked to present it for adoption, in part because I wanted to gain more usage experience, and in part because at the time the committee did not yet have this kind of safety as a first-order priority.</p> <p>Now, times have changed: Parts of this have now been implemented and shipped in Microsoft Visual Studio, JetBrains CLion, a Clang fork, and even a smidgen in Clang trunk I’m told. And safety/security is finally a first-order concern, so the current paper <a href="https://wg21.link/p3465"><strong>P3465R0 “Pursue P1179 as a Lifetime TS”</strong></a> points back to P1179 and suggests that the time is ripe to turn it into an ISO C++ Technical Specification. I proposed that we pursue turning this analysis specification into a Technical Specification (TS) separate from the standard in order to get one more round of WG21-endorsed experience before we cast it in stone as a lifetime Profile: While implementations have implemented a lot of the design, they haven’t yet implemented all of it, and I think making it a TS would show WG21 interest and spur them to complete their implementations so that we could validate the last few important parts too on large amounts of real-world code, and make any needed adjustments. If all goes well with that, I hope to propose it for the standard itself in the future.</p> <p>The group voted <strong>24:0:1 in favor:neutral:against</strong> to direct me to turn P1179 into a working paper for a Technical Specification. Fortunately, the specification of state and state transitions is already very concrete, so it’s already at approximately the same level of detail as normal C++ language specification wording.</p> <h3 class="wp-block-heading">Safety #3 of 3: P3081R0 “Core safety Profiles: Specification, adoptability, and impact”</h3> <p>My third safety/security paper was <a href="https://wg21.link/p3081"><strong>P3081R0 “Core safety Profiles: Specification, adoptability, and impact.”</strong></a> I presented it Wednesday afternoon in SG15 (Tooling), Thursday morning in SG23 (Safety and Security), and Friday morning in EWG (the main language evolution group), with a target of C++26.</p> <p>This is a companion paper to my <a href="https://herbsutter.com/2024/03/11/safety-in-context/">&#8220;C++ safety, in context&#8221;</a> blog essay this spring; see that essay for the full motivation, context, and rationale. P3081 contains the concrete proposed semantics:</p> <ul class="wp-block-list"> <li>Proposes a concrete initial set of urgently needed enforced safety Profiles.</li> <li>Described how a Profiles implementation can prioritize <strong>adoptability</strong> and safety improvement <strong>impact</strong>, especially to silently fix serious bugs in existing code by just recompiling the code (i.e., no manual code changes required) where possible, and making it easy to opt into broadly applicable safety profiles.</li> </ul> <p>I tried to push the boundaries of what’s possible in C++ by suggesting we do something we’ve never done before in the ISO C++ standard: Have the Standard actually normatively (i.e., as a hard requirement) require implementations (usually compilers, and not third-party post-build tools) to offer safety-related “fixits” to automatically correct C++ code where the fix can be super reliable. We’ve never formally required anything like this before, but I felt it was important to try to push this boundary to raise the bar for all compilers because it&#8217;s so important for safety adoptability… yet I really wasn’t sure how this suggestion would fly (or get shot out of the sky, as boundary-pushing proposals tend to be).</p> <p>The first presentation was on Wednesday after lunch to SG15 (Tooling) because the paper suggested this novelty of requiring C++ compilers to offer automatic fixits. The votes on two related polls were both <strong>unanimously 8:2:0 in favor:neutral:against</strong>. People in the room included tooling and compiler experts for GCC and Clang, and their main comment was (slightly paraphrased) ‘yeah, sure, this is 2024, our C++ compilers all already offer fixits, let’s require compilers to do it consistently.’ Whew.</p> <p>The second presentation was on Thursday after breakfast to SG23 (Safety and Security), which has been encouraging work on Profiles but has not yet had any concrete proposal to forward to EWG, the main evolution working group. SG23 gave feedback, and then voted <strong>unanimously 23:1:0 in favor:neutral:against</strong> to forward P3081 to EWG specifically targeting C++26, including that Bjarne’s paper and this one should be merged to reflect the syntax decisions made earlier in the day based on Bjarne’s paper. This is the first Profiles proposal to be forwarded from SG23.</p> <p>The third presentation was on Friday after breakfast to EWG, which voted <strong>44:4:3 in favor:neutral:against</strong> to pursue this paper for C++26, and schedule teleconferences between now and February to go line-by-line through the paper in detail.</p> <p>Disclaimer: Note this means we have to do a ton of work in the next few months, if it is to have a hope of actually making C++26.</p> <h3 class="wp-block-heading">P2392R3 “Pattern matching using is and as”</h3> <p>On Thursday in EWG, I presented <a href="https://wg21.link/p2392"><strong>P2392R3 “Pattern matching using is and as.”</strong></a> There are two main parts to this paper: <code>is</code>/<code>as</code> expressions to unify and simplify safe queries/casts, and inspect pattern matching that uses the <code>is</code>/<code>as</code> approach.</p> <p>This time the results were quite mixed, with no consensus to encourage proceeding with my proposal: For the whole paper, EWG voted <strong>19:6:22 in favor:neutral:against</strong>. For just the is/as portion, EWG voted <strong>21:8:20 in favor:neutral:against</strong>. Clearly no consensus at all, never mind not strong encouragement, and the competing proposal from Michael Park got 33:6:10. But I’m not giving up P2392… I’ll try to incorporate the feedback heard in the room, and perhaps improve consensus at the next meeting or two.</p> <h3 class="wp-block-heading">P3466R0 “(Re)affirm design principles for future C++ evolution”</h3> <p>Finally, on Friday afternoon in EWG, I presented <a href="https://isocpp.org/files/papers/P3466R1.pdf"><strong>P3466 “(Re)affirm design principles for future C++ evolution.”</strong></a> Note: I presented the initial revision R0, and this link is to a draft revision R1 that incorporates the direction from the group (but my R1 edits are still being reviewed to make sure I applied EWG’s direction correctly).</p> <p>The summary up front is:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>C++ is a living language that continues to evolve. Especially with C++26 and compile-time programming, and new proposals for type and memory safety, we want to make sure C++ evolution remains as cohesive and consistent as possible so that (a) it’s “still C++” in that it hews to C++’s core principles, and (b) it’s delivering the highest quality value to make C++ code safer and simpler.</p> <p>The Library Evolution WG has adopted written design principles to guide proposals and their discussion. This paper proposes that the Language Evolution WG also adopt written principles to guide new proposals and their discussion, and proposes the principles in this paper as a starting point.</p> </blockquote> <p>EWG voted to turn this paper into a new Standing Document (which future papers can add to) to document EWG’s values: <strong>29:22:2 in favor:neutral:against</strong>.</p> <h3 class="wp-block-heading">P0707R5 “Metaclass functions for generative C++”</h3> <p>The committee didn’t have time to consider all papers at the meeting, and my paper <strong><a href="https://wg21.link/p0707">P0707R5 “Metaclass functions for generative C++”</a></strong> is one that got deferred to be considered at a between-meetings Zoom telecon over the winter.</p> <p>That’s it for my papers this time… whew. More news next time, from Austria…</p> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2024/11/24/wg21-2024-11/" rel="bookmark"><time class="entry-date published" datetime="2024-11-24T22:00:00-08:00">2024-11-24</time><time class="updated" datetime="2024-11-24T22:36:53-08:00">2024-11-24</time></a> </span> <span class="word-count">17 Minutes</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5656" class="post-5656 post type-post status-publish format-standard hentry category-c tag-c tag-c26 tag-programming tag-reflection tag-safety tag-security tag-software-development tag-technology"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2024/11/11/a-new-chapter-and-a-pivotal-year-for-cpp/" rel="bookmark">A new chapter, and thoughts on a pivotal year for&nbsp;C++</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>Starting today I&#8217;m excited to be working on a new team, with my C++ standards and community roles unchanged. I also wanted to write a few words about why I&#8217;m excited about continuing to invest my time heavily in C++&#8217;s standardization and evolution especially now, because I think 2024 has been a pivotal year for C++ — and so this has turned into a bit of an early “year-end C++ retrospective” post too.</p> <p>It’s been a blast to be on the Microsoft Visual C++ compiler team for over 22 years! The time has flown by because the people and the challenges have always been world-class. An underappreciated benefit of being on a team that owns a foundational technology (like a major C++ compiler) is that you often don’t have to change teams to find interesting projects, because new interesting projects need compiler support and so tend to come to you. That’s been a real privilege, and why I stuck around way longer than any other job I’ve held. Now I am finally going to switch to a new job, but I’ll continue to cheer my colleagues on as a happy MSVC user on my own projects, consuming all the cool things they’re going to do next!</p> <p>Today I’m thrilled to start at <a href="https://www.citadelsecurities.com/">Citadel Securities</a>, a firm that “combines deep trading acumen with leading-edge analytics and technology to deliver liquidity to some of the world’s most important markets, retail brokerages, and financial institutions.” I’ve known folks at CitSec for many years now (including some who participate in WG 21) and have long known it to be a great organization with some of the brightest minds in engineering and beyond. Now I’m looking forward to helping to drive CitSec’s internal C++ training initiatives, advise on technical strategy, share things I’ve learned along the way about sound design for both usability and pragmatic adoptability, and mentor a new set of talented folks there to not only take their own skilled next steps but also to themselves become mentors to others in turn. I think a continuous growth and learning culture like I’ve seen at CitSec consistently for over a dozen years is one of the most important qualities a company can have, because if you have that you can always grow all the other things you need, including as demands evolve over time. But maybe most of all I’m looking forward to learning a lot myself as I dive back into the world of finance — finance is where I started my junior career in the 80s and 90s, and I’m sure I’ll learn a ton in CitSec’s diverse set of 21<sup>st</sup>-century businesses that encounter interesting, leading-edge technical challenges every day that go well beyond the ones I encountered back in the 20<sup>th</sup>.</p> <p>My other C++ community roles are unchanged — I’m continuing my current term as chair of the ISO C++ committee, I&#8217;m continuing as chair of the Standard C++ Foundation, and especially I&#8217;m continuing to work heavily on ISO C++ evolution (I have eight papers in the current mailing for this month’s Wrocław meeting!) including supporting those with <a href="https://github.com/hsutter/cppfront">cppfront</a> prototype implementations. I meant it when I said in my CppCon talk that <a href="https://www.youtube.com/watch?v=FNi1-x4pojs">C++’s next decade will be dominated by reflection and safety improvements</a>, and that C++26 really is shaping up to be the most impactful release since C++11 that started a new era of C++; it&#8217;s an exciting time for C++ and I plan to keep spending a lot of time contributing to C++26 and beyond.</p> <p>Drilling down a little: Why is 2024 a pivotal year for C++? Because for the first time in 2024 the ISO committee has started adopting (or is on track to soon adopt) serious safety and reflection improvements into the draft C++ standard, and that&#8217;s a big turning point: </p> <ul class="wp-block-list"> <li>For <strong>safety</strong>: With <a href="https://wg21.link/p2795">uninitialized local variables no longer being undefined behavior (UB)</a> in C++26 as of March 2024, C++ is taking a first serious step to really removing safety-related UB, and achieve the &#8216;holy grail&#8217; of an easy adoption story: &#8220;Just recompile your existing code with a C++26 compiler, with zero manual code changes, and it&#8217;s safer with less UB.&#8221; This month, I&#8217;m following up on that proposing <a href="https://isocpp.org/files/papers/P3436R1.pdf">P3436R1, a strategy for how we could remove <em>all</em> safety-related UB by default</a> from C++ — something that I&#8217;m pretty sure a lot of folks can&#8217;t imagine C++ could ever do while still remaining true to what makes C++ be C++, but that in fact C++ has already been doing for years in <code>constexpr</code> code! The idea I&#8217;m proposing is to remove the same cases of UB we already do in <code>constexpr</code> code also at execution time, in one of two ways for each case: when it&#8217;s efficient enough, eliminate that case universally the same as we just did for uninitialized locals; otherwise, leverage the <a href="https://wg21.link/p3274">great ideas</a> in the <a href="https://wg21.link/p3081">Profiles</a> proposals as a way to opt in/out of that case (see P3436 for details). If the committee likes the idea enough to encourage me to go do more work to flesh it out, over the winter I&#8217;ll invest the time to expand the paper into a complete catalog of safety-related UB with a per-case proposal to eliminate that UB at execution time. If we can really achieve a future C++ where you can &#8220;just recompile your existing code with safety Profiles enabled, and it&#8217;s safer with zero safety-related UB,&#8221; that would be a huge step forward. (Of course, some Profiles rules will require code changes to get the full safety benefits; see the details in section 2 of my supporting <a href="https://wg21.link/p3081">Profiles paper</a>.)</li> <li>For <strong>reflection</strong>: Starting with <a href="https://wg21.link/p2996r7">P2996R7</a> whose language part was design-approved for C++26 in June 2024, we can lay a foundation to then build on with follow-on papers like <a href="https://wg21.link/p3294">P3294R2</a> and <a href="https://wg21.link/p3157"></a><a href="https://isocpp.org/files/papers/P3437R1.pdf">P3437R1</a> to add generation and more features. As I demonstrated with examples in the above-linked CppCon talk, reflection (including generation) will be a game-changer that I believe will dominate the next decade of C++ as we build it out in the standard and learn to use it in the global C++ community. I&#8217;m working with P2996/P3294 prototypes and my own <a href="https://github.com/hsutter/cppfront">cppfront</a> compiler to help gather usability experience, and I&#8217;m contributing my papers like <a href="https://wg21.link/p0707r5">P0707R5</a> and <a href="https://isocpp.org/files/papers/P3437R1.pdf">P3437R1</a> as companion/supporting papers to those core proposals to try to help them progress.</li> </ul> <p>As Bjarne Stroustrup famously said, “C++11 [felt] like a new language,” starting a new &#8220;modern&#8221; C++ style featuring <code>auto</code> and lambdas and standard safe smart pointers and range-<code>for</code> and move semantics and <code>constexpr</code> compile-time code, that we completed and built on over the next decade with C++14/17/20/23. (And don&#8217;t forget that C++11&#8217;s move semantics already delivered the ideal adoption story of &#8220;just recompile your existing code with a C++11 compiler, with zero manual code changes, and it&#8217;s faster.&#8221;) Since 2011 until now, &#8220;modern C++&#8221; has pretty much meant &#8220;C++ since C++11&#8221; because C++11 made that much of a difference in how C++ worked and felt.</p> <p>Now I think C++26 is setting the stage to do that again for a second time: Our next major era of what &#8220;modern C++&#8221; will mean will be characterized by having safety by default and first-class support for reflection-based generative compile-time libraries. Needless to say, this is a group effort that is accomplished only by an amazing set of C++ pros from dozens of countries, including the authors of the above papers but also many hundreds of other experts who help design and review features. To all of those experts: Again, <strong>thank you</strong>! I&#8217;ll keep trying to contribute what I can too, to help ship C++26 with its “version 1” of a set of these major new foundational tools and to continue to add to that foundation further in the coming years as we all learn to use the new features to make our code safer and simpler.</p> <p>C++ is critically important to our society, and is right now actively flourishing. C++ is essential not only at Citadel Securities itself, but throughout capital markets and the financial industry… and even that is itself just one of the critical sectors of our civilization that heavily depend on C++ code and will for the foreseeable future. I’m thrilled that CitSec’s leadership shares my view of that, and my same goals for continuing to evolve ISO C++ to make it better, especially when it comes to increasing safety and usability to harden our society’s key infrastructure (including our markets) and to make C++ even easier to use and more expressive. I’m excited to see what the coming decade of C++ brings&#8230; 2024 really has shaped up to be a pivotal year for C++ evolution, and I can’t wait to see where the ride takes us next.</p> <p></p> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2024/11/11/a-new-chapter-and-a-pivotal-year-for-cpp/" rel="bookmark"><time class="entry-date published updated" datetime="2024-11-11T04:15:11-08:00">2024-11-11</time></a> </span> <span class="word-count">6 Minutes</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <article id="post-5645" class="post-5645 post type-post status-publish format-standard hentry category-c tag-coding tag-programming tag-rust"> <header class="entry-header"> <h1 class="entry-title"><a href="https://herbsutter.com/2024/10/23/podcast-interview-rust-and-c/" rel="bookmark">Podcast interview: Rust and&nbsp;C++</a></h1> </header><!-- .entry-header --> <div class="entry-content"> <p>In early September I had a very enjoyable technical chat with <a href="https://steveklabnik.com/">Steve Klabnik</a> of Rust fame and interviewer Kevin Ball of Software Engineering Daily, and the podcast is now available.</p> <p><em>Update: I asked them to please change the &#8220;Rust vs C++&#8221; title to &#8220;Rust and C++&#8221; and they kindly did so. Thanks!</em></p> <p>Here&#8217;s the info&#8230;</p> <hr class="wp-block-separator has-alpha-channel-opacity" /> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <h2 class="wp-block-heading"><a href="https://softwareengineeringdaily.com/2024/10/23/rust-vs-c-with-steve-klabnik-herb-sutter/">Rust and C++ with Steve Klabnik and Herb Sutter</a></h2> <div class="wp-block-image"> <figure class="alignright is-resized"><img src="https://i0.wp.com/softwareengineeringdaily.com/wp-content/uploads/2024/10/Rust-and-C-with-Steve-Klabnik-and-Herb-Sutter.png?resize=600%2C315&amp;ssl=1" alt="" style="width:449px;height:auto" /></figure></div> <p>In software engineering, C++ is often used in areas where low-level system access and high-performance are critical, such as operating systems, game engines, and embedded systems. Its long-standing presence and compatibility with legacy code make it a go-to language for maintaining and extending older projects. Rust, while newer, is gaining traction in roles that demand safety and concurrency, particularly in systems programming.</p> <p>We wanted to explore these two languages side-by-side, so we invited&nbsp;<a href="https://herbsutter.com">Herb Sutter</a>&nbsp;and&nbsp;<a href="https://steveklabnik.com/">Steve Klabnik</a>&nbsp;to join host Kevin Ball on the show. Herb works at Microsoft and chairs the ISO&nbsp;C++&nbsp;standards committee. Steve works at Oxide Computer Company, is an alumnus of the&nbsp;<a href="https://x.com/rustlang">Rust</a>&nbsp;Core Team, and is the primary author of The Rust Programming Language book.</p> <p>We hope you enjoy this deep dive into Rust and C++ on Software Engineering Daily.</p> <div class="wp-block-image"> <figure class="alignleft"><a href="https://i0.wp.com/softwareengineeringdaily.com/wp-content/uploads/2020/01/KevinBall.jpg"><img src="https://i0.wp.com/softwareengineeringdaily.com/wp-content/uploads/2020/01/KevinBall.jpg?resize=218%2C258&amp;ssl=1" alt="" class="wp-image-15581" /></a></figure></div> <p><a href="https://www.kball.llc/">Kevin Ball</a>&nbsp;or KBall, is the vice president of engineering at Mento and an independent coach for engineers and engineering leaders. He co-founded and served as CTO for two companies, founded the San Diego JavaScript meetup, and organizes the AI inaction discussion group through Latent Space.</p> <p><a href="http://softwareengineeringdaily.com/wp-content/uploads/2024/10/SED1756-Rust-vs-Cpp.txt">Please click here to see the transcript of this episode.</a></p> </blockquote> </div><!-- .entry-content --> <footer class="entry-footer"> <div class="entry-meta"> <span class="byline"> <a href="https://herbsutter.com/author/herbsutter/" title="Posts by Herb Sutter" rel="author">Herb Sutter</a> </span> <span class="cat-links"> <a href="https://herbsutter.com/category/c/" rel="category tag">C++</a> </span><!-- .cat-links --> <span class="published-on"> <a href="https://herbsutter.com/2024/10/23/podcast-interview-rust-and-c/" rel="bookmark"><time class="entry-date published" datetime="2024-10-23T15:48:47-08:00">2024-10-23</time><time class="updated" datetime="2024-10-25T08:56:23-08:00">2024-10-25</time></a> </span> <span class="word-count">1 Minute</span> </div><!-- .entry-meta --> </footer><!-- .entry-footer --> </article><!-- #post-## --> <nav class="navigation posts-navigation" aria-label="Posts"> <h2 class="screen-reader-text">Posts navigation</h2> <div class="nav-links"><div class="nav-previous"><a href="https://herbsutter.com/page/2/" >Older posts</a></div></div> </nav> </main><!-- #main --> </div><!-- #primary --> <div id="secondary" class="widget-area" role="complementary"> <aside id="search-4" class="widget widget_search"><form role="search" method="get" class="search-form" action="https://herbsutter.com/"> <label> <span class="screen-reader-text">Search for:</span> <input type="search" class="search-field" placeholder="Search &hellip;" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Search" /> </form></aside><aside id="blog_subscription-3" class="widget widget_blog_subscription jetpack_subscription_widget"><h1 class="widget-title"><label for="subscribe-field">Follow by email</label></h1> <div class="wp-block-jetpack-subscriptions__container"> <form action="https://subscribe.wordpress.com" method="post" accept-charset="utf-8" data-blog="3379246" data-post_access_level="everybody" id="subscribe-blog" > <p id="subscribe-email"> <label id="subscribe-field-label" for="subscribe-field" class="screen-reader-text" > Email Address: </label> <input type="email" name="email" style="width: 95%; padding: 1px 10px" placeholder="Email Address" value="" id="subscribe-field" required /> </p> <p id="subscribe-submit" > <input type="hidden" name="action" value="subscribe"/> <input type="hidden" name="blog_id" value="3379246"/> <input type="hidden" name="source" value="https://herbsutter.com/"/> <input type="hidden" name="sub-type" value="widget"/> <input type="hidden" name="redirect_fragment" value="subscribe-blog"/> <input type="hidden" id="_wpnonce" name="_wpnonce" value="5cbc5b712e" /> <button type="submit" class="wp-block-button__link" > Subscribe </button> </p> </form> </div> </aside><aside id="block-2" class="widget widget_block widget_media_image"> <figure class="wp-block-image size-medium is-resized is-style-default"><a href="https://herbsutter.files.wordpress.com/2024/03/herb-cppcon-2021.jpg"><img loading="lazy" width="300" height="230" src="https://herbsutter.files.wordpress.com/2024/03/herb-cppcon-2021.jpg?w=300" alt="" class="wp-image-5065" style="width:248px;height:auto" srcset="https://herbsutter.files.wordpress.com/2024/03/herb-cppcon-2021.jpg?w=300 300w, https://herbsutter.files.wordpress.com/2024/03/herb-cppcon-2021.jpg?w=600 600w, https://herbsutter.files.wordpress.com/2024/03/herb-cppcon-2021.jpg?w=150 150w" sizes="(max-width: 300px) 100vw, 300px" /></a></figure> </aside><aside id="block-3" class="widget widget_block widget_text"> <p class="has-small-font-size">I'm an author and speaker, and a programming language nerd whose focus is on enabling our program code to be both clean <em>and</em> fast. I've been writing about programming since 1993, usually about C++ or about concurrency and parallelism. I'm the designer or co-designer of a number of standardized ISO C++ language and library features. I've served as the chair of the <a href="https://isocpp.org/std/the-committee">ISO C++ standards committee</a> since 2002, and as the chair of the <a href="https://isocpp.org/about">Standard C++ Foundation</a> since 2012. I'm a technical fellow at <a href="https://www.citadelsecurities.com/">Citadel Securities</a>. This personal website expresses the opinions of none of those organizations.</p> </aside><aside id="archives-4" class="widget widget_archive"><h1 class="widget-title">Archives</h1> <ul> <li><a href='https://herbsutter.com/2025/02/'>February 2025</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2025/01/'>January 2025</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2024/12/'>December 2024</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2024/11/'>November 2024</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2024/10/'>October 2024</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2024/09/'>September 2024</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2024/08/'>August 2024</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2024/07/'>July 2024</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2024/06/'>June 2024</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2024/04/'>April 2024</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2024/03/'>March 2024</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2024/02/'>February 2024</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2023/11/'>November 2023</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2023/10/'>October 2023</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2023/09/'>September 2023</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2023/08/'>August 2023</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2023/06/'>June 2023</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2023/04/'>April 2023</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2023/02/'>February 2023</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2022/12/'>December 2022</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2022/11/'>November 2022</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2022/10/'>October 2022</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2022/09/'>September 2022</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2021/10/'>October 2021</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2021/06/'>June 2021</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2021/05/'>May 2021</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2021/03/'>March 2021</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2021/02/'>February 2021</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2021/01/'>January 2021</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2020/12/'>December 2020</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2020/11/'>November 2020</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2020/10/'>October 2020</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2020/09/'>September 2020</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2020/07/'>July 2020</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2020/06/'>June 2020</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2020/05/'>May 2020</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2020/04/'>April 2020</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2020/03/'>March 2020</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2020/02/'>February 2020</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2019/11/'>November 2019</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2019/10/'>October 2019</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2019/09/'>September 2019</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2019/07/'>July 2019</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2019/06/'>June 2019</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2019/05/'>May 2019</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2019/04/'>April 2019</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2019/02/'>February 2019</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2018/11/'>November 2018</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2018/09/'>September 2018</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2018/07/'>July 2018</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2018/04/'>April 2018</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2017/11/'>November 2017</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2017/10/'>October 2017</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2017/09/'>September 2017</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2017/07/'>July 2017</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2017/06/'>June 2017</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2017/03/'>March 2017</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2017/02/'>February 2017</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2016/11/'>November 2016</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2016/09/'>September 2016</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2016/06/'>June 2016</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2016/03/'>March 2016</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/10/'>October 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/09/'>September 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/07/'>July 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/06/'>June 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/05/'>May 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/04/'>April 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2015/01/'>January 2015</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2014/12/'>December 2014</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2014/11/'>November 2014</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2014/10/'>October 2014</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2014/09/'>September 2014</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2014/08/'>August 2014</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2014/07/'>July 2014</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2014/05/'>May 2014</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2014/04/'>April 2014</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2014/03/'>March 2014</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2014/02/'>February 2014</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2014/01/'>January 2014</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2013/12/'>December 2013</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2013/11/'>November 2013</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2013/10/'>October 2013</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2013/09/'>September 2013</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2013/08/'>August 2013</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2013/07/'>July 2013</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2013/06/'>June 2013</a>&nbsp;(7)</li> <li><a href='https://herbsutter.com/2013/05/'>May 2013</a>&nbsp;(22)</li> <li><a href='https://herbsutter.com/2013/04/'>April 2013</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2013/03/'>March 2013</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2013/02/'>February 2013</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2013/01/'>January 2013</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2012/12/'>December 2012</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2012/11/'>November 2012</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2012/10/'>October 2012</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2012/09/'>September 2012</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2012/08/'>August 2012</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2012/07/'>July 2012</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2012/06/'>June 2012</a>&nbsp;(7)</li> <li><a href='https://herbsutter.com/2012/05/'>May 2012</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2012/04/'>April 2012</a>&nbsp;(17)</li> <li><a href='https://herbsutter.com/2012/03/'>March 2012</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2012/02/'>February 2012</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2012/01/'>January 2012</a>&nbsp;(7)</li> <li><a href='https://herbsutter.com/2011/12/'>December 2011</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2011/11/'>November 2011</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2011/10/'>October 2011</a>&nbsp;(10)</li> <li><a href='https://herbsutter.com/2011/09/'>September 2011</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2011/08/'>August 2011</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2011/07/'>July 2011</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2011/06/'>June 2011</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2011/05/'>May 2011</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2011/04/'>April 2011</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2011/03/'>March 2011</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2011/01/'>January 2011</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2010/12/'>December 2010</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2010/10/'>October 2010</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2010/09/'>September 2010</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2010/08/'>August 2010</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2010/07/'>July 2010</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2010/06/'>June 2010</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2010/05/'>May 2010</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2010/04/'>April 2010</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2010/03/'>March 2010</a>&nbsp;(9)</li> <li><a href='https://herbsutter.com/2010/02/'>February 2010</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2010/01/'>January 2010</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2009/12/'>December 2009</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2009/11/'>November 2009</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2009/10/'>October 2009</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2009/09/'>September 2009</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2009/08/'>August 2009</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2009/07/'>July 2009</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2009/06/'>June 2009</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2009/05/'>May 2009</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2009/04/'>April 2009</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2009/03/'>March 2009</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2009/02/'>February 2009</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2009/01/'>January 2009</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2008/12/'>December 2008</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2008/11/'>November 2008</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2008/10/'>October 2008</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2008/09/'>September 2008</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2008/08/'>August 2008</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2008/07/'>July 2008</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2008/06/'>June 2008</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2008/05/'>May 2008</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2008/04/'>April 2008</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2008/03/'>March 2008</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2008/02/'>February 2008</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2008/01/'>January 2008</a>&nbsp;(7)</li> <li><a href='https://herbsutter.com/2007/12/'>December 2007</a>&nbsp;(5)</li> <li><a href='https://herbsutter.com/2007/11/'>November 2007</a>&nbsp;(4)</li> <li><a href='https://herbsutter.com/2007/10/'>October 2007</a>&nbsp;(1)</li> <li><a href='https://herbsutter.com/2007/09/'>September 2007</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2007/08/'>August 2007</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2007/07/'>July 2007</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2007/06/'>June 2007</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2007/05/'>May 2007</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2007/04/'>April 2007</a>&nbsp;(2)</li> <li><a href='https://herbsutter.com/2007/03/'>March 2007</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2007/02/'>February 2007</a>&nbsp;(3)</li> <li><a href='https://herbsutter.com/2007/01/'>January 2007</a>&nbsp;(6)</li> <li><a href='https://herbsutter.com/2006/12/'>December 2006</a>&nbsp;(2)</li> </ul> </aside></div><!-- #secondary --> </div><!-- #content --> <footer id="colophon" class="site-footer" role="contentinfo"> <div class="site-info"> <a href="https://wordpress.com/?ref=footer_blog" rel="nofollow">Blog at WordPress.com.</a> </div><!-- .site-info --> </footer><!-- #colophon --> </div><!-- #content-wrapper --> </div><!-- #page --> <script type="text/javascript"> var infiniteScroll = {"settings":{"id":"main","ajaxurl":"https:\/\/herbsutter.com\/?infinity=scrolling","type":"scroll","wrapper":true,"wrapper_class":"infinite-wrap","footer":"page","click_handle":"1","text":"Older posts","totop":"Scroll back to top","currentday":"23.10.24","order":"DESC","scripts":[],"styles":[],"google_analytics":false,"offset":1,"history":{"host":"herbsutter.com","path":"\/page\/%d\/","use_trailing_slashes":true,"parameters":""},"query_args":{"error":"","m":"","p":0,"post_parent":"","subpost":"","subpost_id":"","attachment":"","attachment_id":0,"name":"","pagename":"","page_id":0,"second":"","minute":"","hour":"","day":0,"monthnum":0,"year":0,"w":0,"category_name":"","tag":"","cat":"","tag_id":"","author":"","author_name":"","feed":"","tb":"","paged":0,"meta_key":"","meta_value":"","preview":"","s":"","sentence":"","title":"","fields":"","menu_order":"","embed":"","category__in":[],"category__not_in":[],"category__and":[],"post__in":[],"post__not_in":[],"post_name__in":[],"tag__in":[],"tag__not_in":[],"tag__and":[],"tag_slug__in":[],"tag_slug__and":[],"post_parent__in":[],"post_parent__not_in":[],"author__in":[],"author__not_in":[],"search_columns":[],"lazy_load_term_meta":false,"posts_per_page":10,"ignore_sticky_posts":false,"suppress_filters":false,"cache_results":true,"update_post_term_cache":true,"update_menu_item_cache":false,"update_post_meta_cache":true,"post_type":"","nopaging":false,"comments_per_page":"50","no_found_rows":false,"order":"DESC"},"query_before":"2025-02-25 03:03:11","last_post_date":"2024-10-23 15:48:47","body_class":"infinite-scroll neverending","loading_text":"Loading new page","stats":"blog=3379246&v=wpcom&tz=-8&user_id=0&subd=herbsutter&x_pagetype=infinite"}}; </script> <!-- --> <script type="text/javascript" src="//0.gravatar.com/js/hovercards/hovercards.min.js?ver=2025097d8bf6c02970a26c6b0c26b0fcfc89796aa30f84307cffd8fd28d2bcca53dd7a" id="grofiles-cards-js"></script> <script type="text/javascript" id="wpgroho-js-extra"> /* <![CDATA[ */ var WPGroHo = {"my_hash":""}; /* ]]> */ </script> <script crossorigin='anonymous' type='text/javascript' src='https://s2.wp.com/wp-content/mu-plugins/gravatar-hovercards/wpgroho.js?m=1610363240i'></script> <script> // Initialize and attach hovercards to all gravatars ( function() { function init() { if ( typeof Gravatar === 'undefined' ) { return; } if ( typeof Gravatar.init !== 'function' ) { return; } Gravatar.profile_cb = function ( hash, id ) { WPGroHo.syncProfileData( hash, id ); }; Gravatar.my_hash = WPGroHo.my_hash; Gravatar.init( 'body', '#wp-admin-bar-my-account', { i18n: { 'Edit your profile →': 'Edit your profile →', 'View profile →': 'View profile →', 'Contact': 'Contact', 'Send money': 'Send money', 'Sorry, we are unable to load this Gravatar profile.': 'Sorry, we are unable to load this Gravatar profile.', 'Profile not found.': 'Profile not found.', 'Too Many Requests.': 'Too Many Requests.', 'Internal Server Error.': 'Internal Server Error.', }, } ); } if ( document.readyState !== 'loading' ) { init(); } else { document.addEventListener( 'DOMContentLoaded', init ); } } )(); </script> <div style="display:none"> <div class="grofile-hash-map-c0ba56bfd231f8f04feb057728975181"> </div> </div> <div id="infinite-footer"> <div class="container"> <div class="blog-info"> <a id="infinity-blog-title" href="https://herbsutter.com/" rel="home"> Sutter’s Mill </a> </div> <div class="blog-credits"> <a href="https://wordpress.com/?ref=footer_blog" rel="nofollow">Blog at WordPress.com.</a> </div> </div> </div><!-- #infinite-footer --> <div id="actionbar" dir="ltr" style="display: none;" class="actnbr-pub-independent-publisher-2 actnbr-has-follow actnbr-has-actions"> <ul> <li class="actnbr-btn actnbr-hidden"> <a class="actnbr-action actnbr-actn-follow " href=""> <svg class="gridicon" height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path clip-rule="evenodd" d="m4 4.5h12v6.5h1.5v-6.5-1.5h-1.5-12-1.5v1.5 10.5c0 1.1046.89543 2 2 2h7v-1.5h-7c-.27614 0-.5-.2239-.5-.5zm10.5 2h-9v1.5h9zm-5 3h-4v1.5h4zm3.5 1.5h-1v1h1zm-1-1.5h-1.5v1.5 1 1.5h1.5 1 1.5v-1.5-1-1.5h-1.5zm-2.5 2.5h-4v1.5h4zm6.5 1.25h1.5v2.25h2.25v1.5h-2.25v2.25h-1.5v-2.25h-2.25v-1.5h2.25z" fill-rule="evenodd"></path></svg> <span>Subscribe</span> </a> <a class="actnbr-action actnbr-actn-following no-display" href=""> <svg class="gridicon" height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill-rule="evenodd" clip-rule="evenodd" d="M16 4.5H4V15C4 15.2761 4.22386 15.5 4.5 15.5H11.5V17H4.5C3.39543 17 2.5 16.1046 2.5 15V4.5V3H4H16H17.5V4.5V12.5H16V4.5ZM5.5 6.5H14.5V8H5.5V6.5ZM5.5 9.5H9.5V11H5.5V9.5ZM12 11H13V12H12V11ZM10.5 9.5H12H13H14.5V11V12V13.5H13H12H10.5V12V11V9.5ZM5.5 12H9.5V13.5H5.5V12Z" fill="#008A20"></path><path class="following-icon-tick" d="M13.5 16L15.5 18L19 14.5" stroke="#008A20" stroke-width="1.5"></path></svg> <span>Subscribed</span> </a> <div class="actnbr-popover tip tip-top-left actnbr-notice" id="follow-bubble"> <div class="tip-arrow"></div> <div class="tip-inner actnbr-follow-bubble"> <ul> <li class="actnbr-sitename"> <a href="https://herbsutter.com"> <img loading='lazy' alt='' src='https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=50&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png' srcset='https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=50&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 1x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=75&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 1.5x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=100&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 2x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=150&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 3x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=200&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 4x' class='avatar avatar-50' height='50' width='50' /> Sutter’s Mill </a> </li> <div class="actnbr-message no-display"></div> <form method="post" action="https://subscribe.wordpress.com" accept-charset="utf-8" style="display: none;"> <div class="actnbr-follow-count">Join 5,292 other subscribers</div> <div> <input type="email" name="email" placeholder="Enter your email address" class="actnbr-email-field" aria-label="Enter your email address" /> </div> <input type="hidden" name="action" value="subscribe" /> <input type="hidden" name="blog_id" value="3379246" /> <input type="hidden" name="source" value="https://herbsutter.com/" /> <input type="hidden" name="sub-type" value="actionbar-follow" /> <input type="hidden" id="_wpnonce" name="_wpnonce" value="5cbc5b712e" /> <div class="actnbr-button-wrap"> <button type="submit" value="Sign me up"> Sign me up </button> </div> </form> <li class="actnbr-login-nudge"> <div> Already have a WordPress.com account? <a href="https://wordpress.com/log-in?redirect_to=https%3A%2F%2Fr-login.wordpress.com%2Fremote-login.php%3Faction%3Dlink%26back%3Dhttps%253A%252F%252Fherbsutter.com%252F2025%252F02%252F17%252Ftrip-report-february-2025-iso-c-standards-meeting-hagenberg-austria%252F">Log in now.</a> </div> </li> </ul> </div> </div> </li> <li class="actnbr-ellipsis actnbr-hidden"> <svg class="gridicon gridicons-ellipsis" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><path d="M7 12c0 1.104-.896 2-2 2s-2-.896-2-2 .896-2 2-2 2 .896 2 2zm12-2c-1.104 0-2 .896-2 2s.896 2 2 2 2-.896 2-2-.896-2-2-2zm-7 0c-1.104 0-2 .896-2 2s.896 2 2 2 2-.896 2-2-.896-2-2-2z"/></g></svg> <div class="actnbr-popover tip tip-top-left actnbr-more"> <div class="tip-arrow"></div> <div class="tip-inner"> <ul> <li class="actnbr-sitename"> <a href="https://herbsutter.com"> <img loading='lazy' alt='' src='https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=50&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png' srcset='https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=50&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 1x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=75&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 1.5x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=100&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 2x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=150&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 3x, https://secure.gravatar.com/blavatar/fe7f5b0b83dba894afe26c42bcab33fe2d1246d9730ef182c72c0bff0dc26acb?s=200&#038;d=https%3A%2F%2Fs2.wp.com%2Fi%2Flogo%2Fwpcom-gray-white.png 4x' class='avatar avatar-50' height='50' width='50' /> Sutter’s Mill </a> </li> <li class="actnbr-folded-follow"> <a class="actnbr-action actnbr-actn-follow " href=""> <svg class="gridicon" height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path clip-rule="evenodd" d="m4 4.5h12v6.5h1.5v-6.5-1.5h-1.5-12-1.5v1.5 10.5c0 1.1046.89543 2 2 2h7v-1.5h-7c-.27614 0-.5-.2239-.5-.5zm10.5 2h-9v1.5h9zm-5 3h-4v1.5h4zm3.5 1.5h-1v1h1zm-1-1.5h-1.5v1.5 1 1.5h1.5 1 1.5v-1.5-1-1.5h-1.5zm-2.5 2.5h-4v1.5h4zm6.5 1.25h1.5v2.25h2.25v1.5h-2.25v2.25h-1.5v-2.25h-2.25v-1.5h2.25z" fill-rule="evenodd"></path></svg> <span>Subscribe</span> </a> <a class="actnbr-action actnbr-actn-following no-display" href=""> <svg class="gridicon" height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill-rule="evenodd" clip-rule="evenodd" d="M16 4.5H4V15C4 15.2761 4.22386 15.5 4.5 15.5H11.5V17H4.5C3.39543 17 2.5 16.1046 2.5 15V4.5V3H4H16H17.5V4.5V12.5H16V4.5ZM5.5 6.5H14.5V8H5.5V6.5ZM5.5 9.5H9.5V11H5.5V9.5ZM12 11H13V12H12V11ZM10.5 9.5H12H13H14.5V11V12V13.5H13H12H10.5V12V11V9.5ZM5.5 12H9.5V13.5H5.5V12Z" fill="#008A20"></path><path class="following-icon-tick" d="M13.5 16L15.5 18L19 14.5" stroke="#008A20" stroke-width="1.5"></path></svg> <span>Subscribed</span> </a> </li> <li class="actnbr-signup"><a href="https://wordpress.com/start/">Sign up</a></li> <li class="actnbr-login"><a href="https://wordpress.com/log-in?redirect_to=https%3A%2F%2Fr-login.wordpress.com%2Fremote-login.php%3Faction%3Dlink%26back%3Dhttps%253A%252F%252Fherbsutter.com%252F2025%252F02%252F17%252Ftrip-report-february-2025-iso-c-standards-meeting-hagenberg-austria%252F">Log in</a></li> <li class="flb-report"> <a href="https://wordpress.com/abuse/?report_url=https://herbsutter.com" target="_blank" rel="noopener noreferrer"> Report this content </a> </li> <li class="actnbr-reader"> <a href="https://wordpress.com/reader/feeds/171936"> View site in Reader </a> </li> <li class="actnbr-subs"> <a href="https://subscribe.wordpress.com/">Manage subscriptions</a> </li> <li class="actnbr-fold"><a href="">Collapse this bar</a></li> </ul> </div> </div> </li> </ul> </div> <script> window.addEventListener( "load", function( event ) { var link = document.createElement( "link" ); link.href = "https://s0.wp.com/wp-content/mu-plugins/actionbar/actionbar.css?v=20250116"; link.type = "text/css"; link.rel = "stylesheet"; document.head.appendChild( link ); var script = document.createElement( "script" ); script.src = "https://s0.wp.com/wp-content/mu-plugins/actionbar/actionbar.js?v=20250204"; script.defer = true; document.body.appendChild( script ); } ); </script> <div id="jp-carousel-loading-overlay"> <div id="jp-carousel-loading-wrapper"> <span id="jp-carousel-library-loading">&nbsp;</span> </div> </div> <div class="jp-carousel-overlay" style="display: none;"> <div class="jp-carousel-container"> <!-- The Carousel Swiper --> <div class="jp-carousel-wrap swiper-container jp-carousel-swiper-container jp-carousel-transitions" itemscope itemtype="https://schema.org/ImageGallery"> <div class="jp-carousel swiper-wrapper"></div> <div class="jp-swiper-button-prev swiper-button-prev"> <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <mask id="maskPrev" mask-type="alpha" maskUnits="userSpaceOnUse" x="8" y="6" width="9" height="12"> <path d="M16.2072 16.59L11.6496 12L16.2072 7.41L14.8041 6L8.8335 12L14.8041 18L16.2072 16.59Z" fill="white"/> </mask> <g mask="url(#maskPrev)"> <rect x="0.579102" width="23.8823" height="24" fill="#FFFFFF"/> </g> </svg> </div> <div class="jp-swiper-button-next swiper-button-next"> <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <mask id="maskNext" mask-type="alpha" maskUnits="userSpaceOnUse" x="8" y="6" width="8" height="12"> <path d="M8.59814 16.59L13.1557 12L8.59814 7.41L10.0012 6L15.9718 12L10.0012 18L8.59814 16.59Z" fill="white"/> </mask> <g mask="url(#maskNext)"> <rect x="0.34375" width="23.8822" height="24" fill="#FFFFFF"/> </g> </svg> </div> </div> <!-- The main close buton --> <div class="jp-carousel-close-hint"> <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <mask id="maskClose" mask-type="alpha" maskUnits="userSpaceOnUse" x="5" y="5" width="15" height="14"> <path d="M19.3166 6.41L17.9135 5L12.3509 10.59L6.78834 5L5.38525 6.41L10.9478 12L5.38525 17.59L6.78834 19L12.3509 13.41L17.9135 19L19.3166 17.59L13.754 12L19.3166 6.41Z" fill="white"/> </mask> <g mask="url(#maskClose)"> <rect x="0.409668" width="23.8823" height="24" fill="#FFFFFF"/> </g> </svg> </div> <!-- Image info, comments and meta --> <div class="jp-carousel-info"> <div class="jp-carousel-info-footer"> <div class="jp-carousel-pagination-container"> <div class="jp-swiper-pagination swiper-pagination"></div> <div class="jp-carousel-pagination"></div> </div> <div class="jp-carousel-photo-title-container"> <h2 class="jp-carousel-photo-caption"></h2> </div> <div class="jp-carousel-photo-icons-container"> <a href="#" class="jp-carousel-icon-btn jp-carousel-icon-info" aria-label="Toggle photo metadata visibility"> <span class="jp-carousel-icon"> <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <mask id="maskInfo" mask-type="alpha" maskUnits="userSpaceOnUse" x="2" y="2" width="21" height="20"> <path fill-rule="evenodd" clip-rule="evenodd" d="M12.7537 2C7.26076 2 2.80273 6.48 2.80273 12C2.80273 17.52 7.26076 22 12.7537 22C18.2466 22 22.7046 17.52 22.7046 12C22.7046 6.48 18.2466 2 12.7537 2ZM11.7586 7V9H13.7488V7H11.7586ZM11.7586 11V17H13.7488V11H11.7586ZM4.79292 12C4.79292 16.41 8.36531 20 12.7537 20C17.142 20 20.7144 16.41 20.7144 12C20.7144 7.59 17.142 4 12.7537 4C8.36531 4 4.79292 7.59 4.79292 12Z" fill="white"/> </mask> <g mask="url(#maskInfo)"> <rect x="0.8125" width="23.8823" height="24" fill="#FFFFFF"/> </g> </svg> </span> </a> <a href="#" class="jp-carousel-icon-btn jp-carousel-icon-comments" aria-label="Toggle photo comments visibility"> <span class="jp-carousel-icon"> <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <mask id="maskComments" mask-type="alpha" maskUnits="userSpaceOnUse" x="2" y="2" width="21" height="20"> <path fill-rule="evenodd" clip-rule="evenodd" d="M4.3271 2H20.2486C21.3432 2 22.2388 2.9 22.2388 4V16C22.2388 17.1 21.3432 18 20.2486 18H6.31729L2.33691 22V4C2.33691 2.9 3.2325 2 4.3271 2ZM6.31729 16H20.2486V4H4.3271V18L6.31729 16Z" fill="white"/> </mask> <g mask="url(#maskComments)"> <rect x="0.34668" width="23.8823" height="24" fill="#FFFFFF"/> </g> </svg> <span class="jp-carousel-has-comments-indicator" aria-label="This image has comments."></span> </span> </a> </div> </div> <div class="jp-carousel-info-extra"> <div class="jp-carousel-info-content-wrapper"> <div class="jp-carousel-photo-title-container"> <h2 class="jp-carousel-photo-title"></h2> </div> <div class="jp-carousel-comments-wrapper"> <div id="jp-carousel-comments-loading"> <span>Loading Comments...</span> </div> <div class="jp-carousel-comments"></div> <div id="jp-carousel-comment-form-container"> <span id="jp-carousel-comment-form-spinner">&nbsp;</span> <div id="jp-carousel-comment-post-results"></div> <form id="jp-carousel-comment-form"> <label for="jp-carousel-comment-form-comment-field" class="screen-reader-text">Write a Comment...</label> <textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a Comment..." ></textarea> <div id="jp-carousel-comment-form-submit-and-info-wrapper"> <div id="jp-carousel-comment-form-commenting-as"> <fieldset> <label for="jp-carousel-comment-form-email-field">Email (Required)</label> <input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field" /> </fieldset> <fieldset> <label for="jp-carousel-comment-form-author-field">Name (Required)</label> <input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field" /> </fieldset> <fieldset> <label for="jp-carousel-comment-form-url-field">Website</label> <input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field" /> </fieldset> </div> <input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="Post Comment" /> </div> </form> </div> </div> <div class="jp-carousel-image-meta"> <div class="jp-carousel-title-and-caption"> <div class="jp-carousel-photo-info"> <h3 class="jp-carousel-caption" itemprop="caption description"></h3> </div> <div class="jp-carousel-photo-description"></div> </div> <ul class="jp-carousel-image-exif" style="display: none;"></ul> <a class="jp-carousel-image-download" href="#" target="_blank" style="display: none;"> <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="3" y="3" width="19" height="18"> <path fill-rule="evenodd" clip-rule="evenodd" d="M5.84615 5V19H19.7775V12H21.7677V19C21.7677 20.1 20.8721 21 19.7775 21H5.84615C4.74159 21 3.85596 20.1 3.85596 19V5C3.85596 3.9 4.74159 3 5.84615 3H12.8118V5H5.84615ZM14.802 5V3H21.7677V10H19.7775V6.41L9.99569 16.24L8.59261 14.83L18.3744 5H14.802Z" fill="white"/> </mask> <g mask="url(#mask0)"> <rect x="0.870605" width="23.8823" height="24" fill="#FFFFFF"/> </g> </svg> <span class="jp-carousel-download-text"></span> </a> <div class="jp-carousel-image-map" style="display: none;"></div> </div> </div> </div> </div> </div> </div> <script crossorigin='anonymous' type='text/javascript' src='https://s1.wp.com/_static/??-eJzTLy/QTc7PK0nNK9EvyClNz8wr1i+uzCtJrMjITM/IAeKS1CJMEWP94uSizIISoOIM5/yiVL2sYh19yo1yKioFmldQADTOPtfW0MzQ1MTczNLYKAsAjy0/rA=='></script> <script type='text/javascript'> (function(){ var corecss = document.createElement('link'); var themecss = document.createElement('link'); var corecssurl = "https://s1.wp.com/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shCore.css?ver=3.0.9b"; if ( corecss.setAttribute ) { corecss.setAttribute( "rel", "stylesheet" ); corecss.setAttribute( "type", "text/css" ); corecss.setAttribute( "href", corecssurl ); } else { corecss.rel = "stylesheet"; corecss.href = corecssurl; } document.head.appendChild( corecss ); var themecssurl = "https://s2.wp.com/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shThemeDefault.css?m=1363304414i&amp;ver=3.0.9b"; if ( themecss.setAttribute ) { themecss.setAttribute( "rel", "stylesheet" ); themecss.setAttribute( "type", "text/css" ); themecss.setAttribute( "href", themecssurl ); } else { themecss.rel = "stylesheet"; themecss.href = themecssurl; } document.head.appendChild( themecss ); })(); SyntaxHighlighter.config.strings.expandSource = '+ expand source'; SyntaxHighlighter.config.strings.help = '?'; SyntaxHighlighter.config.strings.alert = 'SyntaxHighlighter\n\n'; SyntaxHighlighter.config.strings.noBrush = 'Can\'t find brush for: '; SyntaxHighlighter.config.strings.brushNotHtmlScript = 'Brush wasn\'t configured for html-script option: '; SyntaxHighlighter.defaults['pad-line-numbers'] = false; SyntaxHighlighter.defaults['toolbar'] = false; SyntaxHighlighter.all(); // Infinite scroll support document.addEventListener( 'is.post-load', function () { SyntaxHighlighter.highlight(); } ); </script> <link crossorigin='anonymous' rel='stylesheet' id='all-css-0-2' href='https://s1.wp.com/_static/??-eJylj9sKwjAMhl/IGg/IvBEfRWobts60KU264ds7QYcg7EIv8/3kP8CYjeOkmBRiNZlqG5JAj5qtu5kJjdlxfAkQmdNbvAyYPBewVTla1eDmN0dWJDijHUY0HVLGAj6IQkHJnCQMaIbgkeWbrJ3ICpZ7fdaJ7CuhgLOFqyCBjGHKM9eaPOHfbvOmF/jVUAOhN60lwnJfup4B53jaNvum2R83h13/AAJGoGU=&cssminify=yes' type='text/css' media='all' /> <script type="text/javascript" src="https://s1.wp.com/wp-content/js/mobile-useragent-info.js?m=1609849039i&amp;ver=20241018" id="mobile-useragent-info-js" defer="defer" data-wp-strategy="defer"></script> <script type="text/javascript" id="custom-content-types-data-js-before"> /* <![CDATA[ */ var CUSTOM_CONTENT_TYPE__INITIAL_STATE; typeof CUSTOM_CONTENT_TYPE__INITIAL_STATE === "object" || (CUSTOM_CONTENT_TYPE__INITIAL_STATE = JSON.parse(decodeURIComponent("%7B%22active%22%3Atrue%2C%22over_ride%22%3Afalse%2C%22should_show_testimonials%22%3Atrue%2C%22should_show_portfolios%22%3Atrue%7D"))); /* ]]> */ </script> <script crossorigin='anonymous' type='text/javascript' src='https://s0.wp.com/_static/??-eJydj92qwkAMhF/oxKAFxQvxUQ51u9W02SQ0WX/e3hUUvPYmMEnmGwZvBkklsgSWCsb1TOI45bA+zW+NRVXwnyThqRIPSDKSUGTwtCjzRz9WhWQ1+R9+UeOSS3a0empvQ7bchgQ0zeSXvMAGJ0fpr3Tug/RHv89kwCQzjJqqw0j3H0Cvhq0SWcDNkpYPou25Ds3ckgbywGsz6/I6mfJjJOZ39WM5rHddt9tu9utuegK/poIq'></script> <script type="text/javascript" crossorigin='anonymous' src="https://s0.wp.com/wp-content/plugins/gutenberg-core/v20.0.2/build/hooks/index.min.js?m=1740004117i&amp;ver=84e753e2b66eb7028d38" id="wp-hooks-js"></script> <script type="text/javascript" crossorigin='anonymous' src="https://s0.wp.com/wp-content/plugins/gutenberg-core/v20.0.2/build/i18n/index.min.js?m=1740004117i&amp;ver=bd5a2533e717a1043151" id="wp-i18n-js"></script> <script type="text/javascript" id="wp-i18n-js-after"> /* <![CDATA[ */ wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } ); /* ]]> */ </script> <script type="text/javascript" id="jetpack-carousel-js-extra"> /* <![CDATA[ */ var jetpackSwiperLibraryPath = {"url":"https:\/\/s2.wp.com\/wp-content\/mu-plugins\/jetpack-plugin\/moon\/_inc\/build\/carousel\/swiper-bundle.min.js"}; var jetpackCarouselStrings = {"widths":[370,700,1000,1200,1400,2000],"is_logged_in":"","lang":"en","ajaxurl":"https:\/\/herbsutter.com\/wp-admin\/admin-ajax.php","nonce":"66316aba56","display_exif":"1","display_comments":"1","single_image_gallery":"1","single_image_gallery_media_file":"","background_color":"black","comment":"Comment","post_comment":"Post Comment","write_comment":"Write a Comment...","loading_comments":"Loading Comments...","image_label":"Open image in full-screen.","download_original":"View full size <span class=\"photo-size\">{0}<span class=\"photo-size-times\">\u00d7<\/span>{1}<\/span>","no_comment_text":"Please be sure to submit some text with your comment.","no_comment_email":"Please provide an email address to comment.","no_comment_author":"Please provide your name to comment.","comment_post_error":"Sorry, but there was an error posting your comment. Please try again later.","comment_approved":"Your comment was approved.","comment_unapproved":"Your comment is in moderation.","camera":"Camera","aperture":"Aperture","shutter_speed":"Shutter Speed","focal_length":"Focal Length","copyright":"Copyright","comment_registration":"0","require_name_email":"1","login_url":"https:\/\/herbsutter.wordpress.com\/wp-login.php?redirect_to=https%3A%2F%2Fherbsutter.com%2F2024%2F10%2F23%2Fpodcast-interview-rust-and-c%2F","blog_id":"3379246","meta_data":["camera","aperture","shutter_speed","focal_length","copyright"],"stats_query_args":"blog=3379246&v=wpcom&tz=-8&user_id=0&subd=herbsutter","is_public":"1"}; /* ]]> */ </script> <script crossorigin='anonymous' type='text/javascript' src='https://s2.wp.com/_static/??-eJx9jksOwjAMBS9EaqBCZYM4ShUci7okdlQn7fXponwkJLYzek8DS3aoUkgKpOpyrHcWg5FK9vhwK1oyatoEJFV5yX4mCTqBr0WTL4XxPcPozRhdGSiRGyhmmiCwFZjIsorxTG7mQGq/pBltB/+zvmt6FoRb5RgA/aTVKH46NtAklvX2mi6Hru269rw/HccnrbJeyw=='></script> <script type="text/javascript" crossorigin='anonymous' src="https://s0.wp.com/wp-content/mu-plugins/jetpack-plugin/moon/_inc/build/tiled-gallery/tiled-gallery/tiled-gallery.min.js?m=1725888675i&amp;ver=14.4-a.7" id="tiled-gallery-js" defer="defer" data-wp-strategy="defer"></script> <script crossorigin='anonymous' type='text/javascript' src='https://s0.wp.com/wp-content/mu-plugins/carousel-wpcom/carousel-wpcom.js?m=1620989527i'></script> <script type="text/javascript"> (function () { var wpcom_reblog = { source: 'toolbar', toggle_reblog_box_flair: function (obj_id, post_id) { // Go to site selector. This will redirect to their blog if they only have one. const postEndpoint = `https://wordpress.com/post`; // Ideally we would use the permalink here, but fortunately this will be replaced with the // post permalink in the editor. const originalURL = `${ document.location.href }?page_id=${ post_id }`; const url = postEndpoint + '?url=' + encodeURIComponent( originalURL ) + '&is_post_share=true' + '&v=5'; const redirect = function () { if ( ! window.open( url, '_blank' ) ) { location.href = url; } }; if ( /Firefox/.test( navigator.userAgent ) ) { setTimeout( redirect, 0 ); } else { redirect(); } }, }; window.wpcom_reblog = wpcom_reblog; })(); </script> <script type="text/javascript"> (function() { var extend = function(out) { out = out || {}; for (var i = 1; i < arguments.length; i++) { if (!arguments[i]) continue; for (var key in arguments[i]) { if (arguments[i].hasOwnProperty(key)) out[key] = arguments[i][key]; } } return out; }; extend( window.infiniteScroll.settings.scripts, ["jetpack-mu-wpcom-settings","rlt-proxy","wpcom-actionbar-placeholder","grofiles-cards","wpgroho","syntaxhighlighter-core","syntaxhighlighter-brush-cpp","mobile-useragent-info","custom-content-types-data","the-neverending-homepage","independent-publisher-2-navigation","independent-publisher-2-skip-link-focus-fix","independent-publisher-2-wpcom-functions","wp-polyfill","wp-hooks","wp-i18n","jetpack-responsive-videos","jetpack-carousel","tiled-gallery","carousel-wpcom"] ); extend( window.infiniteScroll.settings.styles, ["the-neverending-homepage","wp-block-library","wp-block-library-theme","jetpack-layout-grid","jetpack-ratings","mediaelement","wp-mediaelement","coblocks-frontend","wpcom-core-compat-playlist-styles","wpcom-bbpress2-staff-css","genericons","independent-publisher-2-style","independent-publisher-2-block-style","independent-publisher-2-wpcom-style","reblogging","geo-location-flair","a8c-global-print","h4-global","wp-emoji-styles","videopress-video-style","jetpack-sharing-buttons-style","classic-theme-styles","global-styles","akismet-widget-style","jetpack-global-styles-frontend-style","jetpack-responsive-videos","jetpack-carousel-swiper-css","jetpack-carousel","tiled-gallery","core-block-supports-duotone"] ); })(); </script> <span id="infinite-aria" aria-live="polite"></span> <script src="//stats.wp.com/w.js?68" defer></script> <script type="text/javascript"> _tkq = window._tkq || []; _stq = window._stq || []; _tkq.push(['storeContext', {'blog_id':'3379246','blog_tz':'-8','user_lang':'en','blog_lang':'en','user_id':'0'}]); _stq.push(['view', {'blog':'3379246','v':'wpcom','tz':'-8','user_id':'0','subd':'herbsutter'}]); _stq.push(['extra', {'crypt':'UE40eW5QN0p8M2Y/RE1mNzc2NTVTamdsd0xoLz9RQkM2K298TXY9bERQMXc2MjhEaVZfb2wwakRoSj0mUkp1THptM1NdbkV1WjZIcU9mVWQmPUIvMlN6Jk8wW3NYVEJ3dWZOWExuWD9CbmxqLENKeHZKRG9sOWtMPXxsPzZaPWE9UDdDckNaeEFMRTd6X01ITlUsWnlbaT9+ZDF4Y1MzK3VMNVJEdHppaXVrfjhBRFRfQTktMzdZRn53UVtUZEpvemtjK2RKdVpvSFkmaXlpTG9UfFRTR0VoWzZiZVV4TiY0JjVjPXY3WXZJUDJTcWNiVlhkejJSNjJVV1hyYW1yM0w4LDliP0N+eDl6OHJlSjBifmNrdmVybElmLzI1bEJ2b0NBRkFkZVpBbnZac19qck9tbDc2eF1GMw=='}]); _stq.push([ 'clickTrackerInit', '3379246', '0' ]); </script> <noscript><img src="https://pixel.wp.com/b.gif?v=noscript" style="height:1px;width:1px;overflow:hidden;position:absolute;bottom:1px;" alt="" /></noscript> <script defer id="bilmur" data-customproperties="{&quot;logged_in&quot;:&quot;0&quot;,&quot;wptheme&quot;:&quot;pub\/independent-publisher-2&quot;,&quot;wptheme_is_block&quot;:&quot;0&quot;}" data-provider="wordpress.com" data-service="simple" data-site-tz="Etc/GMT+8" src="/wp-content/js/bilmur-4.min.js?i=12&m=202509"></script><script> ( function() { function getMobileUserAgentInfo() { if ( typeof wpcom_mobile_user_agent_info === 'object' ) { wpcom_mobile_user_agent_info.init(); var mobileStatsQueryString = ''; if ( wpcom_mobile_user_agent_info.matchedPlatformName !== false ) { mobileStatsQueryString += '&x_' + 'mobile_platforms' + '=' + wpcom_mobile_user_agent_info.matchedPlatformName; } if ( wpcom_mobile_user_agent_info.matchedUserAgentName !== false ) { mobileStatsQueryString += '&x_' + 'mobile_devices' + '=' + wpcom_mobile_user_agent_info.matchedUserAgentName; } if ( wpcom_mobile_user_agent_info.isIPad() ) { mobileStatsQueryString += '&x_' + 'ipad_views' + '=' + 'views'; } if ( mobileStatsQueryString != '' ) { new Image().src = document.location.protocol + '//pixel.wp.com/g.gif?v=wpcom-no-pv' + mobileStatsQueryString + '&baba=' + Math.random(); } } } document.addEventListener( 'DOMContentLoaded', getMobileUserAgentInfo ); } )(); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10