473,394 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

pass by ref vs pass by pointer

HI all,

Whats the difference b/w pass by ref and pass by pointer in C++ when
ur passing objects as args..

Cheers..

Aug 17 '05 #1
38 4571
Radde wrote:
Whats the difference b/w pass by ref and pass by pointer in C++ when
ur passing objects as args..


A reference always refers to a valid object, according to language rules.
The difference is that when inside a function, if the argument is a ref,
you can rely upon it being a real object. If it's a pointer, it can have
an invalid value or be null.

V
Aug 17 '05 #2
Victor Bazarov wrote:
Radde wrote:
What's the difference between pass by reference and pass by pointer in C++
when you are passing objects as arguments.
A reference always refers to a valid object, according to language rules.
The difference is that, when inside a function, if the argument is a reference,
you can rely upon it being a real object.

cat main.cc #include <iostream>

void f(const int& r) {
std::cout << "r = " << r << std::endl;
}

int main(int argc, char* argv[]) {

int* p = 0;
int& r = *p;
f(r);

return 0;
}
g++ -Wall -ansi -pedantic -o main main.cc
./main Segmentation fault (core dumped)
If it's a pointer, it can have an invalid value or be null.

Aug 17 '05 #3
E. Robert Tisdale wrote:
Victor Bazarov wrote:
Radde wrote:
What's the difference between pass by reference and pass by pointer
in C++
when you are passing objects as arguments.

A reference always refers to a valid object, according to language rules.
The difference is that, when inside a function, if the argument is a
reference,
you can rely upon it being a real object.

[...example invoking undefined behaviour removed...]


We're are talking valid programs with defined behaviour here.
Aug 17 '05 #4
NULL references are unbelievably easy in C++...

So, you can't always rely on the fact that if an argument is a
reference that it msut be a real object.

Please see the link:

http://discuss.fogcreek.com/joelonso...w&ixPost=63717

This link provides the follwing example:

function Test(const SomeClass& param)
{
param.Method();
}

someClass* instance = SomeOperation();
Test(*instance );

--/ snip /--

If SomeOperation returns a NULL pointer than the reference in the Test
method will be null. This is very common. Of course, this doesn't
apply to references which are not function arguments.

Almost Anonymous
Wednesday, August 13, 2003

Aug 17 '05 #5
Frank Chang wrote:
NULL references are unbelievably easy in C++...
Not in a valid program...
[..]

Aug 17 '05 #6
Victor Bazarov wrote:
E. Robert Tisdale wrote:
Victor Bazarov wrote:
Radde wrote:

What's the difference
between pass by reference and pass by pointer in C++
when you are passing objects as arguments.

A reference always refers to a valid object,
Apparently, a vacuous statement.
according to language rules.
The difference is that, when inside a function,
if the argument is a reference,
you can rely upon it being a real object.


[...example invoking undefined behavior removed...]


We're are talking valid programs with defined behavior here.

Aug 17 '05 #7
E. Robert Tisdale wrote:
> cat main.cc #include <iostream>

void f(const int& r) {
std::cout << "r = " << r << std::endl;
}

int main(int argc, char* argv[]) {

int* p = 0;
int& r = *p;


At this point, you enter the realm of undefined behavior. Everything
afterwards is not covered by the C++ standard anymore. Anything can happen.
Note that the behavior is already undefined _before_ f() is called.
So your program is not a valid example for passing a "null reference" to a
function.
f(r);

return 0;
}
> g++ -Wall -ansi -pedantic -o main main.cc
> ./main

Segmentation fault (core dumped)
If it's a pointer, it can have an invalid value or be null.


Aug 17 '05 #8
Rolf, But in this code snippet from my earlier post on null references,
function Test(const SomeClass& param)
{
param.Method();
} someClass* instance = SomeOperation();
Test(*instance );


If the someClass pointer, instance, is NULL, then the argument passed
by reference to Test will technically a null reference. The argument
passed to Test, *instance , is not evaluated until the function
references the argument inside the function body.

Aug 17 '05 #9
Victor Bazarov wrote:
A reference always refers to a valid object, according to language rules.
The difference is that when inside a function, if the argument is a ref,
you can rely upon it being a real object. If it's a pointer, it can have
an invalid value or be null.

V


void foo(Object& obj)
{
// ... do something to obj
}

int main()
{
Object* o = 0;

foo(*o);

return 0;
}

Oops, seg-fault...

