Sign in to follow this  

Why not allways use a const reference?

This topic is 4744 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

if your function's purpose is to modify its args, then you can't pass the args as const.
inline function is similar to macro in that their contents are copied intact and embeded in where they appear in the program. i.e. calling inline functions doesn't require the stack setup, arg retrieval, etc. steps for calling normal functions.

Share this post


Link to post
Share on other sites
But I said const reference, because so it only passes an address and no stack pushing is required,wich gives some speed, and because it's const, it acts like a normal pass-by value. Why doesn't everybody allways use refences then?

Share this post


Link to post
Share on other sites
Quote:
Original post by the_cyberlord
But I said const reference, because so it only passes an address and no stack pushing is required,wich gives some speed, and because it's const, it acts like a normal pass-by value. Why doesn't everybody allways use refences then?

That's what people usually do for user-defined types.

Share this post


Link to post
Share on other sites
Quote:
Original post by the_cyberlord
Wouldn't that be a liiittle bit faster for functions to do that instead of just passing a normal argument?


The main reason people don't is because:
1. Looks messy - when you have a huge program, you dont want it cluttered with "consts"
2. Time consuming - once again, when you are on large scale design, it's just a pain to make everything const, you never know when you will or will not need something to be const
3. Yes it would be faster - but only if you are passing in very large structs (>1kb) - the speed benefits for always passing in const int rather than int are along the lines of 1x10e100+ or so, so your not doing your self any good.
4. Most people don't understand the concept or just don't care, so they won't use it.

Quote:

And another question: What exactly is an inline function? It's a sort of macro, isn't it?


An inline function is a way to make a frequently called function execute more efficiently by telling the compiler to replace all instances of the function call with the code. Defining a function "inline" only **requests** the compiler to make it inline - there is no gaurntee. The ways you can make a function not be inline are - calling another function, using some sort of loop/switch statement, recursion. It is described as a type-safe macro - so it is similar to a macro in terms of what the compiler does with the code, but not the actual use of it.

I hope this helps!

Share this post


Link to post
Share on other sites
Quote:
Original post by the_cyberlord
So if I don't care about consts in my code, or I could use a define for it, it will do SOMETHING?
Yes.
It has three useful purposes.
1. It gives compilers more opportunity for optimisation. Some will, some won't compile various 'const' things better.
2. It helps make things clear to users of a function to know that a parameter is never modified so you know your supplied data is safe from changes by that function. (I would consider this the main reason)
3. It allows compilers spot mistakes in functions you write, where you might accidentally write code which would modify something it shouldn't.

Oh and of course it's only faster when the data type is not the same size as a pointer i.e. an int x is of course faster than a const int &x (assuming the compiler doesn't optimise it as thought it was int x to begin with).

An inline function is a request to the compiler to inline a function. Inlining means that the function's code is compiled into the function that calls it, thus totally eliminating any pushing and poping that might otherwise be required for calling it. This can make the function that calls it bigger, but for very small inlined functions, taking away the pushing and poping otherwise required actually makes it shorter.
It's still not usually quite as fast as putting the function's code as a hash-define though, which of course makes it truly compiled to be part of the caller's code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
3. Yes it would be faster - but only if you are passing in very large structs (>1kb) - the speed benefits for always passing in const int rather than int are along the lines of 1x10e100+ or so, so your not doing your self any good.


this is true only to a degree, but when you are calling a function in your programs main loop (ie, many times over), there will be an increase of:

(hypothetical amount) -> 1x10e100 * <number of times you call>

so if you call 100 times it will be 1x10e102, although this might not seem much, when you are looking for clocks, this may help you

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
1. Looks messy - when you have a huge program, you dont want it cluttered with "consts"


I've bought Core C++, A Software Engineering Approach cheap, to buff up my knowledge of C++ and to use as a reference. I've found it __extremely__ good. And as the title says it's targetted to produce maintainable and readable code, not so much as perfect code.

