• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
mic_k

C++ Function Parameter

11 posts in this topic

hi,
i'm currently in practice with c++, i found a situation(not critical).

as i read from tutorial & article, it said that good thing in passing argument by reference, but not to change the value inside the function, is to use the [b][i]constant-reference[/i][/b]s as the function parameter.

in situation that i just want to pass the argument to a function just for resource only, not to change the value itself,
1. so when is the right time to use the [i][b]by-value[/b][/i] parameter ?
or
2. when is the time not to use the [i][b]constant-references[/b][/i] parameter ?

may anyone have suggestion..

thank you,
happy coding [img]http://public.gamedev.net//public/style_emoticons/default/laugh.png[/img]
2

Share this post


Link to post
Share on other sites
yes, i also read about that too, use the by-val parameter for built-in types data, use the const-ref for class type data or large list/collection.

and additionally, a consideration when there are needs to copy that function param into local(of function block) variable, some suggested to provide the function with by-value param type.

that give me perspective now, thank you stroppy.
2

Share this post


Link to post
Share on other sites
Most of the time you'll pass by reference or pointer in methods, and then copy the value to a classes member variable if you want to hold onto that value.

for example a Vector3 class
[source lang="cpp"]

class Vector3
{
Vector3( double x, double y, double z )
: x(x),
y(y),
z(z)
{

}
double x;
double y;
double z;
};

class Actor
{
Vector3 mPosition;
void SetPosition( const Vector3 & pos )
{
mPosition = pos;
}
};

[/source]
this allows you to put in a temporary rvalue when you call the function

someActor.SetPosition( Vector3( 0.0, 0.0, 1.0) );

Which is passed by reference. The difference is that a reference is behind the scenes a pointer. A pointer being up to 64bits on 64bit os. Verses the size of the Vector3 being at least 3 * 64 ( if a double is 64 bits on your system ). This is a optimization. And since when the SetPosition class actually makes use of the reference it copies it, there is no worry about having a invalid reference. Edited by EddieV223
0

Share this post


Link to post
Share on other sites
I've posted my opinions on it in [url="http://www.gamedev.net/topic/630972-returned-values/page__p__4978355#entry4978355"]this thread[/url] ([size=2]I don't want to copy+paste the large-ish post[/size]). [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
2

Share this post


Link to post
Share on other sites
[quote name='Servant of the Lord' timestamp='1351733904' post='4996031']
I've posted my opinions on it in [url="http://www.gamedev.net/topic/630972-returned-values/page__p__4978355#entry4978355"]this thread[/url] ([size=2]I don't want to copy+paste the large-ish post[/size]). [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]That's about return values, not parameters, though.

Regarding your post on that other thread, you claim that the compiler will use move semantics in a situation where a caller passes a (local?) value as a function parameter and doesn't use that value afterwards. I see how the compiler has a chance to optimize in this situation, but does the standard actually guarantee the compiler will do so? I don't remember reading about such a thing before. It seems like a potentially very expensive and difficult thing for the compiler to detect reliably under all conditions.
0

Share this post


Link to post
Share on other sites
[quote name='Stroppy Katamari' timestamp='1351758851' post='4996112']
[quote name='Servant of the Lord' timestamp='1351733904' post='4996031']
I've posted my opinions on it in [url="http://www.gamedev.net/topic/630972-returned-values/page__p__4978355#entry4978355"]this thread[/url] ([size=2]I don't want to copy+paste the large-ish post[/size]). [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]That's about return values, not parameters, though.

Regarding your post on that other thread, you claim that the compiler will use move semantics in a situation where a caller passes a (local?) value as a function parameter and doesn't use that value afterwards. I see how the compiler has a chance to optimize in this situation, but does the standard actually guarantee the compiler will do so? I don't remember reading about such a thing before. It seems like a potentially very expensive and difficult thing for the compiler to detect reliably under all conditions.
[/quote]
RVO and named RVO are both allowed by the standard. They are not REQUIRED by the standard, no optimizations of any kind are REQUIRED by the standard. Edited by Washu
2

Share this post


Link to post
Share on other sites
[quote name='Washu' timestamp='1351764066' post='4996129']
[quote name='Stroppy Katamari' timestamp='1351758851' post='4996112']
[quote name='Servant of the Lord' timestamp='1351733904' post='4996031']
I've posted my opinions on it in [url="http://www.gamedev.net/topic/630972-returned-values/page__p__4978355#entry4978355"]this thread[/url] ([size=2]I don't want to copy+paste the large-ish post[/size]). [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]That's about return values, not parameters, though.

Regarding your post on that other thread, you claim that the compiler will use move semantics in a situation where a caller passes a (local?) value as a function parameter and doesn't use that value afterwards. I see how the compiler has a chance to optimize in this situation, but does the standard actually guarantee the compiler will do so? I don't remember reading about such a thing before. It seems like a potentially very expensive and difficult thing for the compiler to detect reliably under all conditions.
[/quote]
RVO and named RVO are both allowed by the standard. They are not REQUIRED by the standard, no optimizations of any kind are REQUIRED by the standard.
[/quote]Hold on. I wasn't talking about RVO. In Servant of the Lord's example above we have the line:
[code]std::vector<std::string> notACopy = GetStuff(veryLargeVector); //No copy made - not in passing the variable in, and not in return the variable.[/code]
For the return value, the standard guarantees that no copy happens. Either RVO is performed *or* the vector is move constructed. The thing I do not fully understand is the claim that veryLargeVector will not be copied when it goes in as a value parameter. Sure, a compiler might notice it will never be used again and use that to optimize (in spite of its lvalue-ness), but do we have an actual guarantee like we do with the return value? Edited by Stroppy Katamari
0

