Pass-by-reference instead of pass-by-pointer = a bad idea?

Discussion in 'C++' started by Mr A, Jul 10, 2005.

  1. Mr A

    Mr A Guest

    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 must be an object

    instead of

    void func(Object* object); //object can be NULL

    I belive that this is a good idea since , in the reference case, it's
    clear that NULL is not an option. It's also clear that NULL is an
    option when a pointer is expected (stating the obvious :) ). The code
    becomes somewhat more self-documenting.

    Any comments on why this could be a bad idea or do you think it's just
    a matter of taste?

    /H
     
    Mr A, Jul 10, 2005
    #1
    1. Advertising

  2. Mr A

    Alan Johnson Guest

    Mr A wrote:
    > 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 must be an object
    >
    > instead of
    >
    > void func(Object* object); //object can be NULL
    >
    > I belive that this is a good idea since , in the reference case, it's
    > clear that NULL is not an option. It's also clear that NULL is an
    > option when a pointer is expected (stating the obvious :) ). The code
    > becomes somewhat more self-documenting.
    >
    > Any comments on why this could be a bad idea or do you think it's just
    > a matter of taste?
    >
    > /H


    That is exactly the right way to do it. I'd go so far as to say always
    prefer a reference over a pointer unless you have an explicit need for a
    pointer (i.e. it needs to be reseated for some reason and/or NULL has a
    useful meaning). The reason being pretty much the same that you stated.
    References are (for me at least) easier to work with, and there is no
    worry of accidentally trying to access an object through a "NULL reference".

    -Alan
     
    Alan Johnson, Jul 10, 2005
    #2
    1. Advertising

  3. Mr A wrote:

    > 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 must be an object
    >
    > instead of
    >
    > void func(Object* object); //object can be NULL
    >
    > I belive that this is a good idea since , in the reference case, it's
    > clear that NULL is not an option. It's also clear that NULL is an
    > option when a pointer is expected (stating the obvious :) ). The code
    > becomes somewhat more self-documenting.
    >
    > Any comments on why this could be a bad idea or do you think it's just
    > a matter of taste?
    >
    > /H


    Unfortunately, there are different vantage points from which we view a
    function: declaration, definition and invocation. Each has it's own
    exposed and hidden information. It has been argued that passing a pointer
    is more explicit, and makes the code easier to read. I tend to agree.

    AFAIK, you *can* pass a null to func() in your example, and the compiler
    will accept it. Your code will segfault when you do so. If you pass a
    pointer, you can check for null, before accessing it. I, therefore,
    suggest using a pointer instead of a reference.


    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #3
  4. Steven T. Hatton wrote:
    > Mr A wrote:
    >
    >>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 must be an object
    >>
    >>instead of
    >>
    >>void func(Object* object); //object can be NULL
    >>
    >>I belive that this is a good idea since , in the reference case, it's
    >>clear that NULL is not an option. It's also clear that NULL is an
    >>option when a pointer is expected (stating the obvious :) ). The code
    >>becomes somewhat more self-documenting.
    >>



    The above paragraph is correct. Attempting to pass ANYTHING except
    a ref to an existing instance of the required type will cause a
    compile-time error. Unless there is some specific reason to pass a
    pointer, using ref's is usually preferred.


    >>Any comments on why this could be a bad idea or do you think it's just
    >>a matter of taste?
    >>
    >>/H

    >
    > Unfortunately, there are different vantage points from which we view a
    > function: declaration, definition and invocation. Each has it's own
    > exposed and hidden information. It has been argued that passing a pointer
    > is more explicit, and makes the code easier to read. I tend to agree.
    >
    > AFAIK, you *can* pass a null to func() in your example, and the compiler
    > will accept it. Your code will segfault when you do so. If you pass a
    > pointer, you can check for null, before accessing it. I, therefore,
    > suggest using a pointer instead of a reference.
    >
    >


    If a function takes a ref, then NULL can not be passed.
    Attempting to pass NULL causes a compile error.
    For example:

    #include <iostream>

    struct Stuff
    {
    int a;
    double b;
    };

    void func(Stuff& obj)
    {
    obj.a = 1;
    }

    int main()
    {
    Stuff s;

    func(s);
    func(0); // causes a compile error

    return 0;
    }

    Larry
     
    Larry I Smith, Jul 10, 2005
    #4
  5. Larry I Smith wrote:

    > Steven T. Hatton wrote:
    >> Mr A wrote:

    [...]
    >>>I belive that this is a good idea since , in the reference case, it's
    >>>clear that NULL is not an option. It's also clear that NULL is an
    >>>option when a pointer is expected (stating the obvious :) ). The code
    >>>becomes somewhat more self-documenting.
    >>>

    >
    >
    > The above paragraph is correct. Attempting to pass ANYTHING except
    > a ref to an existing instance of the required type will cause a
    > compile-time error. Unless there is some specific reason to pass a
    > pointer, using ref's is usually preferred.


    By whom?

    >>>Any comments on why this could be a bad idea or do you think it's just
    >>>a matter of taste?
    >>>
    >>>/H

    >>
    >> Unfortunately, there are different vantage points from which we view a
    >> function: declaration, definition and invocation. Each has it's own
    >> exposed and hidden information. It has been argued that passing a
    >> pointer is more explicit, and makes the code easier to read. I tend to
    >> agree.
    >>
    >> AFAIK, you *can* pass a null to func() in your example, and the compiler
    >> will accept it. Your code will segfault when you do so. If you pass a
    >> pointer, you can check for null, before accessing it. I, therefore,
    >> suggest using a pointer instead of a reference.
    >>
    >>

    >
    > If a function takes a ref, then NULL can not be passed.
    > Attempting to pass NULL causes a compile error.
    > For example:
    >
    > #include <iostream>
    >
    > struct Stuff
    > {
    > int a;
    > double b;
    > };
    >
    > void func(Stuff& obj)
    > {
    > obj.a = 1;
    > }
    >
    > int main()
    > {
    > Stuff s;
    >
    > func(s);
    > func(0); // causes a compile error
    >
    > return 0;
    > }
    >
    > Larry


    In your example, you are not trying to pass null, you are trying to pass a
    literal. That results in the attempt to create a temporary object of type
    int and assign it to the non-const reference. This, however, will compile:

    #include <string>
    std::string func(std::string& s) { return s; }
    int main() {
    std::string* s(0);
    func(*s);
    }

    I know of two companies who have concluded that passing by reference is, in
    general, a bad choice. Trolltech, and SuSE.
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #5
  6. Mr A

    John Carson Guest

    "Steven T. Hatton" <> wrote in message
    news:
    >
    > In your example, you are not trying to pass null, you are trying to
    > pass a literal.


    He is passing NULL which is the same as 0.

    > That results in the attempt to create a temporary
    > object of type int and assign it to the non-const reference. This,
    > however, will compile:
    >
    > #include <string>
    > std::string func(std::string& s) { return s; }
    > int main() {
    > std::string* s(0);
    > func(*s);
    > }


    Dereferencing a NULL pointer is undefined behaviour by section 8.3.2/4.
    When I run your code, the program crashes.

    --
    John Carson
     
    John Carson, Jul 10, 2005
    #6
  7. Mr A

    John Carson Guest

    "Steven T. Hatton" <> wrote in message
    news:
    >>>
    >>> AFAIK, you *can* pass a null to func() in your example, and the
    >>> compiler will accept it. Your code will segfault when you do so.
    >>> If you pass a pointer, you can check for null, before accessing it.
    >>> I, therefore, suggest using a pointer instead of a reference.


    I missed this bit. It seems you are aware of the problem.

    --
    John Carson
     
    John Carson, Jul 10, 2005
    #7
  8. Steven T. Hatton wrote:

    > Larry I Smith wrote:
    >
    >> Steven T. Hatton wrote:
    >>> Mr A wrote:

    > [...]
    >>>>I belive that this is a good idea since , in the reference case, it's
    >>>>clear that NULL is not an option. It's also clear that NULL is an
    >>>>option when a pointer is expected (stating the obvious :) ). The code
    >>>>becomes somewhat more self-documenting.
    >>>>

    >>
    >>
    >> The above paragraph is correct. Attempting to pass ANYTHING except
    >> a ref to an existing instance of the required type will cause a
    >> compile-time error. Unless there is some specific reason to pass a
    >> pointer, using ref's is usually preferred.

    >
    > By whom?
    >
    >>>>Any comments on why this could be a bad idea or do you think it's just
    >>>>a matter of taste?
    >>>>
    >>>>/H
    >>>
    >>> Unfortunately, there are different vantage points from which we view a
    >>> function: declaration, definition and invocation. Each has it's own
    >>> exposed and hidden information. It has been argued that passing a
    >>> pointer is more explicit, and makes the code easier to read. I tend to
    >>> agree.
    >>>
    >>> AFAIK, you *can* pass a null to func() in your example, and the compiler
    >>> will accept it. Your code will segfault when you do so. If you pass a
    >>> pointer, you can check for null, before accessing it. I, therefore,
    >>> suggest using a pointer instead of a reference.
    >>>
    >>>

    >>
    >> If a function takes a ref, then NULL can not be passed.
    >> Attempting to pass NULL causes a compile error.
    >> For example:
    >>
    >> #include <iostream>
    >>
    >> struct Stuff
    >> {
    >> int a;
    >> double b;
    >> };
    >>
    >> void func(Stuff& obj)
    >> {
    >> obj.a = 1;
    >> }
    >>
    >> int main()
    >> {
    >> Stuff s;
    >>
    >> func(s);
    >> func(0); // causes a compile error
    >>
    >> return 0;
    >> }
    >>
    >> Larry

    >
    > In your example, you are not trying to pass null, you are trying to pass a
    > literal. That results in the attempt to create a temporary object of type
    > int and assign it to the non-const reference. This, however, will
    > compile:
    >
    > #include <string>
    > std::string func(std::string& s) { return s; }
    > int main() {
    > std::string* s(0);
    > func(*s);
    > }
    >
    > I know of two companies who have concluded that passing by reference is,
    > in
    > general, a bad choice. Trolltech, and SuSE.



    Obvious exceptions are:

    std::eek:stream& print(std::eek:stream& out) const {...}

    and when passing a const reference:

    int foo(const BigObject& bo){}
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #8
  9. John Carson wrote:

    > "Steven T. Hatton" <> wrote in message
    > news:
    >>
    >> In your example, you are not trying to pass null, you are trying to
    >> pass a literal.

    >
    > He is passing NULL which is the same as 0.


    '0', when it appears in your code, is a literal. If the reference were
    const, the code /would/ compile.

    #include <string>
    std::string cfunc(const std::string& s) { return s; }
    int main() {
    cfunc(0);
    }

    It still has a problem. The above aborts when executed. That's one better
    than a segfault, but not typically what I want from a program.

    >> That results in the attempt to create a temporary
    >> object of type int and assign it to the non-const reference. This,
    >> however, will compile:
    >>
    >> #include <string>
    >> std::string func(std::string& s) { return s; }
    >> int main() {
    >> std::string* s(0);
    >> func(*s);
    >> }

    >
    > Dereferencing a NULL pointer is undefined behaviour by section 8.3.2/4.
    > When I run your code, the program crashes.


    Yes, it segfaults. That was my point.

    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #9
  10. Mr A

    Kristo Guest

    Mr A wrote:
    > 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 must be an object
    >
    > instead of
    >
    > void func(Object* object); //object can be NULL
    >
    > I belive that this is a good idea since , in the reference case, it's
    > clear that NULL is not an option. It's also clear that NULL is an
    > option when a pointer is expected (stating the obvious :) ). The code
    > becomes somewhat more self-documenting.
    >
    > Any comments on why this could be a bad idea or do you think it's just
    > a matter of taste?


    That looks like a very good idea to me, and IIRC, the FAQ agrees. IMHO,
    it's more than a matter of style; it's also a matter of safety. If a
    parameter should never be null, then don't give it the chance.

    Kristo
     
    Kristo, Jul 10, 2005
    #10
  11. Why make every little routine test over and over again something that
    isn't to ever happen?

    The question people ask is, IMO, the wrong one.
    People ask: When should I pass by reference?
    The right question is "When should I pass by pointer?"

    and the answer is "Whenever you want to allow a pointer-to-nothing
    (i.e. 0)"
    which is in my experience almost never.

    I go one step further:
    Pass by const reference unless the object may change.
    This way when you call some code the intent is crystal clear.

    I don't buy the argument that someone might then dereference a null
    pointer and thus you always have to protect your code. Your interface
    is a contract. At least with references you are making your intent
    clear. Pass by pointer and you are saying "You're allowed to pass 0".
    Too often if you rely on this in other people's code you'll be
    surprised by seg faults because they did not handle being passed 0 --
    they really meant it had to point to something.

    You rely on other things in the contract: that the kind of object is
    the kind you ask for (no static_cast downcasting to the wrong type or
    your program will crash), that the relationships between objects is set
    up, and so forth. For clarity of code and ease of maintainability I've
    found passing by reference (const and non-const) leads to far clearer,
    more maintainable and more robust code. Adding null pointer checks all
    over the place instead of only in the places where the pointers can be
    0 hides programmer intent while adding noise to the program and slowing
    runtime. So why do it?

    Stuart
     
    Stuart MacMartin, Jul 10, 2005
    #11
  12. Kristo wrote:

    > Mr A wrote:
    >> 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 must be an object
    >>
    >> instead of
    >>
    >> void func(Object* object); //object can be NULL
    >>
    >> I belive that this is a good idea since , in the reference case, it's
    >> clear that NULL is not an option. It's also clear that NULL is an
    >> option when a pointer is expected (stating the obvious :) ). The code
    >> becomes somewhat more self-documenting.
    >>
    >> Any comments on why this could be a bad idea or do you think it's just
    >> a matter of taste?

    >
    > That looks like a very good idea to me, and IIRC, the FAQ agrees. IMHO,
    > it's more than a matter of style; it's also a matter of safety. If a
    > parameter should never be null, then don't give it the chance.
    >
    > Kristo


    This is one man's opinion:
    http://doc.trolltech.com/qq/qq13-apis.html
    Pointers or References?

    Which is best for out-parameters, pointers or references?

    void getHsv(int *h, int *s, int *v) const
    void getHsv(int &h, int &s, int &v) const


    Most C++ books recommend references whenever possible, according to the
    general perception that references are "safer and nicer" than pointers. In
    contrast, at Trolltech, we tend to prefer pointers because they make the
    user code more readable. Compare:

    color.getHsv(&h, &s, &v);
    color.getHsv(h, s, v);


    Only the first line makes it clear that there's a high probability that h,
    s, and v will be modified by the function call.

    http://en.wikipedia.org/wiki/Matthias_Ettrich
    http://www.kde.org/

    When I started working with the KDE, I could download it with a 28.8 modem,
    build and install it in a matter of a few minutes on a Pentium. It now
    occupies 1.2 G on my harddrive. That may (does) represent some bloat, but
    it also represents unquestionable progress. Ettrich is a man who
    understands the three principles of good software design. User interface,
    user interface, and user interface.
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #12
  13. Mr A

    Ian Guest

    Kristo wrote:
    > Mr A wrote:
    >
    >>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 must be an object
    >>
    >>instead of
    >>
    >>void func(Object* object); //object can be NULL
    >>
    >>I belive that this is a good idea since , in the reference case, it's
    >>clear that NULL is not an option. It's also clear that NULL is an
    >>option when a pointer is expected (stating the obvious :) ). The code
    >>becomes somewhat more self-documenting.
    >>
    >>Any comments on why this could be a bad idea or do you think it's just
    >>a matter of taste?

    >
    >
    > That looks like a very good idea to me, and IIRC, the FAQ agrees. IMHO,
    > it's more than a matter of style; it's also a matter of safety. If a
    > parameter should never be null, then don't give it the chance.
    >

    And passing by reference does this? I don't think so.

    Ian
     
    Ian, Jul 10, 2005
    #13
  14. Steven T. Hatton wrote:
    > John Carson wrote:
    >
    >>"Steven T. Hatton" <> wrote in message
    >>news:
    >>>In your example, you are not trying to pass null, you are trying to
    >>>pass a literal.

    >>He is passing NULL which is the same as 0.

    >
    > '0', when it appears in your code, is a literal. If the reference were
    > const, the code /would/ compile.
    >


    In C++ NULL is zero (0).


    > #include <string>
    > std::string cfunc(const std::string& s) { return s; }
    > int main() {
    > cfunc(0);
    > }
    >
    > It still has a problem. The above aborts when executed. That's one better
    > than a segfault, but not typically what I want from a program.
    >
    >>>That results in the attempt to create a temporary
    >>>object of type int and assign it to the non-const reference. This,
    >>>however, will compile:
    >>>
    >>>#include <string>
    >>>std::string func(std::string& s) { return s; }
    >>>int main() {
    >>> std::string* s(0);
    >>> func(*s);
    >>>}

    >>Dereferencing a NULL pointer is undefined behaviour by section 8.3.2/4.
    >>When I run your code, the program crashes.

    >
    > Yes, it segfaults. That was my point.
    >


    #include <iostream>
    #include <string>

    struct Stuff
    {
    int a;
    double b;
    };

    void func(const Stuff& obj)
    {
    obj.a = 1;
    }

    int main()
    {
    Stuff s;
    Stuff *sp = 0;

    func(s);
    // the next 3 produce comple time errors
    func(0);
    func(NULL);
    func(sp);
    // the next one is a stupid programmer error - deref'ing a NULL
    // pointer. it crashes before func() is called - a good reason
    // to use ref's exclusively rather than pointers.
    func(*sp);

    return 0;
    }


    The pros & cons of refs vs pointers could be argued forever.
    Advocates of the different approaches will probably never
    agree. So let's not beat it to death anymore.

    Regards,
    Larry
     
    Larry I Smith, Jul 10, 2005
    #14
  15. Stuart MacMartin wrote:

    > Why make every little routine test over and over again something that
    > isn't to ever happen?


    Not sure what you mean here. If you can ensure that the error cannot
    happen, then there's no point in testing for it. OTOH, if you can't be
    sure it won't happen, then you either take your chances for the sake of
    performance (and should ask yourself if it really is all that costly to
    make the check), or you put in an error check.

    > The question people ask is, IMO, the wrong one.
    > People ask: When should I pass by reference?
    > The right question is "When should I pass by pointer?"
    >
    > and the answer is "Whenever you want to allow a pointer-to-nothing
    > (i.e. 0)"
    > which is in my experience almost never.


    That is certainly not a universal assumption. I would never intentionally
    pass a null pointer unless I had explicit information telling me it was OK.

    > I go one step further:
    > Pass by const reference unless the object may change.
    > This way when you call some code the intent is crystal clear.
    >
    > I don't buy the argument that someone might then dereference a null
    > pointer and thus you always have to protect your code. Your interface
    > is a contract. At least with references you are making your intent
    > clear.


    Assuming the person maintaining the code actually looks at the function
    declaration, rather than just the call. It would appear (much to my
    amazement) many C++ programmers believe a programmer should *not* look at
    the actual source code where the interface is declared.

    > Pass by pointer and you are saying "You're allowed to pass 0".
    > Too often if you rely on this in other people's code you'll be
    > surprised by seg faults because they did not handle being passed 0 --
    > they really meant it had to point to something.


    It seems to me your understanding of the implication of a pointer parameter
    is unfounded. The only time I might assume it's safe to pass a null
    pointer is if the parameter has a default null value.

    > You rely on other things in the contract: that the kind of object is
    > the kind you ask for (no static_cast downcasting to the wrong type or
    > your program will crash), that the relationships between objects is set
    > up, and so forth. For clarity of code and ease of maintainability I've
    > found passing by reference (const and non-const) leads to far clearer,
    > more maintainable and more robust code.


    I certainly prefer the use of operator[](), operator.() on a reference or an
    object over doing the same on a pointer. If you are working with a
    conceptual design that uses shared objects, you are almost certainly going
    to use some kind of smart pointer. You will have to dereference that
    somewhere. This is why I find the proposal to overload operator.() and
    operator.*() so attractive. Of course some people believe the new move
    semantics will obviate all need for such things. Clearly that is not the
    case.

    At least with a const reference, I *might* be able to catch an exception.
    With a non-const reference, a null pointer is a segfault.

    > Adding null pointer checks all
    > over the place instead of only in the places where the pointers can be
    > 0 hides programmer intent while adding noise to the program and slowing
    > runtime. So why do it?


    Because code that does use pointers, and proper error checking won't crash
    due to a null pointer, but code that uses references to pass variables
    *can* crash because of a null pointer being passed to a reference. So far
    as I know, there is no way to protect yourself from that, other than
    checking for null before dereferencing.

    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #15
  16. Larry I Smith wrote:

    > Steven T. Hatton wrote:
    >> John Carson wrote:
    >>
    >>>"Steven T. Hatton" <> wrote in message
    >>>news:
    >>>>In your example, you are not trying to pass null, you are trying to
    >>>>pass a literal.
    >>>He is passing NULL which is the same as 0.

    >>
    >> '0', when it appears in your code, is a literal. If the reference were
    >> const, the code /would/ compile.
    >>

    >
    > In C++ NULL is zero (0).


    Exactly my point. It is NOT a null pointer, it is a literal.

    > #include <iostream>
    > #include <string>
    >
    > struct Stuff
    > {
    > int a;
    > double b;
    > };
    >
    > void func(const Stuff& obj)
    > {
    > obj.a = 1;
    > }
    >
    > int main()
    > {
    > Stuff s;
    > Stuff *sp = 0;
    >
    > func(s);
    > // the next 3 produce comple time errors
    > func(0);
    > func(NULL);
    > func(sp);


    The error on the last example is because you are passing a pointer to a non
    pointer type, and has nothing to do with the value of the type. In the
    pervious examples you are passing an integer literal which is likewise
    illegal.


    > // the next one is a stupid programmer error - deref'ing a NULL
    > // pointer. it crashes before func() is called - a good reason
    > // to use ref's exclusively rather than pointers.
    > func(*sp);
    >
    > return 0;
    > }
    >
    >
    > The pros & cons of refs vs pointers could be argued forever.
    > Advocates of the different approaches will probably never
    > agree. So let's not beat it to death anymore.
    >
    > Regards,
    > Larry


    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell
     
    Steven T. Hatton, Jul 10, 2005
    #16
  17. Mr A

    David White Guest

    Steven T. Hatton wrote:
    > John Carson wrote:
    >
    >> Dereferencing a NULL pointer is undefined behaviour by section
    >> 8.3.2/4. When I run your code, the program crashes.

    >
    > Yes, it segfaults. That was my point.


    There's no mention of segfaulting in the standard. The behaviour is
    undefined. That means that anything can happen, including the function
    executing without any apparent problem.

    DW
     
    David White, Jul 10, 2005
    #17
  18. Mr A

    David White Guest

    Mr A wrote:
    > 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 must be an object
    >
    > instead of
    >
    > void func(Object* object); //object can be NULL
    >
    > I belive that this is a good idea since , in the reference case, it's
    > clear that NULL is not an option. It's also clear that NULL is an
    > option when a pointer is expected (stating the obvious :) ).


    Not necessarily. Try passing a null pointer to ::strlen(). Just because a
    pointer is passed doesn't necessarily mean that the function will permit it
    to be null.

    > The code
    > becomes somewhat more self-documenting.


    Yes, because you at least don't have to bother finding out if a null pointer
    is acceptable.

    > Any comments on why this could be a bad idea or do you think it's just
    > a matter of taste?


    One thing about the reference case is that you can't tell from the call
    whether it is pass by value or pass by reference. In the pointer case it is
    at least obvious from the call that an address is being passed, so you are
    alerted that the function might change the object.

    DW
     
    David White, Jul 11, 2005
    #18
  19. Well I suppose most of this comes down to local convention. I prefer to
    work with references, and allow a semantic difference between a
    parameter passed by reference rather than passed by pointer.

    Your comment:
    Because code that does use pointers, and proper error checking won't
    crash due to a null pointer, but code that uses references to pass
    variables *can* crash because of a null pointer being passed to a
    reference. So far as I know, there is no way to protect yourself from
    that, other than checking for null before dereferencing.

    And that's precisely the point.

    I figure you should check for null before dereferencing (or otherwise
    using what a pointer points to), and once you've safely dereferenced
    continue to use that reference. You feel you should not trust your
    caller, so insist on checking the pointer over and over again - and
    instead of trusting your callers like I do, you trust the people who
    write the routines you call. Since you'd check that the address of a
    reference isn't 0, you see no semantic difference between passing a
    pointer and a reference.

    Just out of curiosity: do you do dynamic_cast of all your variables to
    make sure the types are the same as the parameters you specified? This
    might sound snide, but I've had people downcast or force a cast
    incorrectly, with problems only showing up when the data model changes
    significantly or subtly on on rare data. If you can't believe they are
    passing a reference to an object when you ask for a reference, how can
    you believe that they are passing the correct kind of object? It's
    easy to fool the compiler into allowing this. The compiler can help
    us, but only to a point. Eventually someone has to understand what a
    routine is supposed to do before they call it.

    Another thing that puzzles me in all of this: doesn't anyone use a
    development environment? How can you not know the parameters and
    whether they are passed by value or pointer or reference, const or
    non-const?

    Stuart
     
    Stuart MacMartin, Jul 11, 2005
    #19
  20. Mr A

    benben Guest

    Well you CAN pass a reference to nothing though:

    void f(int& i)
    {
    i ++;
    }

    int main()
    {
    int* i = new int;
    int& ref = *i;
    delete i;

    f(ref); // tell me what does ref referencing to?
    }

    ben
     
    benben, Jul 11, 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:
    10
    Views:
    1,255
    Big K
    Feb 2, 2005
  2. Robert
    Replies:
    10
    Views:
    1,379
    E. Robert Tisdale
    Aug 24, 2005
  3. LuB
    Replies:
    6
    Views:
    464
    Mike Wahler
    Sep 23, 2005
  4. rantingrick
    Replies:
    44
    Views:
    1,247
    Peter Pearson
    Jul 13, 2010
  5. A
    Replies:
    7
    Views:
    644
Loading...

Share This Page