gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Difference between * and &

#154755 - brave_orakio - Mon Apr 21, 2008 8:45 am

Hi guys its me again. Something thats been bothering me is what is the difference between function declarations:

Code:


   function(int &variable1,struct  &variable2,....)



and

Code:


   function(int *variable1,struct  *variable2,....)



???
Both of these are pass by reference but is there any performance gain on using either one of those over the other? Or even advantages or disadvantages?
_________________
help me

#154760 - Lick - Mon Apr 21, 2008 9:48 am

They say & is faster. But with * you can pass null-pointers.
_________________
http://licklick.wordpress.com

#154761 - kusma - Mon Apr 21, 2008 10:07 am

Lick wrote:
They say & is faster.

Who are "they"?

Quote:
But with * you can pass null-pointers.

Technically, you can pass null-pointers as references as well, but in general people use references as a kind of a non-null pointer.

#154763 - nanou - Mon Apr 21, 2008 1:01 pm

Given the question, you haven't read this: http://www.parashift.com/c++-faq-lite/references.html

Assuming you understand pointers, that should clear it up.
_________________
- nanou

#154772 - Dwedit - Mon Apr 21, 2008 4:13 pm

The one with the *'s is a declaration of the function, saying that this function takes pointers.
The one with the &'s is someone calling the function with references to objects.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#154776 - nanou - Mon Apr 21, 2008 4:55 pm

Dwedit wrote:
The one with the *'s is a declaration of the function, saying that this function takes pointers.
The one with the &'s is someone calling the function with references to objects.


Not if he meant what he said above by these being function declarations. If you don't follow, check the above link.
_________________
- nanou

#154783 - Dwedit - Mon Apr 21, 2008 6:33 pm

dah, I was thinking in C, obviously this is different in C++...
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#154786 - nanou - Mon Apr 21, 2008 6:54 pm

To be fair, that was my immediate impression too.
_________________
- nanou

#154793 - simonjhall - Mon Apr 21, 2008 7:44 pm

I never use references (I find it very hard to not use C), so a couple of (long-winded) questions:

1) I guess it's ABI-specific, but how do references get passed as arguments to a function? With a regular value it's loaded into the relavent register that corresponds to that argument, and with a pointer the address is loaded into that register. What happens with a reference? Is it handled exactly like a pointer? (I use a lot of asm at work)
2) if you have a prototype to a function that's declared extern "C", can you use references in the prototype, even if the actual function is written in assembler?
3) are references really worth it over pointers? It's just NULL checking that you don't have to do, right?

Finally,
do any other people who learnt C first (esp from a young age) have this unexplainably-stubborn resistance to using C++? I find it really difficult using const, references, STL etc. I'm not sure why...
_________________
Big thanks to everyone who donated for Quake2

#154795 - silent_code - Mon Apr 21, 2008 7:55 pm

when using a reference (& for a parameter), you don't have to use the adress operator (again, &) in the function call.

there were no references in c at all.

in c++ you can do stuff like:
Code:
int x = 15;
int &r = x; // acts like a pointer to x, but you can use it just like x, e.g.
r++; // x = 16


that also means, when you're passing structs (or classes) to functions, you can use the '.' access operator for members, instead of the '->' operator.
also note, that references can't be "reset" to other variables, once they have been initialized. (look at the initialisation, then you should know why.)

so, references are indirect pointers and can be seen as a pure language (or specifically pointer) "extension" (with it's own restriction). it's simply put another syntax for pointers, with a slightly different "target".

#154803 - nanou - Mon Apr 21, 2008 8:45 pm

simonjhall wrote:
Finally,
do any other people who learnt C first (esp from a young age) have this unexplainably-stubborn resistance to using C++? I find it really difficult using const, references, STL etc. I'm not sure why...

I feel the same way. Usually I'll be 1/2 through writing a class definition and say to myself "if this were C I'd be done by now." And then go do it in C. When writing something huge and complex I can see the use of it, but I still don't bother.
_________________
- nanou

#154810 - PeterM - Mon Apr 21, 2008 9:27 pm

I sometimes think that I would prefer to use C instead of C++. Then I remember having to use it in my old job and getting rather tired of writing Yet Another Container by hand.

In my head, C++'s strengths (at least compared to C) are templates, the STL and ability to use techniques like RAII.

It's all just a matter of preference.
_________________
http://aaiiee.wordpress.com/

#154835 - Miked0801 - Tue Apr 22, 2008 12:06 am

I'm a C to C++ guy for sure. I'm still having issues with the finer points of template fun and some the the syntax sugar. Still, I see the benefits of C++ and like all things, the more you practice, the better you become. Keep in mind that the same mindset for C++ will help you when playing in C# and all the other, newer languages.

#154843 - wintermute - Tue Apr 22, 2008 12:49 am

simonjhall wrote:

What happens with a reference? Is it handled exactly like a pointer? (I use a lot of asm at work)


From an assembly perspective references and pointers are exactly the same thing.

Quote:

2) if you have a prototype to a function that's declared extern "C", can you use references in the prototype, even if the actual function is written in assembler?


