why reference ?

W

William Xuuu

Hi,

References introduced make things much more complicated. e.g.

int a;
void f(int &n);
void g(int *p);

Isn't g(&a) much more clear than f(a), when we would change the value of
the lvalue a ?

Are there any efficiency differences ?

Is reference a must in c++ ?

thanks.
 
K

Karl Heinz Buchegger

William said:
Hi,

References introduced make things much more complicated. e.g.

int a;
void f(int &n);
void g(int *p);

Isn't g(&a) much more clear than f(a), when we would change the value of
the lvalue a ?

Clearity is in the eye of the beholder :)
Seriously. It depends. In your above example it definitly is
not clear to the caller if

f(a)

will change 'a' or not.

But in practice this is much less an issue then you think. Mostly
because in real life functions are not called 'f' and arguments are
not called 'a'. In

j = CalcFibonacci( InputNumber );

will the function CalcFibonacci alter the passed argument? While
there is no 100% guarantee, bets are good, that it won't.

Same for eg. the prototype

void Deposit( Account& TheAccount, long Amount );

Now guess: Will The Account be changed when the function is called.
If you read the callers code:

Account CustomerAccount;
long Amount;

CustomerAccount = AskForCustomer();
Amount = AskForAmount();

Deposit( CustomerAccount, Amount );

When you read that code, and have no idea that the first argument
to Deposit is passed by reference, would you expect CustomerAccount
to change? Sure I would! If I deposit something on an account, then
the amount associated with that account changes.
Are there any efficiency differences ?

When you pass a pointer, it is the functions responsibility to at
least check that the passed pointer is not 0. On the other hand,
if you pass per reference AND the function gets inlined, you open
a lot of possibilities for the compiler for optimizations.
Is reference a must in c++ ?

Yes. Otherwise writing custom operators would not be possible.
Granted, we could live without that feature (although it is a
nice one) and then AFAIK there would be no killer argument for
not dropping references.
 
T

Thomas Barth

Are there any efficiency differences ?

Is reference a must in c++ ?

Reference variables can be created for local use as aliases
for other variables within a function. Reference variables must
be initialized in their declarations, and they cannot be reassigned
as aliases to other variables. Once a reference variable is
declared as an alias for another variable, all operations performed
on the alias actually are performed on the variable.
As a former java-coder I can say that pointers are needless :)

Thomas B.
 
T

Tilman Kuepper

Hi William,
Isn't g(&a) much more clear than f(a), when we would change
the value of the lvalue a ?

Are there any efficiency differences ?

If a function has to change a variable via a pointer, the function
has to check for null-pointers first. For example...

void Change(int* pVal)
{
if(pVal)
*pVal = 123;
else
throw SomeException;
}

Okay, but perhaps you are writing a function where it is
not allowed to pass null-pointers as parameters. In this
case you have to add some documentation to your function
where this pre-condition is described. You should still
use assert() before accessing the pointer, though...

With references all this is not necessary. If you declare
a function like...

void Change(int& val);

....then it is simply not possible to call this function with a
null-pointer.

Tilman
 
J

John Harrison

William Xuuu said:
Hi,

References introduced make things much more complicated. e.g.

int a;
void f(int &n);
void g(int *p);

Isn't g(&a) much more clear than f(a), when we would change the value of
the lvalue a ?

Are there any efficiency differences ?

Is reference a must in c++ ?

Try writing an assignment operator using a pointer.

class X
{
X& operator=(const X* rhs);
};

Then you would then have to write

X x, y;
x = &y;

Do you think that is good style?

References and pointers are different. The main difference is that a
reference once initialised cannot be made to refer to something else. This
is often exactly what you want, and makes using references very common, it
also makes the syntax simpler.

john
 
G

Gernot Frisch

As a former java-coder I can say that pointers are needless :)

double GetFirstNegative(double* pNums)
{
while(*pNums>0.0) ++pNums;
return *pNums;
}

Try that with references and compare the assembly generated.
 
A

Arijit

Gernot said:
double GetFirstNegative(double* pNums)
{
while(*pNums>0.0) ++pNums;
return *pNums;
}

Try that with references and compare the assembly generated.

How about:

double GetFirstNegative(double* pNums)
{
int i=0;
while(pNums>0.0)
++i;
return pNums;
}

No pointers, no references. Agreed, has an extra variable.

It is very rare in C++ that a pointer is truly needed. Almost all the
time you can get around using references or [].
 
T

Thomas Barth

Hi
double GetFirstNegative(double* pNums)
{
int i=0;
while(pNums>0.0)
++i;
return pNums;
}


Pointer free, array passed by reference

double getFirstNegative(double arr[]) {


Thomas B.
 
J

Jon Bell

References introduced make things much more complicated. e.g.

That depends on your point of view. :)

I came to C++ from Fortran and Pascal, which use reference semantics
(although not the same syntax as C++ of course) for passing data to
functions. I find references to be natural to use, whereas pointers are
cumbersome and error-prone.
 
T

Thomas Barth