Any time you deal with pointers you can have invalid objects and it's
almost impossible to not deal with pointers at some point.

Jo
Aug 17 '05 #10
Jojo wrote:
Victor Bazarov wrote:
A reference always refers to a valid object, according to language rules.
The difference is that when inside a function, if the argument is a ref,
you can rely upon it being a real object. If it's a pointer, it can have
an invalid value or be null.

V

void foo(Object& obj)
{
// ... do something to obj
}

int main()
{
Object* o = 0;

foo(*o);

return 0;
}

Oops, seg-fault...


Not on my system? Your program has undefined behaviour that exhibits
itself as a "seg-fault" on your system. On my system no "seg-fault"
happens, but the behaviour of your program is still _undefined_. That
means that the program cannot be governed by the rules of C++ language.
That by inference, says that according to the rules of C++ language there
can be no null references in a valid program.
Any time you deal with pointers you can have invalid objects and it's
almost impossible to not deal with pointers at some point.


I am not sure what to make of this comment of yours. Are you just
repeating what I said about pointers?

V
Aug 17 '05 #11
Victor Bazarov wrote:
Not on my system? Your program has undefined behaviour that exhibits
itself as a "seg-fault" on your system. On my system no "seg-fault"
happens, but the behaviour of your program is still _undefined_. That
means that the program cannot be governed by the rules of C++ language.
That by inference, says that according to the rules of C++ language there
can be no null references in a valid program.


It doesn't have to be NULL to crash. It could point to delete'd memory,
it could just point to an uninitialized object.

"Valid" program doesn't make any sense. If everyone wrote 100% perfect
"valid" code then nothing would ever crash and we would all be running
perfect software. Never happens and is the reason why people invent
"safe" languages like Java et al. For this reason references do not
make your code inherently safer (or even better) as you implied.
Any time you deal with pointers you can have invalid objects and it's
almost impossible to not deal with pointers at some point.

I am not sure what to make of this comment of yours. Are you just
repeating what I said about pointers?

V


Yes and I'm adding that it's impossible not to deal with pointers.

Jo
Aug 17 '05 #12

Frank Chang wrote:
Rolf, But in this code snippet from my earlier post on null references,
function Test(const SomeClass& param)
{
param.Method();
}someClass* instance = SomeOperation();
Test(*instance );


If the someClass pointer, instance, is NULL, then the argument passed
by reference to Test will technically a null reference. The argument
passed to Test, *instance , is not evaluated until the function
references the argument inside the function body.


Not according to the c++ standard (1.8.18):
"When calling a function (whether or not the function is inline), there
is a sequence point after the evaluation
of all function arguments (if any) which takes place before execution
of any expressions or statements in
the function body"

So you don't technically have a "null reference" you have undefined
behaviour when you dereference the instance pointer and before the
function is actually called.

Aug 17 '05 #13

Frank Chang wrote:
NULL references are unbelievably easy in C++...


No, it is unbelievably easy to invoke undefined behaviour in c++, if
you choose to do so. The undefined behaviour occurs before any "null
reference".

Aug 17 '05 #14
Jojo wrote:
Victor Bazarov wrote:
Not on my system? Your program has undefined behaviour that exhibits
itself as a "seg-fault" on your system. On my system no "seg-fault"
happens, but the behaviour of your program is still _undefined_. That
means that the program cannot be governed by the rules of C++ language.
That by inference, says that according to the rules of C++ language there
can be no null references in a valid program.

It doesn't have to be NULL to crash. It could point to delete'd memory,
it could just point to an uninitialized object.


Yes, IOW, invalid.
"Valid" program doesn't make any sense.
Really? Makes no sense to you, eh? Strange. The entire C++ language
Standard is written that describes valid programs. If there were no
valid programs, or the concept would make no sense, we'd have no language
Standard. Yet we do. Everybody involved in it probably is out of their
mind.
If everyone wrote 100% perfect
"valid" code then nothing would ever crash and we would all be running
perfect software.
No. There are other errors. Like overflow. Division by zero. Absence
of a file when you try opening it. And so on, without end. And those
situations need to be dealt with _after_ the program that deals with them
is made _valid_.

Yes, a valid program shouldn't "crash". And I bet there are programs that
just do not crash. They report critical situations, work their way out of
them, and so on.
Never happens and is the reason why people invent
"safe" languages like Java et al.
No trolling here, please.
For this reason references do not
make your code inherently safer (or even better) as you implied.


