Welcome everyone uh i'm chris and i'm here today to talk about cbs plus value categories um probably most of you have heard about siebel's plus value categories if you read the abstract you've seen some like r value and l value and you've heard these terms being used in articles and but my experience is that Most people have a very blurry understanding of value categories i used to have a very blurry understanding of value categories as well and i was wondering why is that and i started to dig and dig and basically there was a groundwork
for this presentation uh but we're going to fix that today so everyone is going to know what value categories are after Today so first a little bit of outline um this presentation is split up in in two parts the first part is going to be about the theory behind value categories what are they which value categories are there then i put in a little bit of room for questions and i think it makes makes sense to do it right here as i just said um and then there's the Second part of the presentations which will
be about the use of value categories and mechanisms in the c plus plus language okay um a little bit about me i'm chris i'm a developer at vinotion a company in eindhoven in the netherlands and we make products that use computer vision for detecting objects in video and then for example generate statistic information about Traffic flow stuff like that and we use uh ai and machine learning algorithms for that and we built all our products in zippers plus outside of work i'm a husband and father of two i play guitar and a band and i
like running and climbing and if you have any questions or just comments after the presentation you can Reach out to me via this email address or via linkedin that's fine okay the premise and goals of this talk um it's the talk is going to be about cbs plus obviously and it's going to be about siblings plus and then and i mean up to the latest versions of cbs plus the theory that i'm discussing today Holds so that's fine then of course there's more to it than can be told in one hour as with every topic
about supers plus probably um yeah that's that then the goals of my talk are going to be firstly to have everyone understand value categories expression value categories and the second goal is for anyone to see How this concept of value categories is used to describe and generate mechanisms inside the language and perhaps even how you can use your knowledge about value categories to improve your coding and understanding of cps plus code and i want to start out with a bit of quiz code perhaps some of you are familiar with the phone app cpus plus quiz
This is a bit like that so i have a little bit of code here and it actually compiles and it works and it runs and my question is what is the output and i mean this in two ways and the first way is what is the output in the standard output so there's a there's a print command right here and the other question is what is the output going to be In assembly code so will all the code that's here be emitted in the executable or not and i'm just take some seconds to look at
this and then we're going to revisit this example uh later on and then use our freshly acquired knowledge to reason about it [Music] okay so as you can see The code as such doesn't make much sense but it's about the idea but you'll see that later on if we know about value categories and some mechanisms that i'm going to discuss as well that we can really easily basically dissect this code and reason about it and just determine what this will be the output okay what are value categories Value categories all start with expressions and this
is a very important bit of information if if there's anything if anything happens to you or you fall asleep during the presentation or you leave early and you remember only one thing about this presentation it should be this one thing namely that value Categories are about expressions and they are not about object or class types value categories are about expressions and i mean seriously expressions because this is the point where most people go wrong in understanding value categories so remember value categories are about expressions not about objects or class types okay let's continue Now if
they are that important what is an expression really in c plus plus well the formal definition says an expression is in a sequence of operators and their operands that specifies a computation okay it's really formal doesn't doesn't really quantify what what bit of your average code is an expression well i reckon about Half of your code is expressions the other half is statements and things like braces and stuff but in fact probably most of your code is expressions and an expression produces a result and has a side effect possibly and if you don't know what
a side effect is um i'm going to explain a side effect is something happening in the background like for instance the printf function if you Call the printf function with a string it will print something in standard output and that's the side effect of the print function so that's what a side effect is so let's look at some examples of expressions first some simple examples so 42 that's an expression it's a literal integer then the addition of two integers that's an expression as well and it Evaluates to the sum of the integers then there is
a declaration statement uh and two expressions using this variable that was declared which is a and the assignment itself is an expression as well it's it results to the value that was assigned and then we can use this variable name in an expression as well And we see that a plus 17 will result in the integer value 40. and then for instance a static cost also is an expression and it basically results in a floating point value in this case of value 23. then a bit more involved examples um here we have uh again the
integer our integral declaration a then we have this size of expression that results in the Byte size of a the sub expression a is unevaluated in this case second example it's a lambda expression and it evaluates to a closure and here we have this printf function that i just named it the function call itself is an expression as well and it results in the amount of bytes that have been written and it has a side effect in this case that high Exclamation mark with a new line character is printed in the standard output okay so
now we know what expressions are so value categories are expressions but how in in what way are they related well they basically are a direct property of an expression so you have an expression in c plus and each expression has two properties namely a non-reference type and the value category So it's a direct property literally now there are three primary value categories that can be filled in inside this value category x property of an expression so i'm going to list these now and we are going to organize them later on and also show a lot
of examples of them so don't worry the primary value categories there are three primary value categories and these are The value categories that are actually assigned to an expression okay the first one is an l value or locator value second one is a pr value or pure r value and the third one is an x value or expiring value now the color names on the left are the official names Of value categories and the names on the right are made of names and they're unofficial you won't find them in the super standard but they're here
to provide a bit of meaning to the alphabet soup that's on the on the left because br value okay x value whatever doesn't make much sense if you look at them like that so just think about them as locator value Pure alpha r value and expiring value okay and now i hear some of you screaming behind your muted microphone where's the r value i've heard of an r value there's r value references in c plus where is it well there are two more value categories there's the gl value or general l value and r value
which stands for r value in there i think and these are all Value categories so now we actually listed them all so there's five in total three of them are primary value categories and two of them are i don't know general not primary value categories they don't have an actual category name i think now what do they mean and how do they relate to one another because now we have only a list of some weird Names but we don't know how to use them and how they relate to one another so we can do that
by taking two properties of expressions and then organize them using those properties so we go back to expressions and we're going to look at the property whether a expression results in to an identity or evaluates to an identity and the second property is Can we re steal the resources of the result of this expression and for each of these properties we're going to look at some examples for instance this the expression evaluate to an identity now here's some examples and in the comments is the answer to each of them just take a moment to look
at them see if you can reason about all of them And perhaps some of them puzzle you a bit so probably the first ones all make sense right this this heaven doesn't have an identity it's a and these are all sort of temporary literal things they don't have an identity but this one has an identity and that's perhaps surprising and this can be explained By thinking about this property does it evaluate to an identity this is basically standardies can you take the address of an expression result and in this case obviously you can't because they're
all temporarily lived anonymous things but a string literal has static door storage duration in siblings plus so it actually lives somewhere so you can Take the address so it has an identity uh same verb stood c out um obviously the results of these operators are temporary values so they don't have an identity then perhaps these ones are surprising at least they were surprising for me when i first looked at them but if you think about it it makes sense uh the post-increment Operator first returns you a copy of the object that's that is to be
incremented so that's a temporary without an identity and then it increments the object a for the pre-increment operator it's the other way around it first increments a and then it returns to the identity a so that makes sense instead move is one last one that stands out a bit For those that know about move semantics you will know that stood move doesn't move anything because it's just uh it's just a sort of value category hint that a can be moved and we'll get to that later as well so basically this is what describes this property
of an expression does it have an identity or not basically can we take the address or not Then that's the other property which we are going to use for organizing value categories and that's um can the resources of the result of this expression be safely stolen now this is a bit more hand wavy it makes sense for anonymous temporaries because they they have no owner anyway so we can steal the resources of This result right but then if the object does live somewhere then we have to rely on the end of its lifetime as it's
described in the standard as you can see here and this aspect of the expression results was actually the main motivation for introducing move semantics into c plus plus so now with move semantics you can be explicit About the lifetime of the resources of an expression okay a few examples for this property on the left here we define this function that returns a string lateral and returns a string then we have a vector of strings and we push back the result of this function now you can reason about the fact that the result of this function
call This function call expression right here its lifetime ends when this call is done so pushback in this case is allowed to safely steal the resources of this string i hope that makes sense on the right we have a similar example but it's almost the same but we have a local object it does have a name it's x it has an identity with the same value And it's also pushed back but by using move and in this case stud move explicitly marks the resources of x to be stolen from and now pushback is allowed to
steal the resources from x if possible okay now now we have these two properties so we have can we take the identity or this does an expression result in an identity And we have this other property can we steal the resources safely from the result of this expression and we're going to use those two properties to organize the value categories that we've seen and we're going to start out with a table of two by two cells and on the columns we are going to put the property does it have an id or doesn't not have
An id the expression result and then on the rows we put the other property can we steal the resources or can we not steal the resources and now there's one cell in this stable that doesn't make much sense and that's the one on the on the bottom right because what does it mean for an expression result if it doesn't have an id and you Cannot steal the resources that's it's a another really useful concept so we're going to leave that out and now we're going to fill in all the value categories let's start out with
the general l value the general l value basically describes any expression that results in an id so any expression that has an id as a result is a gl value But it's a spanning value category as you can see because it's not inside the cells and that's what it that's why it's not part of the primary value category so the primary value categories are going to be inside the cells for instance the pr value and the pr value is in the spot that doesn't have an id so it's basically an anonymous temporary and we can
steal the resources of it so That's what a pure r value means next one x value x value is in the spot it's an interesting spot because it does have an id but we can also safely steal the resources so that's a mixture of both properties basically and then we have the l value which is basically an expression that results in an id but from which we cannot steal the resources Or at least there's no reason to assume we can there's one left which of course is the r value which is also a sort of
general uh spanning value category that describes a set of value categories so now this is the way value categories are organized so we have these two spanning value categories describing The properties our value and gl value and we have the primary value categories in the cells and this is basically what it's all about and we're going to look at a lot of examples now just to really hammer all this knowledge in and then you know about value categories okay let's look at some examples we'll we'll start simple right so again we have this literal integer
42. it doesn't have an id it's a temporary so it by definition is a pr value right same for null pointer but then we have this string literal and as you can remember the string literal had a static storage duration so it does result in an id and as it is written here there's no reason to assume we can steal resources of this string so it's an l value A bit more in involved examples here we have an integer x and we pre-increment it and we post-increment it and a pre-increment resulted in an id and
in this case there's no reason to assume we can steal the resources because it's just there so it's an l value post-increment resulted in a temporary value so it's a pr value by definition because it doesn't have an id Then again we have integer x and if we use it as is it's an l value it makes sense now right it does have an id there's no reason to assume we can steal the resources but now we apply the move operator to it in the bottom example and now basically what moves this is it re-labels
the value category to x value because now you are explicit about The resources of x to be stolen freely safely sorry a little bit of a more practical example we have a function definition here and we call this function now we call the function with the value 42 which is a pr value an integer literal then it comes here and inside this function we have an r value reference to this integer argument but Arc itself like this this expression is an l value because it's an id and as as it is like this there's no
reason to assume we can safely steal the resources only unless we apply the move operator to it now we can assume we can actually steal the resources and now this is an x value so if we call another function and we move on This argument value now it is an x value so one last example then and this is more of a quiz and if you paid good attention in a previous slide you know the outcome of this question because we have two function overloads one taking an l value reference and one taking an r
value reference now we have this variable here which is An r value reference and we call the function with x now which overload is going to be called number one exactly because x in this case as it is used in the argument list is an l value so this will be the overload that is taken correct and that really this all boiled boils back to this point i stressed in the beginning of This talk and that that is value categories are all about expressions and they are not about objects or class types so i made
this example a bit more deceptive because i used an r value reference variable here and this is fine to do it's basically a temporary reference or something like that But i i move it or i pass it on in the function as an l value so this one is called yeah that's right um and i see there's some some questions in the chat and i'm going to uh to answer the questions uh when we are at the end of this part which is almost so um but before we we end this part uh i'd like
to make a little side step into history Because i think the history of value categories is important to understand them because a lot of knowledge on the web is basically wrong or not really clear about what the value categories are and i had to do a lot of work finding out what the real theory is behind this because there were so many articles and blog posts and whatever that were wrong on this topic and they are wrong Mostly because they are outdated because value categories have a very long history in programming and actually it all
started in the very first ancestor ancestor of cbs plus which sort of cpl the combined programming language from 1963 and it introduced these concepts of l value and r value and it was defined as The expressions that could be put in front or behind or on the left right or on the right side of a of an assignment operator and that's what most people these days still think is the truth about value categories but it's it's it's not anymore um bcpl basically uh inherited the definition uh so that b and c and of course from
c comes c plus Plus and at first follow the rules c but then until c c plus plus o three there was a from c plus percent o three onwards there were some minor changes in the definition and of course in supers eleven we had move semantics added and we had these new value categories like pr value gl value and x value added so i'd like you to forget all the Old-fashioned definitions because the diagram i showed you earlier that's what it's all about okay so now we know about value categories but now what what
what can i do with this well of course it helps with communication because if you know what you're talking about you you can learn better and you can be literal literate about Your language which is important i think then i've seen that there's a lot of compiler errors and warnings that mention value categories and if you don't even know what these errors are about then you cannot effect effectively fix the error so that helps then i think in-depth knowledge on cbs plus is generally beneficial if you want to Learn new stuff it's also really useful
for understanding move semantics because it's a very important part of the underpinnings basically so if you want to go really in depth on move semantics i advise you to be prepared and also know about value categories so that helps and lastly it also helps for Understanding copy elision and implicit conversion and in fact the second part of this talk is going to be about copy elision and some related optimizations and you'll see that by using the knowledge that we now have about value categories that this is really more easy to understand what's happening all behind
the screens of compilation process Okay now before we go into the questions i'd like to revisit the quiz and together we'll look at some of the value categories that are here because we are going to use that for our last revisit of this quiz at the end of this talk so we can see here of course all all execution starts here and we define this local variable x and we basically this is a nested definition or A nested declaration here and we have this 42 which is a pr value that we use to construct this
number which again results in a pr value so this is a pr value expression as well then we use this as the input to this factory function right here because it constructs a d from a number so inside here we have this n which is an l value right here And then we cast it basically to an x value and every we return a temporary constructed t which is a pr value right here and then we we construct a d from a t and from that we call the get function to get the number and
print the value so now we already know a little bit more and we're going to use this knowledge In the last revisit to explain what will be the output and to reason about this okay so i'm going to open the chat window now let's see can i make this a little bit bigger no apparently not oh i can let's see will the video be available after this meeting yes but um actually i will also be uh giving this talk on a sort of mini conference In november so i agreed with uh pavel and mihai to
put this video up only after that a conference but i will be providing the slides so you will also you will already be able to look back so i will do that probably tomorrow so i rely on mihai and pavel to distribute these things let's see [Music] Okay there's no questions really right there's no questions about value categories in the chat perhaps someone else does have some questions about them some of the examples perhaps were unclear or are they stable now or are they planning to add even more categories no no they are stable yeah
um so basically the way you should you Should see it is um c or c plus plus in the first place inherited these value categories uh in the standard from c right the the l value and the r value as as being on the right or on the left of an assignment operator but um in simples 11 they wanted to expand on the functionality of the language by For example being explicit about stealing resources from objects and introducing move semantics and the the the two value categories that were there uh l value and r value
were not enough anymore to describe all the rules that go with move semantics so they basically had to be creative and make up these sort of value categories and then use those for uh Defining all the new mechanisms and that's not the end of the story because they still use these value categories today and today's standards to describe all the mechanisms that are there and they they can also rely on the new ones but i don't think there will be new ones at least not in the next few standards after super 20. at least i
didn't catch any feature that needs another Uh another value category so i think they're stable yeah and i think afghanistan has asked when is the next session oh sorry when is the next session uh what's what session yeah i'm actually wondering about that is it like a work group session or not sure what uh he's asking i want okay well perhaps i'll and we can answer it later on then uh i'll continue with the second Part if that's okay oh i see there's another message i'll just look at that uh oh yeah mentioned about copulation
yeah i will go into copy religion now so that will be the second part of the talk okay yeah there we go so the the part is called value categories in the wild and it's about the practical side of value Categories because we now know what they are which there are and how they are related but how are they used in the standard what meaning do they have when it comes to your daily coding aside from some academic uh description or definition of constructs that you have well actually the they are closer than you think
and The topic i chose here is copulation because it's one of those other topics that many people know a little bit about but not many people know much about it and it's not really that hard but the the knowledge about them is about it is really scattered all through basically the standard as well and there is a part about copulation but There are some extra rules that are basically all over the standard so copulation oh i did it again i the uh no oh there we go copylation right um a copy legend is a actual
part of the siblings plus standard that describes the legend which means omission or leaving a leaving out of copy or move operation so you could argue that since c plus plus 11 it should be called uh copy and move religion not just copy illusion and the result is that you have no copy or move at all so that will be passed by value semantic basically zero copy pass by value semantics is what is called there are some restrictions as with any uh complex thing in sybiz plus and it's it's a mechanism That happens or is
active basically behind your code and you you write a function and you look at the output from the compiler and you don't see the copy happening that you just wrote because the compiler can use this rule from the copulation section to elide away or elide the move operation or copy operation so the compiler will not generate a copy At all which makes your code faster obviously and that's really nice because that's the ultimate goal right zero overhead zero output and just a super fast executable but there are some constraints another thing you want to know
about copulation is it permits religion but it does not guaranteed and now these days i think most Compilers implement all the rules but they don't have to and in in the early days perhaps people are still using embedded compilers or some older compilers because they have to work with legacy hardware and perhaps those compilers don't even do copulation because they are not mandates they are just permissions it allows the compiler to do The omission of copy or move operations so the results are really dependent on compiler and compiler settings and versions and all that so
it basically looks like this so on the left side we have a little bit of cbs plus code we initialize a variable x with the result of a function and this function returns a default constructed d and in this case i sort of listed all The things that are going on we have a construction a copy construction when there's a return and there's a destruction of the original one a copy construction when we do the assignment here and then we have two destructions one of the copy and one of the original one so this is
quite noisy just to basically initialize one object and there's no copulation active so this Is valid output now your compiler may be smart and do return value optimization and for instance uh eli the copy that is being done when the function returns and you could get this situation so there's only one copy construction happening and two destructions for the same code this is also just a valid output for any compiler but The best scenario would obviously be this one and this is full copulation and this is what hap what would happen if your compiler would
elide this copy that's being made when you call this function and also the copy that's made in the assignment this is what we would consider as full copy illusion which is i think the goal Um so where can elections occur we just saw the first one in the initialization of an object we can have in election so then there's a return statement we can have an illusion of a copy or move operation but there are also two other spots like the throw expression and the catch clause and if you use expression or exceptions at All
then these are also cases in which the compiler is allowed to do [Music] copyright of course that's great stuff right now we all want copulation for all of our code and basically end up with this very small binary that runs in infinite speed and now you're going to ask me where is this button To turn this on where's this boolean enable uh full copy legend mode or something like that well it turns out there isn't such a button unfortunately and through this compilers have been doing it for years so uh that's a bit of a
letdown so if you're a coder that uses modern compilers then there's nothing for you to gain here so That's nothing because compilers have been doing it for years unfortunately but is that all of it well not really because there have been some improvements in the last few years and namely in c 17 there are some new rules added to the standard that are informally known as guaranteed copylesion or guaranteed return value optimization And copy evasion and these are all unofficial names for the same concept that was added to the standard and these are mandates so
yeah mandates not permissions they are mandates so now the compiler is forced to apply copy religion in some specific situations and what this comes down to in the siblings plus standard is that it is a Special set of rules for pr value expression so now you know what a pr value expression is right because it's an expression that doesn't result into an id and the resources of this expression can be reused safely and for those cases there's a set of rules that force copy religion so that's guaranteed copulation for you And the the two cases
that were described in the standard are uh initialization of an object so if we initialize an object d with the same type t then the compiler is not allowed to generate a copy so there is a bug in your compiler if it does generate a copy if it adheres to the c plus 17 standard right the other situation is in a friction Return situation so if you have a function of a type t that returns a pr value of the type t then there is no copy allowed in this situation so there's only one default
construction of t allowed here and that's that's really cool because now we've had all the practical implementations of Copulation over the past three years of all the compilers that were smart but now we also have the theory or the the rules in the standard to back it up so that's cool now in order to understand copulation and the rules that i just talked about right here um i want to dig in just a little bit deeper and touch upon the subject of temporary materialization because under the hood These rules about pr values they basically describe
apr value as an unmaterialized recipe of an object now think about this uh there's some expensive words right here so and unmaterialized and materialization basically that means coming into being so if an object is in an pr value expression the object basically is not there yet it's it's like a ghost or an unmaterialized Recipe and until actual materialization is required so basically what happens with a pr value is it isn't is an expression which was if a evaluation materializes an object so before it is being used or being evaluated it is immaterialized and this conversion
from going into From going from a materialized form into materialized form is called a temporary materialization conversion so that's quite a mouthful it makes for a good birthday conversation material i think if you go to the right birthdays so let's let's look at some example there's an example here we start from the bottom um i i have this main function here And i return the age of a function that i created with this factory function and basically what this factory function returns is a struct of this type with a name and an h so a
person has a name and an age and we build it and perhaps this factory function gets some extra runtime data in here to perhaps change the name or modify the age or gather get the h from uh From somewhere and that basically builds this pr value because right here we construct this person object in place and return it so there's this is a pr value return situation so this in this case we have guaranteed copulation this results in a pr value here and but this is still a pr value right so It's unmaterialized but now
we want to know the age of this person that was returned there and now this pr value has to be there because otherwise we cannot we cannot request the age so that's where the temporary materialization conversion happens and basically what that means is that it will be converted into an x value so a temporary materialization conversion is a Implicit pr value to x value conversion and this this is now explainable with the knowledge you have about value categories right and this actually brings us to another remark and this this one br values are not moved
from and if you think about it br values are unmaterialized forms of objects so they are not moved from because there's nothing to move Because they materialize once they are evaluated and that's that for that this little concept forms a lot of confusion for many people especially if you go into trying to understand move semantics without having this background knowledge about value categories so you think you do an actual move but it's not really the case so pr values are these special Expression types okay now temporary materialization occurs uh like we just saw accessing a
member of a pr value binding a reference to apr value applying sizeo or type id to a pr value etc etc when you evaluate it when you have to access the materialized form of this object okay so this case we just saw right br value next one Is an x value because we have this temporary materialization conversion actually in this second example there's three temporary materialization conversions first one is here so we we define this object x that is a concatenation of two strings and in the first string so this is a pr value but
we want to access a member this is a temporary materialization conversion Then we want to add or concatenate two strings so we need to have the values in order to generate a concatenation but this also leads to a pr value which is the concatenated string but it has to be an assigned to an object so there is an initialization going going on here so again there's a temporary materialization conversion so there's three In this example okay so basically in cyprus 17 we have copy and move religion on steroids because there's a copulation and temporary materialization
that form this power duo and make copulation happen in a lot of situations and when i was researching all the background information on this i came across the definition of return value optimization very often And probably many of you have heard of that as well so that's what i'm going to talk about now because it also relies on heavily relies on value categories as an underpinning so return value optimization or rvo is nothing more than just a variant of copy elision so don't let all the information that's out there fool you it's really simple you
have copulation And temporary materialization in super 17 and there's rvo and all these other rvos and they are basically a variant of copulation nothing more okay and actually rvo is not as such a part of the standard copulation is a part of the standard because it has its own section even but return value optimization is an unofficial Term and it's just describing uh describing copy elision in a function return statement right if you look at the name return value optimization it's scopulation in return value but but there's a little bit too more to it there's
two forms namely unnamed return value optimization url or simply called rvo in most cases and there's name to return value optimization or Nrvu and perhaps some of you know about this um there's these two forms and they live outside of the standard as i just said and they are basically a collection of rules in addition to copy religion because if we look into detail and do those into those two forms of return value optimization you have a name return value optimization it Refers to the returning of temporary objects so that's pr values right because they
don't have an id so that's the returning of pr values hey but c is plus had some rules about that and it is guaranteed right and that's right ur vo or unnamed return value optimization is guaranteed by cps plus roles so we don't have to Look into it any further but there's also also another form which is named return value optimization and this is more hand-wavy already because right here we are talking about the return value optimization of named objects hey that's not part of this c plus plus mandates rule but as i just said
it's a collection of rules scattered all over the standard And it refers to the returning of named objects from a function for example we have this little function here we define a local variable result and we return this one and then we initialize an object with this if you compile this it will result in only one construction of t and there will be no copy construction because there will be named return value in action That's really nice and and we can make this a little bit more complicated like this so we have this function again
and again we initialize this variable x with the result of this function we have this local variable result and then we have this if branch here so if if there's true or false and perhaps is even runtime information we return the result in an early stage Perhaps here we modify result and then we return result but again it still works so named return value optimization even works for this example which is that's really nice because now your compiler is able to figure out stuff in your code and make it more efficient even if you didn't
think it was possible however nrvu is quite finicky and i'm going to show you why And in order to understand why we're going to quickly go through a course of function called mechanics and probably all of you know this because you've all been to computer science school or programming school i don't know but you've probably seen many of this background information but we're going to look into it anyway because it makes sense to understand why nrvo is finicky So let's go through this and it and this is a bit of an abstract description of things
you call mechanics there's the details are obviously more elaborate but the idea is this if you have a function call like you see here and you're inside this function and you're going to take a look at the stack there will be the return address and nothing more because this In this case we have a function with no return type and no arguments so the caller may have saved some registers on the stack some values but the only thing we have here is the return address now what happens if we add a function parameter then there
will be a stack frame reserved for this function parameter to be passed On to the function and if we take multiple arguments there will be multiple stack frames reserved now what happens if we have a return value almost the same now there will be a slot reserved called the return slot on the stack for the function to write the return value in and this is really important because there's a slot reserved for the Function to write the result in and if we combine this we get this so we have function arguments and a return value
and you see the return value basically is just like another function argument it gets its own slot but try to keep a good memory of this diagram right here and we i'm going to show this diagram also with the explanation of Of named return value optimization so why this and rvo break sometimes let's see let's look at the first example again we have a little bit of code again we initialize an object with the result of a function return value and now there's a local variable result and we return it here at the bottom But
there's a branch in the middle of the function that returns a temporary value but not result so now the compiler is not able to place this and this in the same slot so it cannot do named return value optimization here so the best the best you will get here is a move construction of x okay i hope that makes sense Another example a global static variable result that's being used for returning from the function again the compiler cannot allocate this global variable which is already alive in the return slot so there's no control over the
address of the return value so there will be no named return value optimization next one Slicing this is a bit a bit of a weird example i think uh you you never come across it normally when programming has at least not in this form but this is fully legal cpus plus so you have a type t which is a base class of u and then you have a function that returns d but you're allowed to do a value return of you so What happens is the footprint of this type is larger than the footprint of
this type because it has additional members so the compiler is not a la is not able to allocate a u type inside this return slot on the side so now and our view breaks again then there's one last example where nrvo is not possible and that's when you return a function argument Directly because as we've seen the arguments get their own slots aside uh the return slots for the return value so in this case the compiler cannot combine the slots so the best case would be a move construction of x summarizing return value optimization so
as i already said return value optimization does not work when the compiler Has no control over the physical location of the object to be alighted but there's always this construct of implicit move and this is all again an unofficial definition i think i borrowed this one from arthur o'dwyer who has some talks on this you should really check out because they're quite interesting and implicit move is this idea of a set of rules that Are defined to allow the compiler to implement a move operation if it can basically so in this case if you return
the function argument as we just saw it breaks named return value optimization but what the compiler will do is it will implement a move operation or a move construction to construct x so depending on your type depending on whether a move construction is Cheaper than a construction or a new construction at all this is an optimization and what will happen is people read about this and they try to be clever and they sometimes do things like this and then you you can see right here there's a situation that has perfectly fine named return value optimization
right Nothing happens with result we can just return it and the compiler will output no copies and only one construction and then people think wait wait there's this implicit move thing let's already anticipate on that and return a moves right and of or moved variable but what will happen is nrvo is not possible anymore because it Can only work on names directly and basically you break nrvo and you get this uh pessimizing uh move construction okay so that that concludes i think the most informative part of my talk but i won't leave you without some
guidelines some guidelines about writing code if you know about Copulation and return value optimization don't be afraid to return objects by value because in many cases many cases as we've seen it's okay because the compiler will optimize the copies that are being made away and that's that's really powerful because now what i've seen over the past years is that people tend to Define output parameters instead of return values in functions what you will then get is void functions with output parameters and that's really counterintuitive so if you keep your stuff simple you can use uh
return by value so try it just use that and it looks better as well it's readable more readable more reviewable also don't be too smart because the Compiler knows everything and these days the compilers are wicked smart and you cannot outsmart them so try to keep your stuff simple don't try to anticipate too much on the mechanisms that are in the background then i advise you for any type to always check out if your move operator is or move constructor is there Because if it's not and there's a situation where you have named return value
optimization and it's not possible and your compiler is able to do a an implicit move and there's no move constructor it will fall back on the copy constructor and possibly for your type that's more expensive and already even if you have a type that has a virtual destructor defined And implemented then basically what the compiler will do is omit the move constructor and move operator s and there will only be copies made in your code so you should pay attention to the role of five or zero or whatever what's there you have to know your
special member functions a little bit then you can also use compile-time programming of course and this is a bit of an open door Yeah obviously if everything in your code is already processed in compile time there is no code to optimize for the compiler so that's the best situation i think and then the last one and is keep your functions short because if you have short functions then the compiler is more often able to do as assumptions on what to optimize and what not in your code and also this I think it just looks better
because you already name subroutines inside your code and it makes for better reviewing and there's all these benefits right so before we go to the conclusions let's look at this quiz that i've shown from the beginning so now here we are again with this quiz code and we already know what the value categories are but now we also know what happens with all the Copy legends and return value optimizations that are there in fact if you take a good look right here we have this the result of this expression right here is basically a pr
value of type t and this function is also returning a type t so in this case there will be no return value or there will be this this function will completely Optimize the way because this the result this will be put in here directly and then we have this situation where we initialize or construct a t from a t and that will also be optimized away and then we basically get this so the factory function is now gone and what is also gone is the copy constructor with its sprint statement so there will be no
output in the Standard output so that's already one half of the answer but then what will be the rest of the answer well compilers are really smart and the output will be basically nothing so you have all this code and fancy stuff going on and in the background the compiler is able to leave out a lot of stuff by rules of the Language and then also be smart enough to optimize the way basically everything and boil it down to two assembly instructions and as you can see it's not even aggressively optimized i think if you
put 0 it will leave in functions uh without them being called or something i don't know but i had to put 01 here to leave all this Other stuff away as well but that's that's that's really nice because now you're able to to program and make readable code that is actually doing something if you read it and then if you look at the output it will be boiled down to the bare minimum really okay so to finish off some conclusions so we have the simplest value categories that i talked about in the first part there's
five value categories of which Three of them are the primary ones that are assigned actually to expressions there's two spanning value categories that basically define a property for instance here the gl value defines identity and our value basically defines any expression from which we can safely steal the resources and the x value is the primary value category that's in Between those uh properties all right then copy illusion and move elision it's a part of the standard so is temporary materialization then we have urvo and nrvo they are unofficial terms so they are not in the
standard copulation does not guarantee it permits right so you can actually turn it off by using Compiler flags it's really interesting by the way and then we have temporary materialization which is an actual mandate so it forces the compiler to adhere to it and employ a guaranteed copulation some more conclusions on copy and move relations so you have a temporary materialization which is a pr value to x value conversion And pr values are not moved from and i think these are one of these remarks that perhaps you have to look back sometime later to if
you don't understand it right now but it will make sense if you look into it and then there's implicit move which is another unofficial term which is basically a return value optimization that happens Without copyrighting so implicit move is basically a set of rules scattered across the standard and that's it for the talk so those were all my slides i'm way over time i think i don't know if i had any uh restrictions on time but i have no restrictions thank you chris yeah i took my time so i i think i originally planned this
for one hour but uh so i'm slow today there were a few Questions in the comments if you have a look let's uh let's open them okay uh yeah so the first one is from ahmad yes elasian happened in return most of the time well well it really depends on the compiler version it has been changed from older version gcc to newer version of gc yeah that really depends and the best bet you can have is If you just program in cbs 17 or later because then you basically work under the rules of temporary materialization
and you also have this guaranteed copy illusion happening and then you are pretty sure about your compiler if it supports simple 17 then it probably does elide every copy it can so i think that's that's the Best answer i can give to that question and uh there's someone we had to run bye let's see thanks for the info yeah thanks another thanks let's see other compiler flags or other mechanisms to mark allegiance so that the compiler emits a warning when that no longer holds hmm that's a good question i'm not really i'm not really aware
of any of those Markings i don't think it's possible because it's it's still it it depends because if it falls under the non-guaranteed copy legends it's still up to the compiler if it does so or not so then it's really compiler and configuration dependent but what you can do and what i sometimes do even for the code at work is create this type that is a i call it a noisy type and i Think i have a example slide for that let me look it up what i then do is just generate a side effect
for every special member function operation for this type so basically you log everything that's going on and if there's a if there's an elation you hope not to see either one of these and you only Hope to see these happening so that's what i sometimes do i hope that um that helps but also helps perhaps is boil down your example into a very small example uh something like uh [Music] the the the quiz i showed you or something like this something really small that you can put in compiler explorer And then basically feed the compiler
this compiler flag for instance minus f no elide constructors and then copy relation will be turned off and you will see the results in the code and perhaps that will answer your question at that point um next question a clan prints a warning in case of a return stood move yeah And it should and i think it's it's mostly the last few versions of uh of clung that does that i think we use clang 9 at work and it it doesn't do it so i think it's the last few versions of clang and also clang
tidy one of those uh tools that you can use for static code analysis this one about uh stud move return doesn't the standard mandate move semantics and return statements And yeah so that's sort of the same right uh same notion about the warning about returning stood move uh rather than it being an optimization let's see well i don't think the standard mandates move semantics at least not that i'm aware of i think this it is an optimization but i don't think there are any rules for that or at least I'm not aware about those rules
and i even tried to look up uh some some stuff in the newest standard cpus 20 to see if they changed anything to that and i couldn't find anything really so i think it's an optimization only okay those better questions or perhaps there's some other questions uh yeah i think yeah in a case like that i Think it it's uh it will warn about because the only option it has is to move right so john mcfarland asks doesn't the standard mandate move semantics in return statements and in some circumstances rather than it being just an
optimization and even when returning a unique pointer so in the case of a unique pointer Which is a move only type uh of course then that's the only option it has in order to transfer the contents of this object to the destination so if for some reason moving is isn't possible then of course there will be a compiler error so i found a small reference there on cbp reference where Apparently you can like there's some more vision that is mandatory okay that's that's cool thanks i'll use that because i i heavily used cpp reference obviously
for building all my uh content but that detail that uh i didn't notice that that's a good one i'm going to write that down they keep changing stuff yeah yeah that's that's right i mean it's still kind of you know like Spooky action at the distance because if you you know in some cases your code is not allowed to move and then in some cases it is then you're kind of you know sometimes it's not that easy to reason about code no no really and i think you perhaps you go a bit too far if
you try to reason about code like that so right because i i had a discussion that at a conference on cppnc And someone asked me about my talk and he said why would you learn anyone about value categories because you're going to make them too smart for instance you you don't need to know about failure categories to be able to program cbs plus and that's obviously that's true yeah but if you know the right things i don't think it hurts and it helps you Understand other concepts in the standard especially if you want to dig
into move semantics i did a workshop with nikolai yosutes about move semantics a one day workshop i think it was uh c plus plus move semantics the complete guide or something like that and i really couldn't have understand it this well if i didn't know about the value category so I was really happy about my preparations so yeah okay cool are there any more questions or going once going twice [Laughter] well i guess that's all so yeah thank you very much chris for the wonderful talk and for answering all the questions that's uh thank you
presentation yeah thank you very much that's very kind of you