passing pointer to struct by reference

Discussion in 'C++' started by Mike, Mar 21, 2006.

  1. Mike

    Mike Guest

    Consider the following code:

    """
    struct person {
    char *name;
    int age;
    };

    typedef struct person* StructType;

    /* Think I got that syntax right above... :) */

    void somefunc(StructType t)
    {
    // do something
    }

    int main()
    {
    StructType st;
    somefunc(st);
    }
    """

    My professor called me out on my invocation of somefunc() by saying that
    I should be passing by reference instead. My response was "Well, it's
    *really* a pointer anyways, so what does it matter?" Now that I think
    about this, I guess you should always pass by reference because you may
    not always know if something is represented as a pointer. Is this the
    reason? I have done more C than C++ so by nature I tend to focus on
    pointers :)

    Thanks.

    Mike
    Mike, Mar 21, 2006
    #1
    1. Advertising

  2. * Mike:
    > Consider the following code:
    >
    > """
    > struct person {
    > char *name;
    > int age;
    > };
    >
    > typedef struct person* StructType;
    >
    > /* Think I got that syntax right above... :) */
    >
    > void somefunc(StructType t)
    > {
    > // do something
    > }
    >
    > int main()
    > {
    > StructType st;
    > somefunc(st);
    > }
    > """
    >
    > My professor called me out on my invocation of somefunc() by saying that
    > I should be passing by reference instead. My response was "Well, it's
    > *really* a pointer anyways, so what does it matter?"


    With a pointer you're saying: "I'm supporting a null-pointer argument".

    With a reference you're saying: "This won't ever be a null-pointer".

    There's less checking and less that can go wrong. For example, in the
    above code you're passing an uninitialized pointer. That's Undefined
    Behavior.

    Better naming can also help.

    Here the pointerness is hidden behind a name that doesn't signify
    pointer, so it's possible your professor didn't even see the UB or the
    null-pointer issue but just assumed you were passing a structure
    (inefficiently) by value.


    > Now that I think
    > about this, I guess you should always pass by reference because you may
    > not always know if something is represented as a pointer. Is this the
    > reason? I have done more C than C++ so by nature I tend to focus on
    > pointers :)


    Mostly, passing by reference (to const) instead of passing by value is
    an optimization that very seldom hurts, and very often helps. Although
    the compiler can do the same optimization, you don't have to worry about
    whether it does. And doing this can clean up the design and help
    improve your own understanding of the code... ;-)

    Passing by pointer instead of by value is, on the other hand, an
    optimization that often hurts, and muddles the waters instead of
    clarifying anything.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Mar 21, 2006
    #2
    1. Advertising

  3. Mike

    Artie Gold Guest

    Mike wrote:
    > Consider the following code:
    >
    > """
    > struct person {
    > char *name;
    > int age;
    > };
    >
    > typedef struct person* StructType;


    Hiding a pointer type like this is, IMHO, ugly.
    >
    > /* Think I got that syntax right above... :) */
    >
    > void somefunc(StructType t)
    > {
    > // do something


    Do something?
    Well, what you're planning to do here is *very* relevant!
    > }
    >
    > int main()
    > {
    > StructType st;
    > somefunc(st);

    As stated here, you're passing an unitialized pointer to a function
    returning void. What could you *possibly* be doing?
    > }
    > """
    >
    > My professor called me out on my invocation of somefunc() by saying that
    > I should be passing by reference instead. My response was "Well, it's
    > *really* a pointer anyways, so what does it matter?" Now that I think
    > about this, I guess you should always pass by reference because you may
    > not always know if something is represented as a pointer. Is this the
    > reason? I have done more C than C++ so by nature I tend to focus on
    > pointers :)
    >

    The reason that passing a reference to a struct as opposed to a pointer
    to a struct is that the pointer may be NULL (and you'd have to check
    that in the called function). The usual `rule' is: pass by reference
    when you can, pass a pointer when you must.

    Why don't you post a (somewhat) more realistic snippet of code? That
    would greatly enhance the possibility of providing a meaningful explanation.

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://goldsays.blogspot.com
    "You can't KISS* unless you MISS**"
    [*-Keep it simple, stupid. **-Make it simple, stupid.]
    Artie Gold, Mar 21, 2006
    #3
  4. Mike

    Mike Guest

    Alf P. Steinbach wrote:
    > * Mike:
    >> Consider the following code:
    >>
    >> """
    >> struct person {
    >> char *name;
    >> int age;
    >> };
    >>
    >> typedef struct person* StructType;
    >>
    >> /* Think I got that syntax right above... :) */
    >>
    >> void somefunc(StructType t)
    >> {
    >> // do something
    >> }
    >>
    >> int main()
    >> {
    >> StructType st;
    >> somefunc(st);
    >> }
    >> """
    >>
    >> My professor called me out on my invocation of somefunc() by saying
    >> that I should be passing by reference instead. My response was "Well,
    >> it's *really* a pointer anyways, so what does it matter?"

    >
    > With a pointer you're saying: "I'm supporting a null-pointer argument".
    >
    > With a reference you're saying: "This won't ever be a null-pointer".
    >


    I understand. But beneath the language isn't a reference just a pointer?
    For example, passing a pointer by reference is equivalent (and probably
    much unsafer) to double indirection. Or am I wrong? :) How does the
    compiler guarantee that pass by reference is never undefined? Maybe I
    just need to study this in more detail. Do you have any good references
    on this topic?

    > Here the pointerness is hidden behind a name that doesn't signify
    > pointer, so it's possible your professor didn't even see the UB or the
    > null-pointer issue but just assumed you were passing a structure
    > (inefficiently) by value.
    >

    I think that's why he called me out... the possibility of passing by
    value. Unfortunately, there's never an in-depth discussion on any
    particular topic...

    Thanks for the assistance.

    --
    Mike
    Mike, Mar 21, 2006
    #4
  5. Mike

    Mike Guest

    Artie Gold wrote:
    > Mike wrote:
    >> Consider the following code:
    >>
    >> """
    >> struct person {
    >> char *name;
    >> int age;
    >> };
    >>
    >> typedef struct person* StructType;

    >
    > Hiding a pointer type like this is, IMHO, ugly.


    I agree -- I'd be doing things differently, but this is how it's taught,
    unfortunately.

    >>
    >> /* Think I got that syntax right above... :) */
    >>
    >> void somefunc(StructType t)
    >> {
    >> // do something

    >
    > Do something?
    > Well, what you're planning to do here is *very* relevant!


    What the function was doing is not relevant to how values are passed to
    the function. "t" is a pointer to type "struct person," so you're
    obviously passing a pointer. That's how I chose to pass it because I had
    knowledge that "t" would be a pointer. But, the professor would have
    preferred to see a function prototype of:

    void somefunc(StructType& t);

    I thougth that would be similar to double indirection, i.e. in terms of C:

    void somefunc(StructType *t); // "t" is already a pointer...

    >> }
    >>
    >> int main()
    >> {
    >> StructType st;
    >> somefunc(st);

    > As stated here, you're passing an unitialized pointer to a function
    > returning void. What could you *possibly* be doing?


    Sorry about that. I didn't give fully working code as an example, so it
    wasn't meant to be compiled and ran. Obviously it will cause a problem,
    but I didn't want to focus on *what* the program is doing. I wanted to
    focus on *how* arguments are passed by reference vs. pointer assuming
    that variables had defined values.

    >> }
    >> """
    >>
    >> My professor called me out on my invocation of somefunc() by saying
    >> that I should be passing by reference instead. My response was "Well,
    >> it's *really* a pointer anyways, so what does it matter?" Now that I
    >> think about this, I guess you should always pass by reference because
    >> you may not always know if something is represented as a pointer. Is
    >> this the reason? I have done more C than C++ so by nature I tend to
    >> focus on pointers :)
    >>


    > Why don't you post a (somewhat) more realistic snippet of code? That
    > would greatly enhance the possibility of providing a meaningful
    > explanation.


    Ok, I'll do that. I'll reply to my original post with something more
    meaningful.

    >
    > HTH,
    > --ag
    >


    Thanks.

    --
    Mike
    Mike, Mar 21, 2006
    #5
  6. Mike

    Mike Guest

    Mike wrote:
    > Consider the following code:
    >
    > """
    > struct person {
    > char *name;
    > int age;
    > };
    >
    > typedef struct person* StructType;
    >
    > /* Think I got that syntax right above... :) */
    >
    > void somefunc(StructType t)
    > {
    > // do something
    > }
    >
    > int main()
    > {
    > StructType st;
    > somefunc(st);
    > }
    > """
    >
    > My professor called me out on my invocation of somefunc() by saying that
    > I should be passing by reference instead. My response was "Well, it's
    > *really* a pointer anyways, so what does it matter?" Now that I think
    > about this, I guess you should always pass by reference because you may
    > not always know if something is represented as a pointer. Is this the
    > reason? I have done more C than C++ so by nature I tend to focus on
    > pointers :)
    >
    > Thanks.
    >
    > Mike


    Here's a more meaningful snippet of code.

    """
    struct person {
    char *name;
    int age;
    };

    typedef struct person* StructType;

    /* Think I got that syntax right above... :) */

    void somefunc(StructType t)
    {
    // do something
    }

    void somefunc2(StructType& t)
    {
    // do something here, too.
    }

    int main()
    {
    // Yes, I know this isn't the best name...
    StructType st = new person;
    StructType st2 = NULL;

    // passing "st" by pointer.
    somefunc(st);

    // passing "st2" by reference, which
    // already is a NULL pointer. So, how does
    // pass-by-reference become safer if "st2" is NULL?
    // Won't the function see a NULL pointer regardless
    // of how it was passed?
    somefunc2(st2);

    delete st;
    }
    """

    See my comments inline with the code.

    Thanks.

    --
    Mike
    Mike, Mar 21, 2006
    #6
  7. * Mike:
    > Alf P. Steinbach wrote:
    >> * Mike:
    >>> Consider the following code:
    >>>
    >>> """
    >>> struct person {
    >>> char *name;
    >>> int age;
    >>> };
    >>>
    >>> typedef struct person* StructType;
    >>>
    >>> /* Think I got that syntax right above... :) */
    >>>
    >>> void somefunc(StructType t)
    >>> {
    >>> // do something
    >>> }
    >>>
    >>> int main()
    >>> {
    >>> StructType st;
    >>> somefunc(st);
    >>> }
    >>> """
    >>>
    >>> My professor called me out on my invocation of somefunc() by saying
    >>> that I should be passing by reference instead. My response was
    >>> "Well, it's *really* a pointer anyways, so what does it matter?"

    >>
    >> With a pointer you're saying: "I'm supporting a null-pointer argument".
    >>
    >> With a reference you're saying: "This won't ever be a null-pointer".
    >>

    >
    > I understand. But beneath the language isn't a reference just a pointer?


    As practical matter a reference T& is very much like a pointer T*const,
    and the compiler can do much of the same kinds of optimizations.

    But the language does not specify what a reference is beneath language.

    Viewing a reference as a pointer in disguise is just a practical
    conceptual picture, useful for understanding things and for debugging.


    > For example, passing a pointer by reference is equivalent (and probably
    > much unsafer) to double indirection. Or am I wrong? :)


    Generally the reference is much safer.


    > How does the
    > compiler guarantee that pass by reference is never undefined?


    It does not; that's your job. However, a quality compiler can help by
    providing useful warnings here and there. But in the end it must assume
    that you know what you're doing.


    > Maybe I
    > just need to study this in more detail. Do you have any good references
    > on this topic?


    Nope, but you can try the FAQ, your nearest text-book, and
    <url: http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01.pdf>.


    >> Here the pointerness is hidden behind a name that doesn't signify
    >> pointer, so it's possible your professor didn't even see the UB or the
    >> null-pointer issue but just assumed you were passing a structure
    >> (inefficiently) by value.
    >>

    > I think that's why he called me out... the possibility of passing by
    > value. Unfortunately, there's never an in-depth discussion on any
    > particular topic...
    >
    > Thanks for the assistance.


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Mar 21, 2006
    #7
  8. Mike wrote:

    > >> My professor called me out on my invocation of somefunc() by saying
    > >> that I should be passing by reference instead. My response was "Well,
    > >> it's *really* a pointer anyways, so what does it matter?"

    > >
    > > With a pointer you're saying: "I'm supporting a null-pointer argument".
    > >
    > > With a reference you're saying: "This won't ever be a null-pointer".
    > >

    >
    > I understand. But beneath the language isn't a reference just a pointer?
    > For example, passing a pointer by reference is equivalent (and probably
    > much unsafer) to double indirection. Or am I wrong? :)


    It's not "unsafer," but the syntax does get a bit ugly.

    > How does the
    > compiler guarantee that pass by reference is never undefined? Maybe I
    > just need to study this in more detail. Do you have any good references
    > on this topic?


    The FAQ:

    http://www.parashift.com/c -faq-lite/references.html

    References may often be implemented as a const pointer. They may also
    be optimized away (and for all I know, perhaps so may const pointers),
    but that's an implementation detail.

    Best regards,

    Tom
    Thomas Tutone, Mar 21, 2006
    #8
  9. Mike

    Mike Guest

    Alf P. Steinbach wrote:
    >> How does the compiler guarantee that pass by reference is never
    >> undefined?

    >
    > It does not; that's your job. However, a quality compiler can help by
    > providing useful warnings here and there. But in the end it must assume
    > that you know what you're doing.


    Ok, that clarifies my question in my most recent post with the clarified
    example. I thought you were implying that passing by reference
    automatically imposed some type of checking. :)


    >> Maybe I just need to study this in more detail. Do you have any good
    >> references on this topic?

    >
    > Nope, but you can try the FAQ, your nearest text-book, and
    > <url: http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01.pdf>.
    >


    Thanks, I'll take a look at that.


    --
    Mike
    Mike, Mar 21, 2006
    #9
  10. Mike

    Mike Guest

    Thomas Tutone wrote:
    > Mike wrote:
    >
    >>>> My professor called me out on my invocation of somefunc() by saying
    >>>> that I should be passing by reference instead. My response was "Well,
    >>>> it's *really* a pointer anyways, so what does it matter?"
    >>> With a pointer you're saying: "I'm supporting a null-pointer argument".
    >>>
    >>> With a reference you're saying: "This won't ever be a null-pointer".
    >>>

    >> I understand. But beneath the language isn't a reference just a pointer?
    >> For example, passing a pointer by reference is equivalent (and probably
    >> much unsafer) to double indirection. Or am I wrong? :)

    >
    > It's not "unsafer," but the syntax does get a bit ugly.


    I'd rather much deal with references than pointers, especially with
    double/triple indirection :)

    >> How does the
    >> compiler guarantee that pass by reference is never undefined? Maybe I
    >> just need to study this in more detail. Do you have any good references
    >> on this topic?

    >
    > The FAQ:
    >
    > http://www.parashift.com/c -faq-lite/references.html
    >
    > References may often be implemented as a const pointer. They may also
    > be optimized away (and for all I know, perhaps so may const pointers),
    > but that's an implementation detail.


    Thanks for the tip. Sometime in the near future I hope to take a
    compiler class. I'm sure I'll learn more about implementation then...

    > Best regards,
    >
    > Tom
    >



    --
    Mike
    Mike, Mar 21, 2006
    #10
  11. Mike

    Howard Guest

    "Mike" <> wrote in message
    news:...
    > Mike wrote:
    >> Consider the following code:
    >>
    >> """
    >> struct person {
    >> char *name;
    >> int age;
    >> };
    >>
    >> typedef struct person* StructType;
    >>
    >> /* Think I got that syntax right above... :) */
    >>
    >> void somefunc(StructType t)
    >> {
    >> // do something
    >> }
    >>
    >> int main()
    >> {
    >> StructType st;
    >> somefunc(st);
    >> }
    >> """
    >>
    >> My professor called me out on my invocation of somefunc() by saying that
    >> I should be passing by reference instead. My response was "Well, it's
    >> *really* a pointer anyways, so what does it matter?" Now that I think
    >> about this, I guess you should always pass by reference because you may
    >> not always know if something is represented as a pointer. Is this the
    >> reason? I have done more C than C++ so by nature I tend to focus on
    >> pointers :)
    >>
    >> Thanks.
    >>
    >> Mike

    >
    > Here's a more meaningful snippet of code.
    >
    > """
    > struct person {
    > char *name;
    > int age;
    > };
    >
    > typedef struct person* StructType;
    >
    > /* Think I got that syntax right above... :) */
    >
    > void somefunc(StructType t)
    > {
    > // do something
    > }
    >
    > void somefunc2(StructType& t)
    > {
    > // do something here, too.
    > }
    >
    > int main()
    > {
    > // Yes, I know this isn't the best name...
    > StructType st = new person;
    > StructType st2 = NULL;
    >
    > // passing "st" by pointer.
    > somefunc(st);
    >
    > // passing "st2" by reference, which
    > // already is a NULL pointer. So, how does
    > // pass-by-reference become safer if "st2" is NULL?
    > // Won't the function see a NULL pointer regardless
    > // of how it was passed?
    > somefunc2(st2);
    >
    > delete st;
    > }
    > """
    >
    > See my comments inline with the code.
    >


    I think everyone got a little confused here about what you were talking
    about. If your examples here illustrate the problem, then it's not a matter
    of passing by pointer versus passing by reference (as has been discussed
    here), it's a matter of passing a pointer by value versus a pointer by
    reference.

    The difference is the same as with any other type: if you want to modify the
    value (of the pointer st2, in this example), then you need to pass it (the
    pointer) by reference (or else by via pointer-to-pointer).

    If you pass the pointer by value, and inside the function you modify the
    pointer (such as by assigning the result of "new" to it), then you're only
    modifying the local _copy_ of the pointer, not the pointer itself.

    So, it all depends upon what you are doing _inside_ the called function, as
    to whether you want to pass the pointer by value (as in somefunc()) or by
    reference (as in somefunc2()).

    -Howard
    Howard, Mar 21, 2006
    #11
  12. Mike

    Ben Pope Guest

    Mike wrote:
    > Mike wrote:
    >> Consider the following code:
    >>
    >> """
    >> struct person {
    >> char *name;
    >> int age;
    >> };
    >>
    >> typedef struct person* StructType;
    >>
    >> /* Think I got that syntax right above... :) */
    >>
    >> void somefunc(StructType t)
    >> {
    >> // do something
    >> }
    >>
    >> int main()
    >> {
    >> StructType st;
    >> somefunc(st);
    >> }
    >> """
    >>
    >> My professor called me out on my invocation of somefunc() by saying
    >> that I should be passing by reference instead. My response was "Well,
    >> it's *really* a pointer anyways, so what does it matter?" Now that I
    >> think about this, I guess you should always pass by reference because
    >> you may not always know if something is represented as a pointer. Is
    >> this the reason? I have done more C than C++ so by nature I tend to
    >> focus on pointers :)
    >>
    >> Thanks.
    >>
    >> Mike

    >
    > Here's a more meaningful snippet of code.
    >
    > """
    > struct person {
    > char *name;
    > int age;
    > };
    >
    > typedef struct person* StructType;
    >
    > /* Think I got that syntax right above... :) */


    typedef person* StructType;

    Will suffice. A struct does not need to be qualified with that keyword
    in C++, only in C.

    > void somefunc(StructType t)
    > {
    > // do something
    > }
    >
    > void somefunc2(StructType& t)
    > {
    > // do something here, too.
    > }
    >
    > int main()
    > {
    > // Yes, I know this isn't the best name...
    > StructType st = new person;
    > StructType st2 = NULL;
    >
    > // passing "st" by pointer.
    > somefunc(st);
    >
    > // passing "st2" by reference, which
    > // already is a NULL pointer. So, how does
    > // pass-by-reference become safer if "st2" is NULL?
    > // Won't the function see a NULL pointer regardless
    > // of how it was passed?
    > somefunc2(st2);
    >
    > delete st;
    > }
    > """
    >
    > See my comments inline with the code.


    You have gained nothing because you still have the pointer there.
    Consider this:

    void someFunc3(person& t) {
    // Now t cannot be null
    }

    I would not recommend hiding the pointer behind a typedef, pointers
    cause enough trouble when they're visible an obvious. When they're
    hidden, it's even more of a pain to find the problem.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
    Ben Pope, Mar 21, 2006
    #12
  13. Mike

    Guest

    Alf P. Steinbach wrote:

    > Nope, but you can try the FAQ, your nearest text-book, and
    > <url: http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01.pdf>.
    >
    >


    Alf, this is a very good tutorial, is it from a book that you wrote?
    Where can I get the rest of it?
    , Mar 21, 2006
    #13
    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. sam pal
    Replies:
    3
    Views:
    525
    E. Robert Tisdale
    Jul 16, 2003
  2. Chris Fogelklou
    Replies:
    36
    Views:
    1,345
    Chris Fogelklou
    Apr 20, 2004
  3. beetle
    Replies:
    2
    Views:
    882
    beetle
    Jan 25, 2005
  4. Zero
    Replies:
    16
    Views:
    638
    Barry Schwarz
    Nov 19, 2005
  5. aleksa

    Struct pointer vs. struct array pointer

    aleksa, Feb 20, 2013, in forum: C Programming
    Replies:
    16
    Views:
    447
    Shao Miller
    Feb 20, 2013
Loading...

Share This Page