You can, yes. You'll only be able to compile the code as C++ though, references aren't available in C.

Quote:

3) are references really worth it over pointers? It's just NULL checking that you don't have to do, right?


Look at the code for pointers versus references, which one is simpler? ( Hint: you don't have to dereference a reference ;) )

Quote:

Finally,
do any other people who learnt C first (esp from a young age) have this unexplainably-stubborn resistance to using C++? I find it really difficult using const, references, STL etc. I'm not sure why...


I learned assembly first then reluctantly learned C much later than I should have. Currently I still have a mindset where most of the common advantages cited for C++ seem like huge disadvantages to me. One of the biggest issues I have is how awkward it feels to design a class and how long I spend messing around tweaking the interface. Overloaded methods are cool though.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#154853 - silent_code - Tue Apr 22, 2008 1:22 am

i like c.
i like c++.
i also like other languages, but that's unimportant right now.

what i like about c the most: it's power and simplicity.
what i like about c++ the most: it's extended syntax.

so in the end, i try to write straight forward, simple and (as) clean (as possible) c++ programs.

new and delete rule, too. ;^) actually that was the reason i moved to c++, i was fed up with *alloc() and free() and classes, overloading and references seemed like a good idea. ;^D

#154855 - Dwedit - Tue Apr 22, 2008 1:25 am

In my opinion, C++'s best feature is destruction when stuff goes out of scope. Makes it so you don't need to think about freeing stuff.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#154858 - silent_code - Tue Apr 22, 2008 1:47 am

wooooh! a good one. that was actually what i implicitly meant by "classes". you don't have to call a damn deinitialization function every time you need to free a class. :^) it makes memory management a bit easier when a class cleans up after it's done. ;^)

@ tpls: hahahaha. :^D


Last edited by silent_code on Tue Apr 22, 2008 2:00 am; edited 1 time in total

#154862 - tepples - Tue Apr 22, 2008 1:55 am

sc: You're right about that. It's too bad that the C++ community has adopted "RAII" as the name for a destructor idiom that's so useful, because it sounds too much like RIAA, which could use a different kind of destructor.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#154865 - brave_orakio - Tue Apr 22, 2008 2:20 am

Ah yes thank you, that clears things up. I actually saw this kind of declaration at work(Maintenance work, so I see both C and C++ programs) and I got confused with it.

I am primarily a C programmer, so I wasn't familiar with that kind of declaration. OOP is still a bit confusing to me! Especially Java! but that's getting of topic.
_________________
help me

#154868 - nanou - Tue Apr 22, 2008 3:11 am

Maintaining random things? I'm familiar with that position. There's a particular kind of dread that goes along with it. "I'm not a qualified Java programmer, why are you asking me to do this?" That sort of thing. It doesn't help on the occasions that you discover that the original author most certainly wasn't either...
_________________
- nanou

#154908 - sajiimori - Tue Apr 22, 2008 8:52 pm

simonjhall,

The main "required" use of references is for overloading unary operator* and operator[] -- you can't emulate a pointer or array without references.