Yes, they do. If I never write any pointer-based code (which is possible)
and instead rely on the libraries supplied with the compiler to do it
correctly, I needn't worry about problems with references. My code is
safe as long as I don't hang onto references that can become invalid.
Any time you deal with pointers you can have invalid objects and it's
almost impossible to not deal with pointers at some point.


I am not sure what to make of this comment of yours. Are you just
repeating what I said about pointers?

V

Yes and I'm adding that it's impossible not to deal with pointers.


I do not agree.
---------------------------
#include <iostream>

int main() {
std::cout << "Hello world" << std::endl;
}
---------------------------
Look, Ma, no pointers!

V
Aug 17 '05 #15

Jojo wrote:
Victor Bazarov wrote:
Not on my system? Your program has undefined behaviour that exhibits
itself as a "seg-fault" on your system. On my system no "seg-fault"
happens, but the behaviour of your program is still _undefined_. That
means that the program cannot be governed by the rules of C++ language.
That by inference, says that according to the rules of C++ language there
can be no null references in a valid program.


It doesn't have to be NULL to crash. It could point to delete'd memory,
it could just point to an uninitialized object.

"Valid" program doesn't make any sense.
If everyone wrote 100% perfect
"valid" code then nothing would ever crash and we would all be running
perfect software. Never happens and is the reason why people invent
"safe" languages like Java et al. For this reason references do not
make your code inherently safer (or even better) as you implied.


But it does change when such an error may occur and therefore where the
responsibility for ensuring you have a valid object lies:

foo(SomeObj & a)
{
a.func();
}

bar(SomeObj * a)
{
a->func();
}

int main()
{
SomeObj * a;
foo(*a);
bar(a);
}

In the above the undefined behaviour is invoked for foo in the calling
code, for bar the undefined behaviour is in it's function body at the
member function call, a->func(). Even if bar checks that the pointer is
not null, it cannot guarantee that the pointer is valid.

Passing by reference puts the onus on the calling code to ensure that
any dereferenced pointer was pointing to a valid object.

Aug 17 '05 #16
Victor Bazarov wrote:
Yes, a valid program shouldn't "crash". And I bet there are programs that
just do not crash. They report critical situations, work their way out of
them, and so on.
> Never happens and is the reason why people invent
"safe" languages like Java et al.


No trolling here, please.


I don't see why this would be trolling. One reason why Java was created is
that it should be more robust against programming errors. Things that lead
to undefined behavior in C++ are either not possible at all in Java or lead
to a defined error (like an exception). That does not mean that Java is
"better" than C++, just that it was created with different objectives in
mind.
Yes and I'm adding that it's impossible not to deal with pointers.


I do not agree.
---------------------------
#include <iostream>

int main() {
std::cout << "Hello world" << std::endl;
}
---------------------------
Look, Ma, no pointers!


Actually, there are pointers. "Hello world" is converted to a pointer to
const char before it's passed to operator<<. And with std::endl, you pass a
pointer to a function to the second operator<<.
Your code doesn't have variables of pointer types, but it sure uses values
of such types.

Aug 17 '05 #17
Rolf Magnus wrote:
Victor Bazarov wrote:

Yes, a valid program shouldn't "crash". And I bet there are programs that
just do not crash. They report critical situations, work their way out of
them, and so on.
> Never happens and is the reason why people invent
"safe" languages like Java et al.


No trolling here, please.

I don't see why this would be trolling. One reason why Java [...]


That's what I call trolling. Java is OFF-f#@*ng-TOPIC, yet you just
continued a discussion on it. He successfully trolled you into this.
Yes and I'm adding that it's impossible not to deal with pointers.


I do not agree.
---------------------------
#include <iostream>

int main() {
std::cout << "Hello world" << std::endl;
}
---------------------------
Look, Ma, no pointers!

Actually, there are pointers. "Hello world" is converted to a pointer to
const char before it's passed to operator<<. And with std::endl, you pass a
pointer to a function to the second operator<<.


So what? I haven't explicitly declared/defined/initialised/assigned or
dereferenced a pointer in that program. It's all done by the language
itself or by the library.
Your code doesn't have variables of pointer types, but it sure uses values
of such types.


And the library is just full of them. Doesn't mean shit.

OK, here you go

#include <iostream>

int main() {
std::cout << 'H' << 'e' << 'l' << 'l' << 'o'
<< ' ' << 'w' << 'o' << 'r' << 'l' << 'd' << '\n';
}