And in that book the writer advocates heavy usage of the 'const' keyword. Precisely because it gives someone reading the code a clear message that this variable or this function will not modify anything.

I myself don't use it that often yet, but I am trying to use it more often, basically everywhere where it can be used.

Share this post


Link to post
Share on other sites
Another point to note if your using pass by reference for a speed boost is that the reference is essentially a pointer(4 bytes) so if your type is less than 4 bytes it would be quicker just to pass by value.

Share this post


Link to post
Share on other sites
Quote:
Original post by the_cyberlord
But I said const reference, because so it only passes an address and no stack pushing is required


Oh no, no! It passes the address - the push of the address is required. (It's only sizeof (pointer) bytes, so that's not that much, but it's still a push).

And non-const references work exactly the same as those const ones! The difference is that the compiler won't allow you to change the const reference and as it knows its value will not be changed, it may do some more intensive optimization.

Oxyd

Share this post


Link to post
Share on other sites
Quote:
Original post by Moagly
Another point to note if your using pass by reference for a speed boost is that the reference is essentially a pointer(4 bytes) so if your type is less than 4 bytes it would be quicker just to pass by value.


I was under the impression that for most 32 bit processors, it was faster to work with 32 bit values than with smaller pieces.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
It is, yes, and that's what most people already do for user-defined types. A const reference should be your default way to say "input parameter", and a non-const reference is used for "output parameter" or "input/output parameter". Use it, it's
easier to understand than normal arguments when you have identity semantics.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Drew_Benton
1. Looks messy - when you have a huge program, you dont want it cluttered with "consts"


Clean code uses const wherever objects shouldn't be modified.

Quote:

2. Time consuming - once again, when you are on large scale design, it's just a pain to make everything const, you never know when you will or will not need something to be const


A few more time spent at design time avoids hours and hours wasted to track consequences of missing consts afterwards.

Quote:

3. Yes it would be faster - but only if you are passing in very large structs (>1kb) - the speed benefits for always passing in const int rather than int are along the lines of 1x10e100+ or so, so your not doing your self any good.


It's faster but usually speed is not the real problem. It's used because it's the normal way to pass read-only objects. It's just clean and that's the normal way to say "this parameter is meant to be read-only".

Quote:

4. Most people don't understand the concept or just don't care, so they won't use it.


Yes you can write your "C with classes" and compile it with a C++ compiler. Or you can write C++.

Share this post


Link to post
Share on other sites
Quote:
Original post by 0xCHAOS
Quote:
Original post by Moagly
Another point to note if your using pass by reference for a speed boost is that the reference is essentially a pointer(4 bytes) so if your type is less than 4 bytes it would be quicker just to pass by value.


I was under the impression that for most 32 bit processors, it was faster to work with 32 bit values than with smaller pieces.


It *is* faster to work with 32bit values - but with smaller data types - as long as they are a power of 2 - are easily placed into registers and used.

Quote:
Original post by rick_appleton
I've bought Core C++, A Software Engineering Approach cheap, to buff up my knowledge of C++ and to use as a reference. I've found it __extremely__ good. And as the title says it's targetted to produce maintainable and readable code, not so much as perfect code.

And in that book the writer advocates heavy usage of the 'const' keyword. Precisely because it gives someone reading the code a clear message that this variable or this function will not modify anything.

I myself don't use it that often yet, but I am trying to use it more often, basically everywhere where it can be used.


I have no arguments with that - I am on track in college to become a Software Engineer myself. However, software engineering approaches are totally different from general programming. *Normal* users won't be writing code so someone else will be depending so heavily on it. In my opinion and in all honestly, I think const is something that is there to help cover up for carless program design. Take this for example: if you have a large class and several "Get" methods - tradition is to use const so you know that nothing is supposed to be modified and it makes sure nothing is modified. However, part of OO design, is that a class should not know what its data is, so using Get functions in OO programming contexts are wrong as well as messey. I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that (besides the face of how much code it was).

Now in regards to const with variables - you cannot pass const variables into pre-made functions that do not accept 'const' variables - you have to typecast them. For example, if I made a program that accepts a char*, and I used the strings c_str() function, which returns a const char*, I would have to type cast it *every time* I want to use it. It gets really annoying after time to have to contiuously typecast values. It undoubtly addss safety, but hey if you are going to use some function, you should understand its uses and whether or not to modify the values.

Just some ideas of mine [wink]. One thing is that C++ is a lot more complex than they make it seem. There are always exceptions and crazy things you can do. I just recently learned that if yo have a non-virtual function in a class, and it uses/modifies no class data you are allowed to call it via a pointer without allocating new memory! How crazy is that. Anyways best of luck!

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Now in regards to const with variables - you cannot pass const variables into pre-made functions that do not accept 'const' variables - you have to typecast them. For example, if I made a program that accepts a char*, and I used the strings c_str() function, which returns a const char*, I would have to type cast it *every time* I want to use it. It gets really annoying after time to have to contiuously typecast values. It undoubtly addss safety, but hey if you are going to use some function, you should understand its uses and whether or not to modify the values.


const is all part of the whole 'design by contract' method. If your function doesnt change the varible you should let the caller know by making your varibles const. In the example you gave there is a damned good reason why it resturns a cons char *, because that lump of memory shouldnt be changed, you shouldnt be changing and you shouldnt change it, thus why its const. This means your function shouldnt change it, thus it should accept const char * to enforce this and let the compiler check things out. If you need to modify the varible then you should fix your code, not just cast away the const.

Const correctness is VERY important when it comes to design and programming in C++, having recently read Exceptional C++ (and reading More Exceptional C++) I can appricate this alot more, I'd suggest that anyone who wants to learn to program properly in C++ either reads these books and about const correctness or reads the Guru of the Week web pages (dont have a link handy, sorry).

Dismissing it because it 'looks messy' (which, having just converted one of my programs to be const correct isnt remotely true), time consuming (it probably saves time over all, as it removes possible bugs), and worse of all dont use it because they dont understand it should educate themselves and stop being so closed minded and stupid (yes, harsh but having learnt about it I think harshness is a good idea), otherwise as the AP says, you're just going to be programming C-with-classes rather than C++.

Share this post


Link to post
Share on other sites
I think the usage of the const keyword in a programmer's code comes when his knowledge of C++ gets more mature and his will of designing before coding increases. Global design of a project is a must, but designing good abstract data types should not be neglected.

One good practice is obviously to protect (when it makes sense) arguments and return values by making them const. Another good practice is to make a member function const when that function is not meant to modify the implicit object (this) in any way. Good candidates for this are selectors and predicates.

class foo {
public:
int size() const;
};

Share this post


Link to post
Share on other sites
Quote:
Original post by _the_phantom_
... quote ...


Now I know what you are saying, and I have a heck of a lot of books on proper C++ coding stuff (I'm a C++ freak [wink]), but this is all what I have to say. From experience - and I'm talking about a lot of game designing (no games made tohugh [lol])(and I know this is a general forums - thats why our ideas aren't on the same track), the "theorey" of good programming is there to try and help to make some sense of the vastness of C++, but it is just theory - it all changes in practice. Every project is different on its own.

Quote:
If you need to modify the varible then you should fix your code, not just cast away the const.

If you are given code to work with, and it is a C-style program, and you are adding in C++ concepts, if you dont cast it out you have to rewrite the code - now what is easier and more efficient - rewriting C style code that works to get it to comply with some "good programming practice" or type casting it so it is *compatible* ad works the same.

Im not trying to argue with anyone about the importance or use of const - everybody has their own views and ideas which are valid and totally acceptable and I fully respect them. However I'm just saying in my oopinion - from all my experiences that if you *truly* have data that does not need to be modified - then why are you passing it with all the techniques avalaible from OOP and C++. Pertaning to your original question - the only reason I could see to pass an argument as a const& would be if it were of some large size - at which case if you have some data type *that* large to where you need to pass a const refrence to it - then your implementations of designs are flawed. What you should be doing is passing it as a const pointer - that is why c++ gave us the -> operator to use.

Just my views on the matter. Like I said, I do respect everyones views and opinions here [wink]. I guess it just depends on what you are working with.

P.S. If you were working with a char, which is 1 byte - why would you want to pass it by const refrence (4bytes)? Just an idea. It all goes back to the 3 tradeoffs of programming - speed, size, efficiency - I used to think there must be a way not to ssacrifice 2 of them, but not with the way the programming languages are designed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Quote:
Original post by _the_phantom_
... quote ...


Now I know what you are saying, and I have a heck of a lot of books on proper C++ coding stuff (I'm a C++ freak [wink]), but this is all what I have to say. From experience - and I'm talking about a lot of game designing (no games made tohugh [lol])(and I know this is a general forums - thats why our ideas aren't on the same track), the "theorey" of good programming is there to try and help to make some sense of the vastness of C++, but it is just theory - it all changes in practice. Every project is different on its own.


There is truth in what you say - no advice is absolute. That said, avoiding using const saves you little (a few characters of typing) and can cost you much (in debugging - e.g. the infamous if (x = y)).

Quote:
Quote:
If you need to modify the varible then you should fix your code, not just cast away the const.

If you are given code to work with, and it is a C-style program, and you are adding in C++ concepts, if you dont cast it out you have to rewrite the code - now what is easier and more efficient - rewriting C style code that works to get it to comply with some "good programming practice" or type casting it so it is *compatible* ad works the same.


This is one instance where it does make sense to const_cast away the constness. Provided you're 100% sure the function you're passing to won't try to modify the object. In general though _the_phantom_'s advice is good.

Quote:
Im not trying to argue with anyone about the importance or use of const - everybody has their own views and ideas which are valid and totally acceptable and I fully respect them. However I'm just saying in my oopinion - from all my experiences that if you *truly* have data that does not need to be modified - then why are you passing it with all the techniques avalaible from OOP and C++.


I'm not following you here. Why shouldn't you pass it as const?

Quote:
Pertaning to your original question - the only reason I could see to pass an argument as a const& would be if it were of some large size - at which case if you have some data type *that* large to where you need to pass a const refrence to it - then your implementations of designs are flawed. What you should be doing is passing it as a const pointer - that is why c++ gave us the -> operator to use.


It doesn't take that much to get an object large enough that passing by reference is more efficient. A couple of members and a base class is usually more than enough. What advantages do const pointers provide over references? I can't think of any. Why should we prefer pointers to references?

Quote:
Just my views on the matter. Like I said, I do respect everyones views and opinions here [wink]. I guess it just depends on what you are working with.

P.S. If you were working with a char, which is 1 byte - why would you want to pass it by const refrence (4bytes)? Just an idea. It all goes back to the 3 tradeoffs of programming - speed, size, efficiency - I used to think there must be a way not to ssacrifice 2 of them, but not with the way the programming languages are designed.


(quoted for completeness - I make no comment on this part).

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Quote:
If you need to modify the varible then you should fix your code, not just cast away the const.

If you are given code to work with, and it is a C-style program, and you are adding in C++ concepts, if you dont cast it out you have to rewrite the code - now what is easier and more efficient - rewriting C style code that works to get it to comply with some "good programming practice" or type casting it so it is *compatible* ad works the same.


Depends on how likely it is that just casting away a const is going to land you in a world of pain regarding bugs [wink] If its easier to make a change to the calling signature of the function and a couple of adaption in the function, then i'd do that, if I wasnt sure that the function wasnt going to try and modifiy things it shouldnt, then i'd probably call it using the old method and interfaces it into my code some how.
However, thats all a different sitution from designing const correctness into your code from the word go.

Quote:

Pertaning to your original question - the only reason I could see to pass an argument as a const& would be if it were of some large size - at which case if you have some data type *that* large to where you need to pass a const refrence to it - then your implementations of designs are flawed. What you should be doing is passing it as a const pointer - that is why c++ gave us the -> operator to use.


I wouldnt have said so, it depends completely on what you are doing, if I was using a raw pointer to memory than sure pointers are fine, but what about passing around large vectors? or std::strings? Both are large enuff that passing by value is going to be a killer, passing by pointer would work however you have no compiler induced garrentees regarding the use of the object, well, unless you put const in but at which point the question becomes why not use a const & to a vector/string instead of having to get a pointer to it and then dereference it at the other end to use.

Quote:

P.S. If you were working with a char, which is 1 byte - why would you want to pass it by const refrence (4bytes)? Just an idea. It all goes back to the 3 tradeoffs of programming - speed, size, efficiency - I used to think there must be a way not to ssacrifice 2 of them, but not with the way the programming languages are designed.


Well, yeah, for a single built in type using a const ref would be total over kill, as you say, its all about the right tools for the job, personally I'll take a reference over a pointer in the majority of cases and const is certainly a good idea (not just for paramters, const correctness even on fuction names etc).

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that (besides the face of how much code it was).

...
For example, if I made a program that accepts a char*, and I used the strings c_str() function, which returns a const char*, I would have to type cast it *every time* I want to use it.


So. Let me get this straight. You advocate writing huge classes with all public data and no consts. And if perchance some other object ever returns its internal data as const, you should cast it away immediately! It'd be nice if you could #define const to be whitespace... or if VC++ had a checkbox so you could "ignore const", or even "make all data public" to allow easy integration with code written by some const-nazi.


Quote:

It gets really annoying after time to have to contiuously typecast values.


Totally! You would love Lisp.

Although the paretheses... they can be a bit much.

Share this post


Link to post
Share on other sites
I think referencesare the same as pointers, but you can use them as if nothing happened and like you'd be using a normal pass-by value.
But still: Does it give a performance boost when doing it in a while(1){} loop?

Share this post


Link to post
Share on other sites
Quote:
Original post by ajas95
Quote:
Original post by Drew_Benton
I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that (besides the face of how much code it was).

...
For example, if I made a program that accepts a char*, and I used the strings c_str() function, which returns a const char*, I would have to type cast it *every time* I want to use it.


So. Let me get this straight. You advocate writing huge classes with all public data and no consts. And if perchance some other object ever returns its internal data as const, you should cast it away immediately! It'd be nice if you could #define const to be whitespace... or if VC++ had a checkbox so you could "ignore const", or even "make all data public" to allow easy integration with code written by some const-nazi.


I did not say that I advocate writing huge classes with all public data and no consts. That would be a C struct and totally dumb [wink], as well as not being a class first of all. Like I said,*** I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that ***, as in *biiiiiggg mistake (kinfa like microsofts)*. Hopefully you can see that. Second of all, remember KISS (keep it simple, stupid). If you have huge complex classes your just asking for trouble, no matter how careful you are. That is the class design methodology I advocate. Third of all, if you understand the point of type casting from a const-to a non const to ensure *compatibility* with programs that were written with no intention of const to begin with, that is what I'm referring to. If you go and change your functions to comply with STL string, then they are dependend on its implementation. What if the end user doesnt use STL?

My last opinion on this whole matter is that I try not to *assume*. I know that you should not assume that your end user will not need to modify the data passed, who knows what the heck they will be doing [lol]. What if they did? If you are making a base class so users can dervive their own methods from it, it is not a good thing to restrict your users power to control the way the function works by making them pass a const value in order to use the function. Anyways, I'm done expressing my views, that's the beauty of programming, there is no one right way. Its been a pleasure discussing this topic! Hope to see you all around in other threads. Peace.

- Drew

Share this post


Link to post
Share on other sites

This topic is 4744 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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