I avoid non-const references in all other cases because I find them misleading (who's modifying what again?). I use const references as a prettier version of pointers if and only if it's just as an optimization of pass-by-value, with no semantic relevance to the client (e.g. they don't need to worry about object lifetimes).

About transitioning from C to C++, I didn't look beyond C until I felt constrained by my own mental limitations. I'm a total amnesiac -- I'm not good at keeping track of a lot of things at once. At the time, I thought I was not smart enough to be a programmer.

It turned out that I just needed to reduce the amount of things I have to keep track of. I needed ways to wrap things up and formalize them with compiler-enforced rules that allow me to safely forget the largest possible amount of information, and to quickly re-understand it as necessary.


Last edited by sajiimori on Wed Apr 23, 2008 3:02 am; edited 2 times in total

#154922 - Miked0801 - Tue Apr 22, 2008 11:32 pm

You need a stack upgrade :)

Of course, my own stack leaks quite a bit as well. Good points there Saji.

#154925 - silent_code - Tue Apr 22, 2008 11:48 pm

second that!

#155267 - gmiller - Sun Apr 27, 2008 4:21 pm

As an aside to the passing of pointers and the use of "const", it "can" reduce the influence of pointer aliasing within you code and help reduce compiler paranoia.

The less paranoid the compiler the cleaner the generated code, since the compiler is striving to "do no harm" to the logic you write it tries to prevent issues with pointer dereferenced data from impacting doing what your code describes.

#155319 - sajiimori - Mon Apr 28, 2008 6:02 am

I can't think of any situations where the compiler can safely make extra assumptions based on the constness of a pointer argument. Are you thinking of 'restrict'?

#155322 - keldon - Mon Apr 28, 2008 7:27 am

Hmm, well const char * will invoke const methods, so you could get a much faster implementation somewhere down the line; besides it helps you avoid any knock on effects when you use const-correct methods/classes, stopping the compiler from shouting at you!

#155324 - PeterM - Mon Apr 28, 2008 8:21 am

Hmm, I'm really not sure about pointer/reference parameters being const having any real world performance benefit.

While in theory it should be possible to optimise out extra reads/writes, when it comes to the crunch, the compiler can't normally be 100% sure that the variable isn't being modified elsewhere and is forced to assume it's aliased. That's what the restrict keyword is all about.
_________________
http://aaiiee.wordpress.com/

#155333 - gmiller - Mon Apr 28, 2008 12:58 pm

The concept of pointer aliasing deals with having two pointers that point to the same data. In any function call the compiler has to "assume" that any two pointers "can" point to the same data and act accordingly.

If pointers are passed to a function then the compiler has to assume that any data that is holds dereferenced using that pointer "could" have changed. Therefore the compiler will insert extra code to get the data again if it "could" change. This can be a big impact on RISC machines since the only thing you can do to main memory is read from it and save to it, all other manipulations requires putting the data in a register.

With the const key word on the function parameter the data does not have to be re-retrieved if it is being held locally or in a register. This is because you guaranteed with the "const" keyword it would not.

#155334 - PeterM - Mon Apr 28, 2008 1:11 pm

If I understand you correctly, which I think I do, that's not what const means at all.

Const is a "promise" (and really not even that, given that you could cast the parameter to non-const and do as you like) that you will not modify a variable. It does not indicate that something else will not modify the variable, so the compiler has no choice but to re-fetch it if it may have changed.

I'd be really surprised if you can show me a situation where marking a parameter as pointing to a const reduces aliasing.
_________________
http://aaiiee.wordpress.com/

#155335 - kusma - Mon Apr 28, 2008 1:23 pm

gmiller: const is as pointed out pure programmer-semantic, and should not affect the code-generation. Are you sure you're not thinking of the pointer/reference difference? A reference should in theory reduce aliasing, since it is conceptually a pointer to a single object, unlike a normal pointer that can also point to an array of unknown size. The compiler basically has no other choice for normal pointers than to assume that the array occupies the entire already-allocated memory, and thus aliases with all existing pointers / references. I'm not entirely sure how the strict-aliasing rules in C++ affects this, though.

#155337 - gmiller - Mon Apr 28, 2008 1:28 pm

Well I am combining two different things here and the const on a parameter inside of a function does not reduce aliasing inside of the function, extra data retrieval (you have to use a local var to hold the dereferenced value, assuming that it is not changing), but it does reduce the retrieval across function calls. It is true there is no guarantee that we do not break the "const" condition but from the calling code it has to assume it will not so the compiler can act accordingly. This can create some ugly bugs. I guess I have combined multiple things into aliasing that might not be strictly in the single concept but have always in my training been grouped together under aliasing. Of course 'const' is a compile time concept and only controls how the compiler will generate code but has no runtime component (other than the way the code was generated).

#155338 - tepples - Mon Apr 28, 2008 1:32 pm

PeterM wrote:
Const is a "promise" (and really not even that, given that you could cast the parameter to non-const and do as you like) that you will not modify a variable. It does not indicate that something else will not modify the variable

What sort of "something else" are you talking about? Are you talking about the kind of situation that would need the 'volatile' qualifier, such as hardware registers or memory shared between threads?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#155339 - PeterM - Mon Apr 28, 2008 1:46 pm

Nope, my point was only that const is a programmer "correctness" aid and is really unlikely to affect code optimisation.

My reference to "something else" was really a nudge about aliasing (in that "restrict" is the keyword needed to tell the compiler that nothing else will alias the variable) and that const isn't related.
_________________
http://aaiiee.wordpress.com/

#155346 - pepsiman - Mon Apr 28, 2008 5:45 pm

In C++, const is part of the function signature, so it can cause a different function to be called.
operator [] is much slower on non-const stl::strings than const stl::strings.

#155347 - sajiimori - Mon Apr 28, 2008 6:05 pm

gmiller, I'm with PeterM on this one: a const pointer just means you can't modify the object via that pointer -- there could easily be other pointers to the same object, maybe even in global scope. Obviously, you can copy out the value into a local variable yourself, but short of compiler-specific __pure function attributes (or whatever), the compiler can't help you here.

kusma, I also can't think of a way that the compiler can safely make additional assumptions based on an argument being a reference. There can be two references to the same object, a reference and a pointer to the same object, a reference into an array, and so on -- no reduction in aliasing that I can think of. Care to give an example?

Edit: I realize I'm completely ignoring the trivial fact that calling a different function results in different code being generated.

#155352 - kusma - Mon Apr 28, 2008 7:04 pm

sajiimori wrote:
kusma, I also can't think of a way that the compiler can safely make additional assumptions based on an argument being a reference. There can be two references to the same object, a reference and a pointer to the same object, a reference into an array, and so on -- no reduction in aliasing that I can think of. Care to give an example?

When I try to construct a case, I realize that you seem to be absolutely right. I'm unable to use that info for anything useful :)

edit: by "that info" I mean that it's pointing to a single element.