Better now?

V
Aug 17 '05 #18
Andy, I know what the c++ standard says about the fact that that all
evaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things.
"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers.

The dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack.

If the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."

So, in reality , the argument addresses are pushed on the stack without
being deferenced. I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.

Aug 17 '05 #19
Andy, please read post 9 in this thread. Thank you.

Aug 17 '05 #20
Andy, please read post 9 in this thread. Thank you.

Aug 17 '05 #21

Frank Chang wrote:
Andy, I know what the c++ standard says about the fact that that all
evaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things. One should code by the standard not by what compiler
says/generates/behaves. This way when one changes the compiler,
everything works as expected.

"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers. This is the result of UB. Why is it so hard for you to understand? As
soon as the invalid pointer is dereferenced you step into UB land.
Anything is possible, *including* crash inside the function.

The dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack. that is how the code is compiled by your compiler on your platform

If the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."

So, in reality , the argument addresses are pushed on the stack without
being deferenced. I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.

Even if every single C++ compiler would generate the same machine code
(as your compiler), that doesn't make the code right, does it?

/dan

Aug 17 '05 #22
Victor Bazarov wrote:
Rolf Magnus wrote:
Victor Bazarov wrote:

Yes, a valid program shouldn't "crash". And I bet there are programs
that
just do not crash. They report critical situations, work their way
out of
them, and so on.

> Never happens and is the reason why people invent

"safe" languages like Java et al.
No trolling here, please.


I don't see why this would be trolling. One reason why Java [...]

That's what I call trolling. Java is OFF-f#@*ng-TOPIC, yet you just
continued a discussion on it. He successfully trolled you into this.


