pass by ref vs pass by pointer

Discussion in 'C++' started by Radde, Aug 17, 2005.

  1. Radde

    Radde Guest

    HI all,

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

    Cheers..
     
    Radde, Aug 17, 2005
    #1
    1. Advertising

  2. 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
     
    Victor Bazarov, Aug 17, 2005
    #2
    1. Advertising

  3. 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.
     
    E. Robert Tisdale, Aug 17, 2005
    #3
  4. 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.
     
    Victor Bazarov, Aug 17, 2005
    #4
  5. Radde

    Frank Chang Guest

    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/joelonsoftware/default.asp?cmd=show&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
     
    Frank Chang, Aug 17, 2005
    #5
  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.
     
    E. Robert Tisdale, Aug 17, 2005
    #6
  7. Frank Chang wrote:
    > NULL references are unbelievably easy in C++...


    Not in a valid program...

    > [..]
     
    Victor Bazarov, Aug 17, 2005
    #7
  8. Radde

    Rolf Magnus Guest

    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.
     
    Rolf Magnus, Aug 17, 2005
    #8
  9. Radde

    Frank Chang Guest

    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.
     
    Frank Chang, Aug 17, 2005
    #9
  10. Radde

    Jojo Guest

    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
     
    Jojo, Aug 17, 2005
    #10
  11. 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
     
    Victor Bazarov, Aug 17, 2005
    #11
  12. Radde

    Jojo Guest

    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
     
    Jojo, Aug 17, 2005
    #12
  13. Radde

    AndyRB Guest

    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.
     
    AndyRB, Aug 17, 2005
    #13
  14. Radde

    AndyRB Guest

    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".
     
    AndyRB, Aug 17, 2005
    #14
  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.


    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
     
    Victor Bazarov, Aug 17, 2005
    #15
  16. Radde

    AndyRB Guest

    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.
     
    AndyRB, Aug 17, 2005
    #16
  17. Radde

    Rolf Magnus Guest

    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.
     
    Rolf Magnus, Aug 17, 2005
    #17
  18. 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
     
    Victor Bazarov, Aug 17, 2005
    #18
  19. Radde

    Frank Chang Guest

    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.
     
    Frank Chang, Aug 17, 2005
    #19
  20. Radde

    Frank Chang Guest

    Andy, please read post 9 in this thread. Thank you.
     
    Frank Chang, Aug 17, 2005
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    341
  2. Replies:
    22
    Views:
    763
    peter koch
    Apr 30, 2008
  3. Replies:
    6
    Views:
    352
    James Kanze
    Apr 29, 2008
  4. Navindra Umanee

    strong ref from weak ref?

    Navindra Umanee, Feb 12, 2005, in forum: Ruby
    Replies:
    2
    Views:
    145
    Navindra Umanee
    Feb 12, 2005
  5. Juha Nieminen
    Replies:
    13
    Views:
    621
    Edek Pienkowski
    Aug 29, 2012
Loading...

Share This Page