What’s New in Compiler Explorer? 2024 Update - Matt Godbolt - C++Online 2024

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone one second hopefully I have now shared the correct screen for everyone fantastic all right um I have a lot of content to get through so I'm going to start fairly soon on I don't know what the uh the general delay has been but we're going to we're going to crack on so if you're interested in know learning what's new in compil Explorer you're in the right place place and if not there is another talk going on in another track and I'm seeing folks waving already so hello uh so yes we're going to talk about what's new in compiler Explorer and if I've got the focus in the right window then I be able to advance my slides okay I'm going to do through the medium of uh some background where I'm going to start uh with some just quick fire questions about the project so first of all what is compiler Explorer well if you're attending a meeting called what's new in compiler explor you probably know but just in case uh it is a website that lets you type in C++ code and other languages and see how the compiler outputs its assembly from that so as you type the compiler runs we show the assembly output and an awful lot more uh why why would you want to do this that's an excellent question uh so uh compile explorer came out of the need that I had um a number of years ago when I was trying to argue with my then lead developer about using some C++ 11 features uh he was very conservative about enabling new things worrying that they would slow down the code and at the time I was working for a trading company that Trading Company uh latency was really important so performance was key and so anything new was treated with suspicion probably correctly there are some rationals as to why uh but uh I was frustrated I wanted a use C++ 11 features like range fours and so I knocked up a tiny shell script to compile code and show like some Sy um slightly massaged output from the compiler by you know gripping out things that were unimportant and uh running it through C++ filt and I was able to show that the source code for a iterate over a vector um using you know the the old school ways of size T index equals zero index is less than size generated the exact same assembly output or very close to it as the uh range for which is perhaps of no surprise to us now many years on very equivalent but uh it was in it was an eye opener and I started running it interactively by putting it in a watch Loop and then having an editor in the other window and uh very quickly I thought this is this is cool this is probably more useful than uh than I thought so I knocked up a little website so anyway that's the backstory that's why it's really important for us back then although it's used for a lot of other reasons now when did this happen so this was in uh 2012 so I was working for a trading company as I said and within a couple of months we I got permission to open source this internal tool I'd made and on the 22nd of March 2012 uh the GitHub repo was created and compiler Explorer or GCC Explorer or interactive compiler even as it says here in the very first commit was born so you can actually check out the very first commit to the project and you can it still runs with a tiny bit of tweaking and it will show you something which looks like this uh it's probably somewhat familiar to to to you uh you can see that we have the left hand pane with the editor and the assembly output which is unfiltered it's got loads of junk in there that's probably not very interesting but we could choose a compiler and you could add in compiler options and things like that uh so back in 2012 we supported GCC and clang although it was called GCC Explorer uh it did in fact support clang from the from the outset uh at least the first public version did the GCC Explorer name kind of outlived its usefulness uh and so I renamed it to compiler Explorer which is a lot more um generic when we added more and more compilers and other things and I uh initially um hosted it on my own uh personal domain at gcc.org and many you know I call it compiler Explorer many other folks have decided to call it by the domain name that you're probably more familiar with but it's compiler Explorer at least to me anyway so 2012 we had GCC and clang it only supported C++ the output was unfiltered although actually that was one of the first things as we added filtering and probably the one and only thing that I thought of as being uh my contribution other than running other people's code is the syntax uh highlighting of the backgrounds that shows how the Source Code maps to the assembly output the sort of synchronized color background everything else is just me running other people's code uh the project was only 5,000 lines of JavaScript it was just me and my I it was self-funded my wife was happy enough for me to spend a few uh100 here and there to keep the thing afloat fast forward 12 years and we are now at 2,800 compilers more than 2,800 compilers although In fairness some of those are double counted we count GC both as a c compiler and a C++ compiler but even if conservatively we've got like 1,400 unique compilers we support 65 languages we have filters we have tools we have diffs we have idas we have all sorts of things which I'll show you in a minute it's now 90,000 lines of typescript typescript is a typ safe version of JavaScript which means to say it's not really all that typ type safe and it needs to be compiled so it kind of gets all of the worst things of C++ like like slow compiles and all of the worst things of something which doesn't really have types but it's still better than pure JavaScript uh and I'm very very pleased to say that I have an amazing team of folks who help run the site who do most of the work and who um uh are pretty much the only yeah reason that the site keeps going is is the volunteers I I'm here to pay the bills and sort of vaguely project manage things um these days and we also have loads and loads of contribut who who um come in and help like update compilers and things like that uh and I'm glad to say I don't actually foot the bill myself the um the bill is is covered and more that more so um by some patrons that I have and some commercial sponsors who um support the site so a huge thanks to both my team and my anyone who supports the site financially it really is far too much for me to be able to do by myself these days on all those axes how how is it working or how does it work um this is a simplified diagram of what goes on behind the scenes each one of these like boxes is either a computer or a set of computers or a service and the intention here is not for you to look at it and not for me to go through this because you're not really had a talk called how does compiler Explorer work but it is it has grown and grown and grown and we have Linux machines Windows machines machines that have gpus we have uh external access to uh uh Microsoft where they run some of the compilers for us we have a staging instance we have a lot of infrastructure so I'm very very pleased again to have the support of um lots of people to help me with all of this and who this is not who makes it this is who is using the site um developers probably most of the folks who are watching this are developers uh I use it in my day-to-day life it's a real great way of not only seeing how the compiler works but just testing out ideas it's quick to to to compile small Snippets of code I can pick loads of different comp ones that I don't have installed I can run some of the tooling that we've got there that's is more convenient um than running it locally which is actually kind of a an argument that our tooling needs to improve across the board if you if it's easier to send your source code across the other side of the world to someone else's server and then have it sent back to you than it is to run it locally then maybe we should be looking at our tooling but that's a different topic of conversation so developers use it for all sorts of things trainers and universities uh use the site so that it's a very convenient way of demonstrating parts of the language without showing uh lots of awkward things like how I complicated Ides or make files or uh running command lines from the client um it also means that at University you can have a room full of students and say just hit this URL and off you go um that is um a lot more convenient than trying to get everybody set up it's certainly for an introduction to programming course and also some of the tooling that we we have is very very convenient if you're trying to learn how compilers work behind the scenes and we'll see some of those later on I also know that security researchers have used the site um I had a few people ask if they can train their AI to detect particular code Snippets by sending um like known vulnerable bits of source code through all the different compilers we support and I'm not sure how that came out but I said that they were fine to do it we have an API that they can use and I'm really pleased to say that compiler authors use the site um to both reproduce bugs or have folks who uh uh um report bugs use uh compiler explor to show that it's like not just a problem on their computer uh and that means that the the compilers themselves are improving because of compil Explorer and that is wonderful um I mean not just because obviously but it's part of part of the the ecosystem that helps uh compilers improve which actually ultimately benefits me in my day job uh the back so there's a question about the backstory of why msvc output execution has gotten removed we can talk about that after I'll get to that if you want to hang out in gather town we'll we'll chat there so the way that I want to talk about what's new in compiler Explorer is through the lens of different people who might want to use the site so I've invented some people and their theoretical use cases and then I'll sort of like show the recommendations that I would have for them to be able to get the most out of the site and what it what it can do and that will cover some of the things you've probably seen before but also some things that are new and even if you think you've used a lot of the site you'll probably see something novel in here yourself the first person we're going to talk about is Jordan Jordan is a highfrequency Trader and has been um in the similar situation that I was uh when I invented the site so he's sort of more focused on the performance and he wants to be able to show his team that certain C++ idioms are in fact more performant or at least as performant as doing it like the old way or the difficult way um and that you should be able to trust the compiler to do things for you rather than um write it all out long hand so we're going to start with an example here I'm going to click here and hope that this also shows up paray so I am using the Dark theme if you haven't noticed uh up here in the settings more and settings you can pick uh the theme of the of the system that we put a number of different themes I've picked same as system and everything's dark on my system so if it looks unfamiliar to you if you're used to seeing it look like this it's because I am using a system theme that makes it dark and I'm actually going to turn on the dark rainbow line highlighting color scheme so we've got a slightly different thing hopefully if this is awful to see by the way please put something in the chat and I will change to the light light um um style uh so this is the site right we um uh we're going to show um a piece of code that Jordan maybe has in his code base right now which for whatever important trading reason he wants to sum an array and the array has been given and this actually already hurts me that I've forgotten to do this uh that should be a con Point AR right and it probably should be a span or something called like this but let's just assume Jordan has an array and a number of things that go into the array and he's has to return the uh the sum of the things that are in the array and that we're not going to worry about overflow or anything like that so um this is the old way of doing it there is a much nicer way of doing it down here using standard accumulate um but we want show that we can use this because Jordan's lead programmer is very conservative and thinks that the in some old school way is probably better or faster or whatever so how might we do this with compiler Explorer so the first thing that I'm going to do is the I I could just switch back and forth between these two implementations or I could have a hash Define between the two of them that toggles it back and forth but I'm actually going to open up some more windows and I'm going to do some comparisons between them sort of side by side the way that I'm going to do this is I'm going to remember that I'm on a Mac at the last minute and the keyboard shortcuts are all different so bear with me a second I'm going to copy the code and remove this from here and I'm going to add a new source editor plop it down here so this is another copy of the editor I'm just make this 22 as well I'll paste in whoops again you'll see me typing Mac related things that are comment that in and delete that so in this bottom one I have the standard accumulate version in the top one I've got the old school version now at the moment we've still only got one compiler over here so this is currently compiling this is a little small uh but it tells us that it's GTC blah but editor number one editor number one is this top one so I can add a new compiler to the bottom and I'm going to click and drag and incidentally uh when you when you click on these things you can actually just hold the mouse down and then that lets you choose where the output is going to go so I'm going to put it down here and I'm going to steal the same oops again with the the keyboard shortcuts uh I'm going to paste that in here and I'm going to Output this to be also 22 and so we've got the output of uh the two programs here and that's kind of useful I guess I could scroll up and down and look and see if they look the same or different um I could actually put them side by side so one thing uh that maybe you didn't know is that um this is a fully tabbed sort of um Window Manager I can grab this uh um window and plop it so that it's like a tab next to its own source code and I could do the same for the one down here and now I could drag this whole window up so let's do it like this and then put that next to it um and so I've got the source code in one Tab and I've got its compilation in another and that means I can have the the the assembly code side by side uh uh yes um yeah also in gather Town absolutely for for how the short links work be delighted to explain that so they look kind of similar to me on both sides and that's kind of okay I could sort of squint a little bit but what we can actually do is we can add a whole new view from this very top level excuse me I'm going to add a difference view I'm going to just plunk it in the middle and I'm going to use another um button up here so again it being a window manager means we have a maximize and minimize button so I'm going to maximize this those other windows are behind this now and this is a difference between the two and let's just quickly Zoom that in um by default it actually picks the same thing obviously there's no difference between these two um um outputs but if I pick the second the right hand side as being editor and compiler number two we now get an actual side by-side diff and you can see that there is a slight change in the number of instructions um from left to right and number of instructions isn't always a good example of whether something is faster or slower but it's interesting right it's something to look into um but I know that for large arrays the thing that's going to M matter most is the inner loop and I happen to know where that inner loop is and it's down here at L4 and so if I compare lines 15 and um through what is that 15 through 19 on this side with uh 19 through 23 on the other they look very very similar and in fact the only real difference is that a different register here this R DX versus R CX so they're essentially identical and that might be enough for me to go to my boss and say there's a little bit of change either side of it but the core Loop is identical it's the same instructions give or take a register allocation which is different which should have no impact on the performance so that's pretty cool now what we can actually do is go one further I'm going to now pick up that code and I've now got it in my clipboard and I'm going to close down one of these P you down and I'm going to change this to be an analysis window so you can pick a different language we've got many languages in here one of them is analysis which isn't a real language but it lets you put assembly code in and then run an analyzer on it so I'm going to paste the snippet that I got into this window and then add a compiler which I shouldn't have closed I'm going to pick the analyzer llvm MCA which is the llvm projects machine code analyzer uh Osaka is another one in here and there's there are other ones available but this is the one I know the most and again I would just zoom this into 22 and what this does is it does a kind of simulation of the code assuming it's in a loop and does 100 iterations of that Loop by default and it says if I were to run this code on some synthesized um simulator of an x86 and I did 100 iterations then it would be 400 instructions that figures there are four instructions here four times uh 100 is 400 but it would only take 110 machine cycles and it does that through this analysis that you can drill into here we can actually also tell it to do Dash timeline if I could type timeline and it will show a timeline down here of the instructions and where they are in the in the pipeline all sorts of clever stuff now I haven't got time to go into details here but this is a really cool way of say showing that this would be um I don't know why it's gone up to 143 Cycles now never Chang things while we're going that's really interesting the putting timeline and actually changed it oh well um something's going on behind the scenes there um but anyway this is a great way of being able to take this and and go and say not only can I show that the code is equivalent to you standard accumulate to using um a regular int based Loop but I can actually tell you how long it should take now now this doesn't take into account cash and all that kind of stuff like that but it's it's it's demonstrating another feature that we have here so I'm going to go back now um yes analysis View and so that's one way that you could show that uh modern compilers are great at generating the kind of output that we that we want uh another thing that we might want to do is is so um the compiler ability to inline H so this is a bug bear of mine so you you might start to realize that the Jordan is kind of me really so I'm going to open a new tab and I'm going to go to compile Explorer and I'm going to reset I'm going to go up here and going to reset code and UI layout so I'm going to from scratch so wish me luck if I remember how to do this I'm going to try and demonstrate um inlining except I'm going to show that inlining across translation units is possible with modern compilers so one thing that uh you may do is for very high performance code or for reason other reasons you might put the implementation of all your functions into the header files so that they're available to all other translation units and they can be inlined and that's great um it's an important thing to be able to do but it's not very good if you need to change that implementation because if you change that implement ation your entire project has to rebuild because you've just touched one of the header files that's important so it's nice to be able to hide away the implementation in the CPP file in the translation unit um but you're now giving up the ability of the compiler to in line across those translation units except modern compilers can actually do this and so if I wanted to demonstrate to my boss that it would be okay to pull things out of header files where we appropriate um um I would want to do something like we're going to do now so I am going to use this square example you've all seen a 100 times before I am going to add a new source editor over here and this Source editor does not inherit the size unfortunately and I'm going to assume that on the on the left hand side this is like the implementation file and on the right hand side this is like some main program so I because I'm not going to do headers I'm just going to say there exists a function called Square and if I could type it would help it takes an integer num and I'm not going to Define it I'm only declaring Shing it here now this is just because I don't have time to do all of the header bar inclusion stuff and then my main function is going to be returning the square of 10 okay so nothing is compiling at the moment because I don't have a compiler and if I were to actually add a compiler it would compile each file individually which wouldn't work in this instance that we would see that there would be a link error if we tried to link it or it would definitely not be able to inline Square because it doesn't know what square is there are two independent compilations but new and awesome feature that we have is to be able to have a tree or IDE mode and let's snap this to the side here and now you can see that we have uh a little bit more of a traditional um uh IDE kind of view where on the left hand side we can see all of the windows that we've got open and um we can actually join them to a build and in fact by hitting either this plus button here or by hitting contr s to save which I'm going to do over here I'm going to save this file as Square whoops Square square. CPP and you'll notice it's appeared in this included files over here on the left and this file over here I'm going to save as please work save oh there oh I'm pressing wrong key again I had to switched to a Mac at last minute because my Linux machine wasn't working uh main but CPP and now they're both in the build and then for the purposes of what I would like to do I'm going to use cmake to build both of these things together and then link them so I'm going to take the cmate build box here and I'm going to say that it's going to output something called uh let's call it Square um but now I need to see make lists so let's add a new source editor and and this one I'm going to save immediately and I'm going to save it as cmakelists.txt and this is what I have to hope and you'll notice it's changed the type to cmake up here so this is Project we're going to call it square square square add executable square and it's going to be square. CPP and main.cpp all right nothing is happening yet though and we're going to 22 this one so you can actually read it okay uh I'm going to stack all these things up together so that all of the um the three Tabs are here and now I'm going to add a compiler but I'm going to add the compiler to the IDE window which means that it will compile the entire project so I'm going to pick up this compiler I'm going to drag it over here this chap was going to be smaller and this one is going to be 22 and so what we've got now is the entire program so first of all we're building an entire program in fact if I open the output window down here you can see there's cmake doing all of the cmake things that we love we know and love it's doing detecting it's building two different programs here sorry files square. CPP main.cpp and it has linked it and then it's disassembled it over here so so that's pretty cool and again like all my um source code are in these three tabs here uh let's take a look uh on the right hand side nothing particularly exciting happen let's turn the optimizer on I know we've got cmake build type equals debug over there but I can override it by putting O2 in here and then we can see that um Square the function Square over here is just doing an imol exactly as we'd expect it takes the input multiplies it with itself and then returns it in eax great and then we look at Main and Main says exactly as we've asked it to do uh put 10 which is nor XA if you Mouse over nor XA you can see it says 10 at the top there and we get all of the various different interpretations of what that might be 10 is a is some crazy floating Point number um but then it just jumps to the square which means it hasn't inline that function because if it had inlined that function we would hope that it would be smarter than actually doing the multiply operation so now we finally having done all this setup work have got to this the point where we can demonstrate that if we turn turn on FL lto for link time optimization and hope that it works we can see that now Maine has in fact inlined the square function and has output norx 64 which is indeed the 100 that we would expect so this is a way of using the IDE mode to build an entire project and show that project level settings can take effect cool all right let's move back to the presentation and oh whoops yes aha this is I knew I should do this type of thing let me bring the uh window back I'm glad I have my notes so I didn't look at them so you may be thinking to yourself that's great Matt there's a lot of things there there's a lot of Windows I have to move around it just took you 10 minutes to demonstrate this to us um how on Earth am I going to remember how to do all of those things well I have good news for you I'm going to actually reset the code and UI layout so we're back to good oldfashioned default output and I'm going to show you that we have these things called templates if you click up here this these templates uh do not have uh 1,000 line error messages they have nice pictures and what these templates are are a way of getting the site into a particular configuration conveniently so we've got these preand diffs of two sources which shows you know differencing the output of two sources much like I did earlier we've got two compiler outputs being different we've got a C++ cmake example and so I'm going to click this C++ cmake and you get dropped into a version which shows all of the features I just discussed and more this actually has some files that are inside the uh the output that you can open up as a file so like this resources hello.txt here it says hello world and you'll see the output of the program down here is actually reading that file so we actually upload all of the resources and let your program run on those resources if you need to it's also showing some Library functionality that we'll cover in a second so um there's a lot of um cool features here that are are preone so you can bring up the Ada ID if you want to go and see what Ada looks like and you can actually save your own um templates as you know my cor template here and then you can come back to it now you can of course bookmark a short URL U if you go up to the top here and do a short link and you copy that to the clipboard or if you bring it up here you can you can uh copy this and that's another way of getting similar functionality the templates themselves are saved in your browser storage so if you are one of those people who clear their browser storage regularly you probably want to just have um some some short links saved but it's not a bad way to get started or even just explore what we can do and some of the other things that you maybe know didn't know that we can that we supported all right did we go through all those things I think we did good all right that's Jordan let's talk about Mason Mason's another user of the site Mason works for a local community college and has a YouTube channel and they spend a lot of their time um trying to bring uh the Delights of programming to the masses be they folks who are already interested in it people who don't really know much about programming at all or folks who are trying to dig more and more into the the world of what goes on behind the scenes so what kind of things might you do if you were a trainer like this well the first thing obviously is teaching so what you might do is hand out a short link such as I've just clicked on to your uh students and say hey um I would like you to fill in this function here I've given you a function which is bull contains zero and it's given a reference to a vector of integers and I want you to return true or false depending on whether or not uh there is a zero in that array of integers that Vector of integers and you know if you're old like me you'd start doing something like four Auto X and excuse my short things um variable names here uh if x is equal to zero return true return false right that's a way of doing it and you can see the code is generating on the right hand side and we're going to take we're going to ignore that now but you know this is not the right way to do things these days there are better ways of doing this um so what if I were to do return uh stood uh ranges contains B comma 0 is that the right one no it's find sorry ha see I can remember this find B comma 0 is not equal to stood n of B okay well we've got a problem here because it says there's no member named uh ranges in namespace stood so let's include include range is it range or ranges I can never remember ranges okay well even though we included ranges it's telling me and it didn't go wrong with that it's telling me there's no member named ranges in nam space stood and that's because our compiler needs to be told to enable all of the cool new features that C++ 2A or 23 or whichever one it is um uh needs to in order to see this ranges even though the file is physically present um now I could fiddle around up here and try and work out what the right command line flag is but I'm not even sure what it is so how would how do I how might I go from here well we have a new feature called overrides and if we click the overrides button here which has this little tool next to it um we can configure the compiler in a a a new way um one thing we can do is we can add compiler environment variables this is not so important for C++ I don't think there are many C++ compilers that care about um environment variables when they're compiling but there are other languages that do but we also PA a subset of the mline parameters of the current compiler and we pull out for example all of its supported Target architectures and we can now see that clang support all of these different kinds of architectures and if I tick one of these it would put the right command line flag on to turn that architecture on we can change which tool chain this clang is um looking at if you might know by default clang um on Linux at least uses gcc's um C++ library in order to be ABI compatible with the other programs on the system but you can pick which version of GCC we choose one for you we choose the latest one but if you need to pick another version you can go through the thousands and thousands of possible combinations of other um gcc's that we have available and more importantly for what we're doing right now we pass out all of the supported standards and so I think I want probably C++ to be the working draft for ISO C C++ 2023 bis whatever that is I'm going to click that and then behind the scenes When I close this window we have to hope that it now compiles hooray so now we have a working compiled version of the code and that's awesome um we don't know if it's right or not um but right now um we're um we're sort of faced with this assembly output which is a little bit scary um so we're going to talk a little bit about the assembly and then we're going to get rid of the assembly because when you're trying to teach folks then um you're you probably don't want to be pointing them straight at assembly I mean I probably would but that's that's just me so before we move away from the assembly view there's a couple of things I want to show um first of all even if you don't know what half these instructions are you can Mouse over them and for x86 and for I believe arm and coming soon um some of the risk five I think um we we have support for passing out the um manuals for these things and so you can Mouse over it and see that this is what the instruction does sets the destination oper to 01 depending on uh you can also right click and go to view assembly documentation where we get more information and ultimately you can click on this to go to the website where we we we scrape um so that's one thing and then another thing is that some people are more visual Learners um and we have a way of showing the output um from this so um up here we've got these two different things we've got add new and add tool add new here um it adds a new thing which kind of plugs into the current compiler so these are all to do with the current compiler or very close to the compiler whereas adding a tool add something which runs on the output of the compiler after the compiler is finished or is independent of the compiler so that's why we separate these two things I realize it can be confusing so I'm going to add a new control flow graph and I'm going to plunk it down here and then I'm actually going to maximize it and then I'm going to reset the view and I zoom around a bit and what this is another way of showing the output from the compiler um and this is showing the control flow so we can see each basic block each set of instructions that run from beginning to end without any jumps and then at the end of each basic block there are two or one or two outs one is the if the branch is taken one if the branch is not taken so we can kind of see the flow here if we were to follow the red arrows we would be falling into the loop and then this is it falling into the uh the comparison and then if it went through the green line here that's it looping back around to the top and so you can kind of get some a view of like what's going on and if you even if you don't fully understand what all the instructions are doing this is another um way of visualizing the same thing so let me close that and go back to this again um we can run the code these days like I think we showed um I can execute this code and it would tell me oh it's not there's no main I'd have to write a test so luckily here's one I prepared earlier I'm going to go to execution so now we've got this bull has zero and I've you know use the stood span now because that's a lot better um and it's using rang is find up here and I've written this little main function here um and it's not again not that useful to see all of this assembly output especially now we've got like trying to print out stuff in here so I'm going to turn this output over here this this window into an Executor which you know we can tick the execution button down here but I'm not interested in this assembly View and I want to have more control over the output and the way that we've tried to do this is instead of ramming all of the functionality that you want when you're executing your code into the same window as this assembly view is that we've created a new view entirely that view can excuse me that view can either come from you adding a new execution only view on the on the left hand side here or on the right hand side you can say I want this view but as an executor and so I'm going to add a new executor from this and I'm going to drag it up to there close the other one so now and as always we've forgotten the size um we're just compiling and running the program we're not showing you the disassembly that's that's not very useful um but um you know uh here it looks like it's working my my little test case here that has a vector of you know 0 1 two three one two4 zero in fact um has a a zero is true and then if I were to get rid of the zero over here um it would compile it would have a think about it and it would say false okay but that's not very satisfying because as you can see here I've totally punted on actually printing out the vector which would be a nice thing to do right um I would love to use stood print here and all the good stuff stuff that comes with it but it's not supported in GCC 13.1 which is the the version I've used here but I do know where I can get it from fmt so I could include whoops include format or fmt for format. H um but there's no such file directory because I haven't got format H but it would be really cool if I could get access to it right luckily we have some libraries available and by some I mean quite a lot um so if you click the little library book uh button over here which will look like a book if you haven't got space on your screen this popup will will appear and you can see we have many many many many many many many libraries um the vast majority of them are um header only but there's still a substantial number for which we will build and allow you to link against two and I'm going to search in here for format and here is uh results for fmt and I'm going to say I want the 10.2.1 version of format and now that's available on my path I'm also going to hit the star here and it's remembered as a favorite so that I can come back to this a lot quicker again this is stored in the browser and if I was on my laptop uh my uh non-mac laptop I would have been a had some of these things set up so to demonstrate but I'm but I'm not so there's format 1021 um incidentally you can do the same with compilers you can make compiler's favorite so I can tick the box here that makes GCC 13.1 a favorite and now it'll always be at the very very top along with all the other favorites that I have uh but uh now we've got format available let's quickly uh do fmt print and what do we need to do say we want to say vector and then we need to do two of those because we have to escape them as a zero question mark Splat Splat and then what do we need to pass it uh we need to say um fmt join I with I don't know comma and then uh has zero oh I need to slash n on there don't know as well has zero I right let's get rid of the stood SE out and see if I've been able to type correctly uh what have I missed out here uh no it worked Ray gri grief few just took a moment and so now we're actually seeing Vector 1 2 3 40 has a zero true and I'm sure there are much better ways of doing this of course we can get rid of the one two three four and it'll say has a zero false hopefully in a few seconds time and of course if we really want to do this properly I could go in here and let's look at something like catch two and I could actually use catch two and write actual unit test to fail correctly and have nice outputs um yes let me just quickly check my list of things yes okay we've done everything I think now where I'm looking at the time and I'm thinking gosh this is going awfully quickly so um let's uh let's change Tac a little bit and so as well as showing that just actually how to program in C++ um there are other aspects of the site that are interesting if you're trying to teach mlight how things work behind the scenes so let's have a look at linking so this is something that I do quite a lot is that um in fact you saw it earlier I will sometimes use extern in some function and then I'll call that function even though it's not defined anywhere and that's really useful for like just saying it's not important right now what that function does I just want to have the code for something that doesn't exist but um you can see that we output this uh this text on the right hand side but it'd be interesting to see what it looks like to to to get the binary output of this um this function even though it's not linked now the way that we used to do this is um we had this thing called uh um compiled to Binary or something um actually I forget what it used to be but it was the equivalent of this link to Binary Option and if I click it here you get the please hold you get the error that you'd expect you know we're trying to build an executable and then disassemble it and it's got an undefined reference to some function fair enough but if you're trying to teach how um linkers work or how operating systems um conspire with linkers to to to to get all of the symbols found it's useful to be able to look at the O file and so we now support this compil to Binary object which does exactly that so if I compile to Binary object we will compile and show you all of the op codes you know 4883 ec8 apparently is sub r RP Comm R great um and you'll see that there is the calls to functions that don't exist yet and we get to see a little bit behind the curtains in how this stuff works behind the scenes so um you'll see that it says call nine well nine is the next instruction one excuse me nine is the next instruction which is not true right we're not calling the next instruction we're calling some function but the reason it says call 9 is because in x86 the call instruction has a relative um address and the the address is relative to the beginning of the next instruction and at the moment we don't know where that function is we haven't linked it yet and so the instruction is actually E8 for call and then o four bytes of zero saying that there's a 32-bit offset here that I don't know where it is yet and by default obviously that will mean an offset of zero which means the next instruction but we also passed the output of uh some of the symbol table and inside that symbol table is a reference to the Linker to say hey please find something called sum function and when you do find it the sum function here get its address minus 4 and poke it in at address number five and so this R x86 64 PLT 32 thing is an instruction to the Linker to do this work and so it will come along and it will replace these four zero bytes with the actual offset to the function that you want to call and so that way we can show and Mason could show their students that this is what the Linker is going to do behind the scenes and we can go a little bit further than that even I can add a tool and all of the familiar Unix tools like NM which R the symbol table can be run on the output fact if I zoom this in here here it is with you know showing that there is an undefined reference toore z12 or z12 gosh until I've been in the America too longcore z12 some function V I can still pass command line arguments I can click this and I'm I can do- C which means Dem mangle and you see that yes it's an undefined reference to some function and we've got a number of things here we've got coverage we've got uh read elf strings and other things that you might be interested in seeing um but again we're running short on time so I'm going to zoom on to the next thing so that's linking and running some of the tools um if you're teaching anyone how to program these days I think you should tell them about static analyzers and so uh this is an example of me running a static analyzer um so I will run a tidy here so this is a piece of code it's just made up this is obviously not a very good example of how you should validate a user but you know assuming that we can get the hash of the password that they supplied us and look it up um this is completely okay code but if you're looking at it like I look at it you're probably starting to Twitch there's something that's not quite right um if I were to add a whoops add a tool um PL tidy and I'll add it down here and get rid of you oh I really need you actually hang on there we are okay uh and then I forgotten how to use it so I'm actually just going to run it with D- here and it is D- checks equals that's right okay so Das D checks equals and I happen to know the thing that I you can enable thousands and thousands of checks and it will be too much for us to look at it because every single piece of code has hundreds of checks but if I say per star it will enable all of the performance checks which is the ones I'm interested in and then you can see here that it's saying hey look you should probably pass these by reference because they're only copied and all you're doing is copying the data twice unnecessarily which is perhaps what all of you are shouting at your screens right now why the heck is this not const string amp and so clang tidy has your back here and there are hundreds and hundreds of other really useful warnings that clang tidy can provide for your code and so as a trainer you would want to be able to demonstrate that too very quickly we also have some commercial tooling so one of our sponsors sonar um let us run uh their um uh their linter and this is an example that I found from their is I haven't got time to go into it but this is how to misuse Concepts you're not actually using the concepts you think you are if you're doing it this way which you can have a laugh at later if you want look at the slides to see what it is but if I add sonar as a tool here uh you'll see that sonar will pretty quickly tell us that these two things here the stood as integral stood as same that's not how that works is what it's saying in a very long-winded way it's saying these are unevaluated this should probably be something like that I think if I remember rightly off the top of my head whoops I could actually type code and look at my keyboard at the same time is it going to work uh no okay uh no it's not even required it's just equals that right please hold yes so it's now only complaining about the second thing so anyway that's that's sonar okay so that's Mason that's training what we show we went through the assembly tool tips I showed you the control flow graph I showed you some of the binary tools we looked at the overrides which lets you set all of those extra fancy things um there's an equivalent also for executing the code I should have showed that as well um but you can set environment variables and other flags for the the execution environment oh in fact no there is I will go back to that hang on let's go back to that quickly because it's too cool not to show so let's go back to execution and if I turn this output no where are I gosh add new executor from this this is where I've gone off topic uh if I go to the runtime tools we can actually turn on Heap tracking and I can actually turn on a graph of the Heap now this is not a very exciting example because we don't really allocate anything but now when we run the program we run it with heat track and there's a little button that pops up here and then this is too small to see on the Monitor and I can't find a zooming in button on my screen right now but you get the idea that it pops up a view where you can look at where allocations are happening and um we we have some other things I've got it where is it on my list here we've got a Time Trace in in one of the other um compilation things but unfortunately I don't have a slide for that um anyway so yes we have overrides we've got static analyzers I've shown you how you can do execution only and that we have lots of libraries there was a question earlier um which libraries do we select to support whoever sends us a PR um gets it we've made this the process as easy as we can it's not I won't say that it is easy um but it is entirely possible for individual Library authors to send us a PLL request in a couple of repositories and that will get the library installed and available on the site usually within a couple of days see people are typing I'll try and get to those questions as I go but otherwise we'll have to wait till gather town because we've got 13 minutes left and I've got more more more slides to go through so let's talk about oh should add a tip of the day window that's a great idea actually that's a fantastic idea just mentioned in the chat right one second right so Joanna let's talk about Joanna Joanna is one of those developers that loves to I'm going to say misuse but let's say use use the compiler features um in ways that no one else has ever thought of before there are um so she's she's always trying to find these new and exciting ways to um compile C++ to get things that you didn't think you could do in C++ done and she's also really interested in the kind of optimizations that compilers do she's essentially a compiler uh adjacent person um and she has a very cute dog and uh let's have a look at what the kind of things that compiler Explorer can help somebody like Joanna so um I haven't got like one of the more complicated things that Joanna probably would work at and most people would know about this particular issue anyway uh but here for example is um the the c++'s most vexing pause so if you are torturing the language and trying to get the the uh the weirdest things to compile you might hit things like this it's not a very good example but it's an example nonetheless and so what this is is um I'm trying to cast this as an INT you know I'm doing int of f that's being you know cast F to an INT in a terrible way and then I'm assigning it to this int as int and then I'm returning it but that's not what's happening you know actually compilers will tell you if I Mouse over this it says you know hey it was disambiguated as a function declaration which is a bit of a hint but um yes there's no conference without have this uh but you know it might be interesting to see how this comes about one of the things that we do is we support introspection into clangs abstract syntax tree so if you have a clang compiler selected you can add a new as I'm add the where am I'm going to put I'm going put it down here right and I'm going to zoom it in because of course I haven't got my default set my mouse will works there we are 22 and so what we've got here is an internal representation of clangs abstract syntax tree which is hard to say and as you can see just just like any other window as I Mouse over it the different parts of the expression I like where they came from in the source code and so what we can see here is this whole program has been trans um passed as a translation unit which is a function declaration makes sense of which has a parameter value which makes sense and it has a compound statement yep yep so far so good and then it has a declaration statement ah well that's not what I meant at all I wanted to Define a variable here and it says it's a function declaration and so this kind of explains a little bit about c++'s most vexing pause um and certainly gives you some way of introspecting into what the heck is going on inside the the paa obviously we have to fix it there are much better ways of doing this obviously but let's just fix it because it hurts me to look at it and there we are oh they're still complaining about that oh no there it has in fact finished and now it pauses it's fine and it has in fact been uh passed as a variable declaration with an initializer list and all sorts of complic stuff going on there so that's the first thing that we could use this um approach uh for and if I could use find the back key that would help so pausing check we can go and look at the internal state of the compiler and um and maybe infer why our esoteric Edge case of C++ isn't compiling the way we thought it should do maybe find a bug another thing and now this is where again all of these people um are different sort of parts of my personality as much as they are any other real person um we might want to look into the internals of a compiler now this is just my absolute favoritest thing ever about what compilers can do these days and so no talk would be uh good without mentioning something smart that compilers do so imagine for whatever reason you wanted to know how many one bits there were in this value this 64-bit value here you might write code such as I have written here which is to say we start with a count of zero while our input value is still nonzero we know that there's at least one bit set so I'm going to increment the number of bits set and then I'm going to use this cool trick it's one neat trick for clearing the bottom set bit is the first bit counting from the bottom that is currently set we're going to clear it and then we're going to go around and we just keep going around until there are no more one bits left and then however many times we had to clear a bit was how many bits there were set right and so that's pretty cool and all but if you look on the right hand side it has been completely replaced with a single instruction pop count there is an instruction in x86 that does this operation and the compiler is smart enough to read my code which has a loop in it and determine that it is in fact a single instruction we're not going to talk about the C move that's a whole other talk but let's just assume for the moment that it's just this pop count and again we can Mouse over and see this instruction calculates the number of bits set to one hooray but how did it achieve this masterpiece how how might we find out well one way to do this is to look at the optimization pipeline so again this is for llbm we could deep inspection introspection excuse me of what's going on inside llvm I'm going to put this window here and it's going to tell me error which it shouldn't do I'll few is never do live demos and this is a whole live demo I'm going to maximize it so it takes up the whole screen so again what we what we had it before is behind this window and I'm going to zoom this into 22 because 22 is the magic number what we're looking at here is the one and only function that's defined in this file and we're looking at a full report of everything the compiler did to the code on the left hand side is a list of all of the different function passes that uh that the clang uh Optimizer did and there are lots and lots and lots and lots of them as you can see there's literally hundreds of passes and what generally happens inside a compiler is that there is an inter intermediate representation of your program in clang it's llvm this is the lowlevel virtual machine which is what you can see on the screen behind me behind me behind in front of you in fact and each pass makes some kind of small change to improve the performance or to annotate the code or whatever and that's what's happening on this left hand side here what we do is we highlight in green any of the passes that actually change the code and then this is actually a difference view so if I C click on this Sr a pass which is the Scala replacement of aggregate pass I just happened to know we can see that the code changes quite a lot I'm going to zoom out a tiny bit so we've got a little hope of seeing a bit more maybe that's still big enough but you can see some big changes happen a lot of stuff moved from the left hand side and changed to the right hand side some FES got added or fees some people could say fee um and so on and anyway this is if you were a compiler author you would know what all of these things do and you can click on them all and look at the various differences that are happening you know something happened there and then you scroll and scroll and scroll and if you're an interested person like I am you would take the time to click around these until you eventually get to the pass called Loop deletion pass you'd click on that and you would see that on the left hand side there is a while loop wild body all this kind of nonsense and on the right hand side that Loop has been deleted the labels haven't been but the loop itself has been deleted and replace with this call to llvm doct poop. I64 which is the internal way of saying hey the loop deletion pass has determined that there is a built-in magical function which maps to an instruction in this count case that actually does the work of this 64-bit population count and that's marvelous now I can go and Google I can go and find the loop deletion pass I can go and find the code and you can go and see how it's done which is really clever so um that is we we're hoping to get more we've got similar things for GCC um but we haven't got them quite as as to the same level of um of uh finesse but um nonetheless you can have a look at the compiler internals uh very quickly as we're down to the last few minutes here one of the other things you might do if you're into like all these template tricks and all these other bits and pieces is to actually want to compile your code like the stood ranges find on many many many different compilers to see which ones actually support the thing that you're doing so I'm going to close the um compiler here and I'm going to add something that is the conformance view and what the conformance view basically is is me to select lots of different compilers and paste in all of the um flags that I had and unfortunately I don't have a lot of time at the moment let me just turn on I'm picking random compilers here as you can tell and every time I change anything in the code I can add up I think there's couple of dozen of these things here so that won't work obviously so like this doesn't work on AVR GCC it's doing the compile I can look at the error messages I can open a tad that just has that compiler in it uh the red that means that it failed the green means that it succeeded the Amber means that we're warning things and so you can fiddle around with your code to your heart's content and obviously if I if I break it on purpose by typing rubbish into it they'll all fail um so this is a great way of trying out code on lots of compilers and of course you can um set up one of these with all the compilers you care about and then save a short link or a template and then um you can come back to it and use it as your kind of Workhorse for does this work on all the compilers that I care about and you can also help you know run up our our Amazon bill by doing lots and lots of compiles at once okay so we covered the as view the llbm past viewer you've now know where to look to go and find the equivalence for GCC and we looked at the conformance view as well now in the three minutes remaining we're going to talk about the last person who uses the site uh we're going to call that person Matt so Matt is a late 40s software engineer who somehow can't give up on his childhood obsession with 8bit computers that he had when uh when he was growing up and so what Matt might want to do is for example take some code for the BBC micro Circ Circa 1984 um like this although this is not actually from 1984 this is more modern than that this is my friend Richard Richard's code I mean sorry Matt's friend's Richard's code um and it's cool and all it's written in the assembly because you know it's it's a BBC micro and we can compile it which is to say we can assemble it over here and indeed we've assembled it into the equivalent code we look up tables and everything and that's great but I'm going to reload the page because once it loads up there's a little thing at the bottom right hand corner which I can click and it actually fires up an emulator with that code and so you can see it running on this BBC micro as you can tell with this little micro vitc CB monitor if you for those of you of a certain age this is probably more memorable than not and um yes you can run an emulator um from a compiled version directly in the site uh we support also I think uh we've got an Nintendo emulator we've got a Commodore 64 one I think um we've got a Sega Master System emulator and some of the compilers even can Target it I forget exactly which one we're running very low on time uh but there are I think you have to select C and if you do 6502 yes we've got cc65 in here I think there's even um a um a C++ compiler that supports it but I yeah I should have noted that down beforehand um anyway there is more there's more there's only 60 seconds more but there is more of this so very very very quickly we have public statistics about what's going on the site if you hit stats. compiler explorer.com you can see it we do support execution on gpus these days so if you want to run some Cuda code on an actual real GPU you can we support some amount of Windows execution if you use MW then you can run on um your program on one of our Windows hosts and um yes the results May Vary because the as noted before the msbc um thank you partu has put into the chat the p is the person who knows more about this than me I don't know why I'm even talking and I should put poto up here but um the uh the supported emulators link is in in the chat and we'll post it somewhere else too um I think that is all I've got here yes no I've got future dreams don't we all um obviously more compilers languages platforms it would be cool to support arm um something that's asked for a lot something that would be useful in my day job would be to have a live updating links that is links that I can share with somebody and then we can both type in the window or at least one of us can type in the other can see and see it change as they um edit but that's a lot of work um and then the Confluence of all the things that I love would be to take emulators and simulators performance compilers optimizers put them all into one thing and have like a fully featured x86 or similar simulator that can show just like the um uh the o o osak ACA and the um llvm MCA example but interactively show what's going on inside the CPU as you're single stepping through the single C++ code that you wrote okay last slide thank you for staying with me on this this hourong journey huge thanks to our commercial sponsors Intel Google solid sand sonol lint um uh my patrons and my GitHub supporters and anyone who supports us directly on PayPal of course a huge huge thank to all of the implementers uh part amongst them who's in the chat Channel right now you can say thanks to them too um for doing all of the hard work and me letting me take all of the credit for it and um thanks to my employer aquatic for letting me take a couple of hours out of my day to come and speak with you all um if you're interested in this kind of stuff you might want to ping me directly um we're always looking for smart individuals and that's how I pay for the time off so um that is me done thank you very much I will be in gather town to answer questions immediately after this um thank you very much indeed for your time f
Info
Channel: C++Online
Views: 850
Rating: undefined out of 5
Keywords: compiler explorer, c++ tools, online compiler, compiler explorer c++, compiler explorer boost, compiler explorer website, matt godbolt, in cpp, in c++, exploring c++ code, c++, cpp, coding, c++ development tools, compiler exploration tools, control flow graph, compiler, exploring cpp code, cpp lang, c plus plus, programming, 2024, tutorial, talks, c++online, latest, features of, What’s New in Compiler Explorer, cplusplus, developer, dev, c++ talk, c++ compiler, new in compiler explorer
Id: 28Gp3TTQYp0
Channel Id: undefined
Length: 61min 48sec (3708 seconds)
Published: Thu May 02 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.