LOL, when did the discussion on Java start? I could have put anything
there. I made no comparisons to Java. I said nothing positive or
negative about anything. I'm not a Java programmer nor advocate.
Sheesh, this is why I don't typically hang out on USENET, too many
insane individuals (not that the rest of the 'Net is much different ;) )

and on top of all that no one could solve my problem that I came here
for anyway. I think I need to find some real experts and not just
talkers. Buh-bye!

Jo
Aug 17 '05 #23
As you can see, this question always generates a flame war.

The answer is one of philosophy and mindset.
Passing reference uses the mindset: "I think in terms of objects.
This function requires an object. Caller is responsible for properly
providing an object. The compiler will make sure it's the right type
and valid unless you circumvent that. We only need to test a pointer
at the place where we dereference it, before calling the functions that
take a reference."

If you are of this mindset with passing references, then passing
pointers means "You can give me a pointer to nothing as well" although
some people confuse const with pointer and mean "I can edit your
value".

If you are of the mindset that references are evil, then pass by
pointer means (I'm not entirely facetious here): I don't understand
objects and I think in terms of pointers. I might or might not be
allowing you to pass 0, and I might or might not be expecting you to
check that the pointer is non-zero because I might or might not check
it before I dereference, depending on whim. If I am careful about
checking pointers against 0, I insist this be done in every routine no
matter how small, so typically I prefer encapsulation problems to tiny
routines. Since I know you can dereference a pointer to 0, I prefer to
work with pointers and love to pontificate about the horrors of
references. However, although I get on my high horse about references
not really being guaranteed to be objects when you lie to the compiler,
I will conveniently ignore the equivalent problem that passing a
non-zero pointer doesn't guarantee that it's a pointer to something
legitimate, and that dereferencing a pointer can actually cause a crash
if you've lied to the compiler and passed a pointer to a deleted object
or arranged for the pointer to be to some arbitrary number.

In other words, as far as the compiler is concerned it's about the same
thing. As far as you are concerned, passing by reference or not helps
clarify your code and make it clear who is supposed to check that
pointers are valid. Generally code that passes references are easier
to maintain, but that depends on the people involved.

Stuart

Aug 17 '05 #24
Frank Chang wrote:
Andy, please read post 9 in this thread. Thank you.

Most of us aren't reading this from Google. There are no numbers on the
posts. Google sticks those on.


Brian

Aug 17 '05 #25

Frank Chang wrote:
NULL references are unbelievably easy in C++...

someClass* instance = SomeOperation();
Test(*instance );


I don't understand this argument.
What's the difference between this and someone inadvertantly doing:

Test(someClass* p)
{
p->doSomething();
}
....
someClass* instance = SomeOperation();
Test(instance);

or even worse:

Test(SomeOperation()); // We assume Test will check that that pointer
is ok

Both cases dereference a pointer that's never been checked for
non-zero. Are you saying that people are careless when dereferencing a
pointer using * but not careless when using a pointer via ->? That's
not consistent with my observations of people's code. I've seen much
sloppier handling of pointers in code that takes pointers than in code
calling routines taking references.

Stuart

Aug 17 '05 #26

Frank Chang wrote:
Andy, I know what the c++ standard says about the fact that that all
evaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things.
And these are cases where the compiler is non-conforming.
"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers.

The dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack.

If the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."

So, in reality , the argument addresses are pushed on the stack without
being deferenced.
Is this guaranteed?
I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.


You say "the" c++ compiler as though there is only one. I guess the
fact there are many c++ compilers is the reason we have the c++
standard and it is only this which actually defines the language.

The point I am trying to make is that the code that caontains the
undefined behaviour is the calling code, it is the calling code that is
erroneous not the function body. The function can assume the reference
refers to a valid object because anything else would mean that you have
already eneter the realm of undefined beahviour and at that point what
happens within the function body is pointless to discuss because it is
*undefined*. Where a program crashes (assuming it crashes) is not
necessarily the point where the program first became undefined and it
is this point which is important (from a coding perspective).

Aug 17 '05 #27
Stuart, I agree with what you just said. This is one of those
"religious wars" that can go on and on. I've learned a lot by listening
to everybody's viewpoints and that is what really counts.

Aug 17 '05 #28
Victor Bazarov wrote:
Rolf Magnus wrote:
Victor Bazarov wrote:

Yes, a valid program shouldn't "crash". And I bet there are programs
that
just do not crash. They report critical situations, work their way out
of them, and so on.

> Never happens and is the reason why people invent

"safe" languages like Java et al.

No trolling here, please.

I don't see why this would be trolling. One reason why Java [...]


That's what I call trolling. Java is OFF-f#@*ng-TOPIC,


What's your problem, man?
yet you just continued a discussion on it. He successfully trolled you
into this.
Actually it was you. If you hadn't called him a troll, I wouldn't have
answered to it. My point was that I don't consider just the bare mentioning
of the word "Java" as trolling. He didn't write something like "Java is
better than C++" or "C++ is better than Java". He only used it as an
argument for his point that in the real world, errors happen, and so it can
happen that an invalid reference is passed to a function. And so, passing a
reference instead of a pointer is in no way safer. The function has to rely
on the caller providing valid data in both cases.
OK, here you go

#include <iostream>

int main() {
std::cout << 'H' << 'e' << 'l' << 'l' << 'o'
<< ' ' << 'w' << 'o' << 'r' << 'l' << 'd' << '\n';
}

Better now?


Yup ;-)

Aug 17 '05 #29
Dan, Your points are well stated. However, you state
This is the result of UB. Why is it so hard for you to understand? As
soon as the invalid pointer is dereferenced you step into UB land.
Anything is possible, *including* crash inside the function.
This is true, but I never claimed the code wouldn't crash inside the
function.

Your last point,
Even if every single C++ compiler would generate the same machine >>code
(as your compiler), that doesn't make the code right, does it?


is completely true. I was just stating to AndyRB that it would be
interesting to see the assembly code from a from a well-known C++
compiler like MS Visual Studio, to see what goes on behind the scenes.
By the ways , "almost anonymous" looked at the assembly code generated
by the Metrowerks C++ compiler and made the observation about the
arguments being pushed on the stack.

Aug 17 '05 #30
Andy, You are right. There is not only one C++ compiler. By the way ,
it was "almost_anonymous" who made the observation about the Metrowerks
C++ compiler pushing arguments on the stack. The point of my post
directed to you was that one would need to look at the assembly code
generated by other well known compilers, before we could draw any
conclusions. Your final point is what really counts
Where a program crashes (assuming it crashes) is not
necessarily the point where the program first became undefined and >>it
is this point which is important (from a coding perspective).


Thank you for bringing your viewpoints to this discussion. I learned a
lot from reading your posts.

Aug 18 '05 #31
Passing by pointer comes from the C attitude:

void useAnInt( int x )
{
do_something_with_x( x );
}

void setAnInt( int * x_address )
{
*x_address = someValue();
}

Now from the code that calls the function it looks clear
whether or not the function is likely to modify (set) your value.

void callingFunc()
{
int x;
setAnInt( &x ); /* will be setting this value to something */
useAnInt( x ); /* x will not be changed by this function */
}

Those who are taught "C first" will probably learn this even before
they use larger structs, which they might
want to pass as a pointer even if it is not going to be modified for
efficiency.

When they move over to C++ and learn about references, there is a
feeling of discomfort.
You can pass a function thus useAnInt( x ); and you won't know if
useAnInt() might modify the x without
looking at the function, whereas setAnInt( &x ) is likely to because
you passed it by address.

Therefore they stick with pointers and avoid references. (Apart from
the fact they are sticking with the familiar).

By the way, Java does not use references in the style of C++. What they
call references are really pointers, albeit
more like smart-pointers. But let's end that discussion here because we
are not here to discuss Java.

Aug 18 '05 #32

Stuart MacMartin skrev:
Frank Chang wrote:
NULL references are unbelievably easy in C++...

someClass* instance = SomeOperation();
Test(*instance );
I don't understand this argument.
What's the difference between this and someone inadvertantly doing:

Test(someClass* p)
{
p->doSomething();
}
...
someClass* instance = SomeOperation();
Test(instance);

or even worse:

Test(SomeOperation()); // We assume Test will check that that pointer
is ok

Both cases dereference a pointer that's never been checked for
non-zero. Are you saying that people are careless when dereferencing a
pointer using * but not careless when using a pointer via ->? That's
not consistent with my observations of people's code. I've seen much
sloppier handling of pointers in code that takes pointers than in code
calling routines taking references.


One difference is that when programmers see a signature involving a
reference, they have the obligation to check their pointer before
passing it on. Secondly, they should assume that a function that
accepts a pointer will allow passing 0 (unless specifically stated in
the docs, but this requires more documentation). Thus using a reference
is a valuable point of documentation.
Another is that by not using (raw) pointers you reduce the option of
inadvertently passing one. And pointerusage is very heavily reduced in
C++ program compared to the equivalent C-code.
Unfortunately it appears that there are loads of "C++"-programmers
using naked pointers all the time, at least judging by this newsgroup.
I would not have let those in to my development team without a heavy
brainwash.

/Peter
Stuart


Aug 18 '05 #33
Ram
> Whats the difference b/w pass by ref and pass by pointer in C++ when
ur passing objects as args..


Apart from accessing the object's member's with dot (.) notation, it
delegates the responsibility of passing a valid object to the caller.
When one passes a pointer, that may not or may be a NULL (in which case
you aren't allowed to de-reference it). But with a reference and in a
valid sequence you are guaranteed that you have a valid object. That
can't be said for a pointer argument. The NULL pointer itself may be a
valid argument.

Ramashish

Aug 18 '05 #34
Ram
> Andy, I know what the c++ standard says about the fact that that all
evaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things.
Frank, if you program according to the standard i.e. by assuming that
"all evaluation of function arguments takes place before execution of
any expressions of any expressions or statements in the the function
body" this question wouldn't arise.

"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers.

The dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack.

If the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."
That is just the way your compiler implements a reference. May not be
true for all compilers and even if it is I should not care.

So, in reality , the argument addresses are pushed on the stack without
being deferenced. I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.


Again, whether or not the compiler de-reference it before passing on is
upto it. Looking at the assembly code is no good way to resolve this
issue. If one is keen to abuse the language, then little can be done
about it.

If I were to design a compiler that throws an exception on having an
invalid reference object then I need to de-reference the pointer (from
which the object is being constructed) whether I use the reference
variable or not in the function. Why, the standard C++ already does it
for dynamic_cast..

#include <iostream>

using namespace std;

class A
{
public:
virtual ~A() {}
};
class B: public A
{
public:
};

int main()
{
A *a = new A;

try {
B &b = dynamic_cast<B&>(*a);
}
catch(...)
{
cerr << "Invalid cast\n";
}

delete a;

return 0;
}

Ramashish

Aug 18 '05 #35
Ram

Earl Purple wrote:
Passing by pointer comes from the C attitude:

void useAnInt( int x )
{
do_something_with_x( x );
}

void setAnInt( int * x_address )
{
*x_address = someValue();
}

Now from the code that calls the function it looks clear
whether or not the function is likely to modify (set) your value.

void callingFunc()
{
int x;
setAnInt( &x ); /* will be setting this value to something */
useAnInt( x ); /* x will not be changed by this function */
}

Those who are taught "C first" will probably learn this even before
they use larger structs, which they might
want to pass as a pointer even if it is not going to be modified for
efficiency.

When they move over to C++ and learn about references, there is a
feeling of discomfort.
You can pass a function thus useAnInt( x ); and you won't know if
useAnInt() might modify the x without
looking at the function, whereas setAnInt( &x ) is likely to because
you passed it by address.


I don't agree here. If I am using a function, I definitely know in what
way it uses its arguments. If it doesn't modify its arguments the
reference would be const and I don't need to bother. And if its
expected to modify and I don't know about it then I am already doomed.

Aug 18 '05 #36
Ram
> > A reference always refers to a valid object, according to language rules.
The difference is that, when inside a function, if the argument is a reference,
you can rely upon it being a real object.
> cat main.cc

#include <iostream>

void f(const int& r) {
std::cout << "r = " << r << std::endl;
}

int main(int argc, char* argv[]) {

int* p = 0;
int& r = *p;


The behavior of the program becomes undefined at this step itself. The
problem has nothing to do with reference but to your de-referencing a
NULL pointer.
f(r);


f has every right to assume that it is passed a valid and real object.
If you mess up before calling f, then there's nothing that can be done
about it in f.

Ramashish

Aug 18 '05 #37
Ram wrote:
Whats the difference b/w pass by ref and pass by pointer in C++ when
ur passing objects as args..
Apart from accessing the object's member's with dot (.) notation, it
delegates the responsibility of passing a valid object to the caller.


I disagree. If I call a function that takes a pointer, I never pass a null
pointer unless the documentation of the function explicitly says that it
accepts a null pointer _and_ that it handles it the way I want.
When one passes a pointer, that may not or may be a NULL (in which case
you aren't allowed to de-reference it). But with a reference and in a
valid sequence you are guaranteed that you have a valid object. That
can't be said for a pointer argument. The NULL pointer itself may be a
valid argument.


It may be, or it may be not.

Aug 23 '05 #38
Kev
Rolf Magnus <ra******@t-online.de> wrote in
news:de*************@news.t-online.com:
I disagree. If I call a function that takes a pointer, I never pass a
null pointer unless the documentation of the function explicitly says
that it accepts a null pointer _and_ that it handles it the way I
want.


I am still getting the hang of references but they do seem to be less error
prone at least for me... more so in catching my errors while coding than
anything else. That in itself helps quite a lot. I find pointers to be a
bit of voodoo but then Im newish. And if anyone put assembly in front of me
I would think I was looking at the matrix, just without the pretty green
waterfall effect.

Its a bit difficult to keep track when using both in different places. I am
trying to stick with references wherever possible. But a couple of times I
didnt see a way to get them to work, whereas things such as pointers to
pointers worked just fine.
Aug 23 '05 #39

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: DamonChong | last post by:
Hi, I am still struggling to master C++ and is trying to understand how to achieve passing arguments using pointers. I got some questions that I like to post to the experts here, hope you can...
110
by: Mr A | last post by:
Hi! I've been thinking about passing parameteras using references instead of pointers in order to emphasize that the parameter must be an object. Exemple: void func(Objec& object); //object...
10
by: nospam | last post by:
Hello! I can pass a "pointer to a double" to a function that accepts double*, like this: int func(double* var) { *var=1.0; ... }
4
by: z_learning_tester | last post by:
I'm reading the MS press C# book and there seems to be a contradiction. Please tell me which one is correct, 1 or 2. Thanks! Jeff 1. First it gives the code below saying that it prints 0 then...
4
by: Jon Slaughter | last post by:
I'm reading a book on C# and it says there are 4 ways of passing types: 1. Pass value type by value 2. Pass value type by reference 3. Pass reference by value 4. Pass reference by reference. ...
14
by: Abhi | last post by:
I wrote a function foo(int arr) and its prototype is declared as foo(int arr); I modify the values of the array in the function and the values are getting modified in the main array which is...
6
by: lisp9000 | last post by:
I've read that C allows two ways to pass information between functions: o Pass by Value o Pass by Reference I was talking to some C programmers and they told me there is no such thing as...
11
by: venkatagmail | last post by:
I have problem understanding pass by value and pass by reference and want to how how they are or appear in the memory: I had to get my basics right again. I create an array and try all possible...
4
by: S. | last post by:
Hi all, I have the requirement that I must pass-by-reference to my function addStudent() and getAge() functions where my getAge() function is within the addStudent() function. I am able to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.