Share this post


Link to post
Share on other sites
[quote name='Stroppy Katamari' timestamp='1351758851' post='4996112']
[quote name='Servant of the Lord' timestamp='1351733904' post='4996031']
I've posted my opinions on it in [url="http://www.gamedev.net/topic/630972-returned-values/page__p__4978355#entry4978355"]this thread[/url] ([size=2]I don't want to copy+paste the large-ish post[/size]). [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]That's about return values, not parameters, though.[/quote]
The thread is about return values primarily, but my post talks about both parameters and return values.

[quote]Regarding your post on that other thread, you claim that the compiler will use move semantics in a situation where a caller passes a (local?) value as a function parameter and doesn't use that value afterwards. I see how the compiler has a chance to optimize in this situation, but does the standard actually guarantee the compiler will do so?

I don't remember reading about such a thing before. It seems like a potentially very expensive and difficult thing for the compiler to detect reliably under all conditions.[/quote]
I was under the impression from the [url="http://channel9.msdn.com/Events/GoingNative/GoingNative-2012"]Going Native 2012 videos[/url] that it is very likely to use move semantics in that situation, but [b]I was getting confused between lvalues and rvalues[/b]. If it was an rvalue, such as an unnamed temporary, it would use move semantics instead of copying (if a move constructor exists for that type). I don't know if it's [i]guaranteed[/i] that it will, but I think it would be if the argument type had the proper move constructor.

[code]std::vector<std::string> result = GetStuff(std::vector<std::string>(1000, "very large string containing alot of data");[/code]

In this case, since the vector as an argument is an unnamed temporary, my possibly flawed understanding is that it will be guaranteed to be moved instead of copied (if a move constructor exists). Further, my (again: possibly-flawed) understanding that GetStuff(), without RVO, would create a temporary, and then the temporary would be moved into 'result'.

However, you could use std::move() to tell the compiler to move the lvalue and get the same effect: std::move() would take the lvalue and return it as a rvalue, allowing GetStuff() to use a move-constructor for its parameter.

[code]std::vector<std::string> veryLargeVector;
veryLargeVector.resize(2000, "very large string containing alot of data");
std::vector<std::string> result = GetStuff(std::move(veryLargeVector));[/code]

It seems all of this would depend on the class being passed around to actually implement move constructors though (which std::vector does).

Where I'm getting my impressions from:
[size=2][url="http://en.wikipedia.org/wiki/C%2B%2B11#Rvalue_references_and_move_constructors"]C++11: Rvalue references and move constructors[/url] (Wikipedia)[/size]
[size=2][url="http://www.artima.com/cppsource/rvalue.html"]A Brief Introduction to Rvalue References[/url] (2008)[/size]
[size=2][url="http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/STL11-Magic-Secrets"]GoingNative 2012 - STL11: Magic && Secrets[/url] (2012 - Particularly 35 minutes into the video)[/size]

I haven't read the actual standard, despite having the PDF draft on my computer.

[b]tl;dr:[/b] I was getting confused between lvalues and rvalues, but you can explicitly get the same result if you use std::move() and the type has a move constructor defined. Whether or not a compilers would automaticly detect it (which I recall hearing somewhere, but have no proof of, and it wouldn't be guaranteed), an explicit std::move() should guarantee it. Edited by Servant of the Lord
0

Share this post


Link to post
Share on other sites
[quote name='Servant of the Lord' timestamp='1351826347' post='4996409']

tl;dr: I was getting confused between lvalues and rvalues, but you can explicitly get the same result if you use std::move() and the type has a move constructor defined. Whether or not a compilers would automaticly detect it (which I recall hearing somewhere, but have no proof of, and it wouldn't be guaranteed), an explicit std::move() should guarantee it.
[/quote]Thank you, that was an excellent response. (A++++, would reply again, ... [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] )
The Lavavej video at exactly 36:53 confirms my earlier point. In your initial example when you passed in a lvalue, you would have gotten a useless copy, contrary to what you initially assumed. I also think you are correct in that applying std::move to the argument would work here, assuming the type has a move constructor. However, the smart default to use is still const ref, and a beginner should just go with that every time instead of trying to puzzle out when to use by-value and when to use move. Moving the argument also leaves the undefined object dangling in the caller and causes the risk of accidentally using it again. I think it's safe to say >90% of people coding C++ for a living do not understand move yet, and a lot of them never will.
0

Share this post


Link to post
Share on other sites
Np, sorry for the initial confusion and spread disinformation. [img]http://public.gamedev.net//public/style_emoticons/default/laugh.png[/img]
[size=2]I edited the original post, not to change what I said, but to visually strike-out the wrong info and add a link to this thread.[/size]

The Lavavej video at ~35:00 indicates the proper time to use pass-by-value would be when you are creating a copy from the const ref anyway, because then with temporaries the copy can be avoided; as STL puts it in other places: "Never slower, but sometimes faster".

So, general rule of thumb seems to be:[list]
[*]Default to [b]const ref[/b], [i]unless...[/i]
[list]
[*][i]...[/i]you need to modify the original, then default to regular [b]ref[/b]
[*]...you need to make a copy, then default to [b]by-value[/b] which will sometimes (depending on move constructor) optimize away the copy for temporaries.
[/list]
[/list]
Which was pretty much the same rule of thumb C++ has always had. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
0

Share this post


Link to post
Share on other sites
Read this (including the references -- Boris' three-parter "Efficient argument passing in C++11" is linked to in the blog post):
http://scottmeyers.blogspot.com/2012/10/parameter-types-in-constructors.html
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0