And you should always consider the size of an array

double getFirstNegative(double arr[], int &iSize) {
double dValue = 0.0;
for (int i = 0; i < iSize && dValue == 0.0; i++) {
if(arr < 0.0) dValue = arr;
}
return dValue;
}

I am not a friend of code compression :) Your code versions
would throw an OutOfBound-exception

Thomas B.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

William said:
int a;
void f(int &n);
void g(int *p);

Isn't g(&a) much more clear than f(a), when we would change the value of
the lvalue a ?

Yes, but if you name the function evaluate_something instead of f things
will be much more clear.
 
A

Andrew Koenig

Julián Albo said:
Yes, but if you name the function evaluate_something instead of f things
will be much more clear.

For example:

std::cin >> a;

Isn't this clearer than having to write

std::cin >> &a;

?
 
L

Lionel B

John said:
References and pointers are different. The main difference is that a
reference once initialised cannot be made to refer to something else.

....and perhaps equally important (as several posters have pointed out),
a reference *must* be initialised.

And hence may be assumed to refer to something sensible... oops, maybe
not:

int* p = new int(5);
int& i = *p;
delete p;

I note that the following program:

<CODE>

#include <iostream>

int main()
{
int* p = new int(5);
int& i = *p;
std::cout << "i = " << i << '\n';
delete p;
p = new int(6);
std::cout << "i = " << i << '\n';
delete p;
return 0;
}

</CODE>

outputs:

i = 5;
i = 6;

on my system - but I suspect that this is actually UB and it is
fortuitous that the second new allocated the same address as the
first...
 
A

Arijit

Thomas said:
And you should always consider the size of an array

double getFirstNegative(double arr[], int &iSize) {
double dValue = 0.0;
for (int i = 0; i < iSize && dValue == 0.0; i++) {
if(arr < 0.0) dValue = arr;
}
return dValue;
}

I am not a friend of code compression :) Your code versions
would throw an OutOfBound-exception

Thomas B.


I was replying to Gernot's post. I made as minimal changes as possible
to the program to get to it work without pointers.

Actually, my code will not throw any exception, the whole thing will
just crash. On Linux, probably the famous "Segmentation fault. Core dumped."

-Arijit
 
T

Thomas Barth

Actually, my code will not throw any exception, the whole thing will just crash. On Linux, probably the famous "Segmentation
fault. Core dumped."

It's embarrassing that a coder presents code that "just crashs". Do you know
exception handling? Remember, the topic of this thread-child is that pointers
are needless. You showed us a crashy solution with a pointer.
Shake your head and wake up!

Thomas B.
 
A

Arijit

Thomas said:
It's embarrassing that a coder presents code that "just crashs". Do you know
exception handling? Remember, the topic of this thread-child is that pointers
are needless. You showed us a crashy solution with a pointer.
Shake your head and wake up!

Thomas B.

I know exception handling. The point is that no exceptions will be
thrown in this case. And I showed a solution without explicit pointers.
No out-of-bound exception will be generated, even when you access
elements outside the array bounds.

And you miss the whole point of my reply. The message I replied to had
this ->
double GetFirstNegative(double* pNums)
{
while(*pNums>0.0) ++pNums;
return *pNums;
}

Try that with references and compare the assembly generated.

Which I changed to ->
double GetFirstNegative(double* pNums)
{
int i=0;
while(pNums>0.0)
++i;
return pNums;
}

No pointers, no references. Agreed, has an extra variable.


I probably should have written double GetFirstNegative(double pNum[]),
but thats besides the point. What I tried to do was the change the code
already posted to work without pointers, while keeping the structure of
the original code unaltered. Thats why I did not use range checking,
because the original code didn't have it. And the way the code is
written, range checking is unnecessary if you use sentinels.


-Arijit
 
T

Thomas Barth

I probably should have written double GetFirstNegative(double pNum[]), but thats besides the point. What I tried to do was the
change the code already posted to work without pointers, while keeping the structure of the original code unaltered. Thats why I
did not use range checking,

Who said to keep the structure of the code? :) Of course you have
to change the programming style as well, if you want to pass on pointers.
That's the deal with it.

Have a nice evening :)

Thomas B.
 
M

Markus Elfring

Are there any efficiency differences ?

Do you check the pointer in g() for a non-zero value?
This safety check can be avoided and omitted by the passing of the
arguments by reference.
 
O

Old Wolf

double GetFirstNegative(double* pNums)
{
int i=0;
while(pNums>0.0)
++i;
return pNums;
}

No pointers, no references. Agreed, has an extra variable.


This still uses a pointer. pNums is a pointer. The fact that
there is no '*' symbol in the code does not change this.
pNums is the same as: *(pNums + i)
Pointer free, array passed by reference

double getFirstNegative(double arr[]) {

In this case, arr is a pointer. This is identical to the
original declaration.

To pass an array by reference you need to write:
double foo( double (&arr)[10] )
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,184
Messages
2,570,973
Members
47,528
Latest member
AnaHawley8

Latest Threads

Top