Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

OK, I'm facing this all the time in many functions I write, which should I use?

void sth(int* a)
void sth(int& a)

Which one is faster, regarding two separate occasions: a is a small variable or a is a large data struct.

I would like a deep answers with pertinence to the actual hardware and stack process.

share|improve this question
 
int& doesn't exist in C. –  mouviciel 2 days ago
 
Is there seriously no int& in C? How is that possible, & and * are very closely linked to each other. Although, this statement does explain my observation why so many codes (cpp and c) use * over & in arguments. Frankly, Ive only seen & a couple of times. –  user209347 16 hours ago

3 Answers

The main semantic differerence between int* and int& is that the former allows passing of NULL or uninitialized values, and the latter does not. So if the function you are going to write does not explicitly has a special need to allow NULL values as input, use int&. In this case using int* increases the risk of passing NULL accidentally, which may result in an error. See also this Wikipedia entry.

Note that you should not make your decision based on which of the 2 alternatives is faster. Your first priority should be correct code, not any micro-optimizations, which I would expect in this case to be neglectable.

share|improve this answer
 
You have to put more effort to pass a NULL (or an uninitialized pointer) for an înt& parameter, but you can do it using * ((int *) 0). –  Giorgio Oct 20 at 12:10
3  
@Giorgio: using references instead of pointers makes unintentional errors unlikely, but if you want to bypass this intentionally, in C++ there are of course always ways to achieve this. –  Doc Brown 2 days ago
 
Gonna cover/recommend the use of const int&, and mention rvalues? And while you're there you could mention right to left reading order (int const&) :-) –  user1158692 2 days ago

Most compilers will implement references as pointers. So the deep answer to your question is that there will be absolutely no difference in terms of performance between the two. (Doesn't change aliasing analysis either as far as I know.)

If you want to be 100% sure of that statement, inspect your compiler's output.

struct Small {
    int s;
};
void foo(Small* s)
{
    s->s = 1;
}
void bar(Small& s)
{
    s.s = 1;
}

Compiled with clang++ -O2, saving the assembly:

_Z3fooP5Small:                          # @_Z3fooP5Small
    .cfi_startproc
# BB#0:
    movl    $1, (%rdi)
    ret
_Z3barR5Small:                          # @_Z3barR5Small
    .cfi_startproc
# BB#0:
    movl    $1, (%rdi)
    ret

You can try that with a large struct or an enormously complex struct - doesn't matter, all you're passing in to the function is a pointer.

That being said, there are semantic differences between the two. The most important one being that, as long as your program is free of undefined behavior, the overload that takes a reference is guaranteed to get a reference to a valid, live object. The pointer overload isn't.

Also assigning to s in these two examples has completely different meanings. It would replace the pointer in the first function (i.e. whatever it pointed to remains unchanged, but becomes unreachable from within that function; caller unaffected by the assignment).
In the second, it would call the appropriate assignment operator en the object passed in (effect visible from the caller).

So your choice shouldn't be made on a potential performance difference (there will generally be none), but on semantics. What you need the function to be able to do, and how you should be able to call it, will dictate what overload(s) you need to provide.

share|improve this answer
 
This answer is very intriguing, especially because you show the low level assembly to substantiate your point! I like that! Basically, using pointers/references won't matter according to you guys, and since reference is safer (and easier, syntax in function is like direct access), ill more likely use those. –  user209347 16 hours ago
 
However, one question, why do so many codes I have seen use pointers over references in arguments? Most functions I see use int sth(sth* sth) instead of &. And I read that when passing large structs, a pointer/reference is faster than just copying the value into your arguments stack, is that true? –  user209347 16 hours ago
 
The fact that you can't pass a null (no object) with a reference parameter can be a reason to use a pointer instead. Passing ownership of something also requires pointers. Interactions/interfaces with C can't use references. And the semantics, as I said, are different. As for copy vs pointer/reference - it depends. You need to benchmark. Optimizers have an easier time when you pass values around. –  Mat 8 hours ago

References are converted to pointers by the compiler so at run time there is no difference in speed. Speed is not the reason you choose references instead of pointers but in fact references might be a bit faster in your overall code simply because you don't need to constantly check for invalid references (NULL pointers).

If a is a small variable (no larger than the machine address size), then there is no difference between a and &a. If a is larger than the machine's address size (e.g. a class object) then &a is faster and &a must be done (rather than a).

Of course you need to consider whether you want to be able to edit a in the called function. If a is large and you want to forbid changing of a, pass a constant reference to a.

If using C++, you should always use references when possible. A good C++ book will list what the difference between references and pointers are. You should consider the following:

References are implemented underneath as pointers. So why use a reference? Because it allows the function writer to determine how a function works without affecting how it is called. With references, the caller of a function doesn't need to know if the function takes a pointer or the object itself. For example, you call the following 2 functions the same way and notice that we can change add1 to use references without affecting all the callers:

int add1 (int a, int b);
int add2 (int &a, int &b) {
// this actually gets converted by the compiler to
// *a + *b
    return a + b;
}

If you were using pointers, you'd have to know that the function is actually taking the address, not the object itself. In other words, references add to information hiding.

So to sum up, references are just syntactic sugar. The compiler will convert all references to pointers and operation to references to valid operations with/on pointers.

Second, unlike pointers - a reference is the object. With pointers, you can change the object pointed to or you can change the pointer itself (in which case it will point to something else). With a reference there's only one thing you can change - the referred object.

Third, references cannot be re-assigned to refer to another object like a pointer can. Often, in linked lists you have to move pointers forward/backwards. You can't do this with a reference. Think of a reference as an alias to an object.

Lastly, about the NULL...in C code you will see a lot of NULL pointer checking. References are meant to help with that by allowing the compiler to catch whenever a reference doesn't refer to a valid object. The C++ standard also says that a reference cannot point to an invalid object (e.g. a NULL). However, I think it's up to the compiler on how it implements that so you need to double check with your compiler. I think some compilers will not even warn you.

share|improve this answer
 
The answer is inconsistent. If references are implemented underneath as pointers, how can pointers be faster than references. –  Bart van Ingen Schenau Oct 20 at 10:33
 
I meant &a vs just a at the beginning. I've corrected it. –  s5s Oct 20 at 10:57
 
I still find that paragraph confusing and it does not seem to add any value to your answer. I would remove it if I were you. –  Bart van Ingen Schenau 2 days ago
 
There is nowhere in the C++ standard that says references have to be implemented as pointers. However it does explicitly state that whether or not references even require storage at all is an implementation detail. –  bstamour yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.