From: Bo Persson on
Ben Voigt [C++ MVP] wrote:
:: "David Wilkinson" <no-reply(a)effisols.com> wrote in message
:: news:eR1GUla3HHA.4584(a)TK2MSFTNGP03.phx.gbl...
::: Gerry Hickman wrote:
:::: I guessed 'returns' should be a comment, but the first two lines
:::: didn't make sense with void following vector<string>::size_type,
:::: I guess I was supposed to _replace_ void with
:::: vector<string>::size_type, seems obvious now.
:::
:::: Does this only apply to the 'pointer' version, or does it apply
:::: to the 'references' version too?
:::
::: Gerry:
:::
::: The "void" is Doug's post was a typo, I think. This confused me
::: also.
:::
::: When you pass a pointer, the "implication" is that it could be
::: NULL, and that the function will take some special action in this
::: case. If you pass a reference, it cannot be NULL (every reference
::: must be initialized to some object), so no such action need be
::: taken.
::
:: This "every reference must be initialized to some object" is not
:: true. Any pointer can be converted to a reference.
::

But you can't convert the pointer to an invalid reference, without
invoking undefined behavior. Then it's your problem.


Bo Persson


From: Doug Harrison [MVP] on
On Mon, 13 Aug 2007 13:13:18 +0100, Gerry Hickman
<gerry666uk(a)newsgroup.nospam> wrote:

>I was confused by Doug's example, I'd copied it literally
>
>vector<string>::size_type
>void GetDeviceClasses(vector<string>& guids)
>{
> guids.clear();
> // If you can estimate n, reserve can eliminate reallocations.
> // guids.reserve(n);
> ...
> returns guids.size();
>}
>
>I guessed 'returns' should be a comment, but the first two lines didn't
>make sense with void following vector<string>::size_type, I guess I was
>supposed to _replace_ void with vector<string>::size_type, seems obvious
>now.

Of course, I meant to write:

vector<string>::size_type
GetDeviceClasses(vector<string>& guids)
{
guids.clear();
// If you can estimate n, reserve can eliminate reallocations.
// guids.reserve(n);
...
return guids.size();
}

I'm amazed that no one, including myself, has commented on this before now.
:) I think what happened back in July, when I was replying to your original
thread, is that, I initially had the function returning void, but then I
reviewed your example and saw it would be useful to return the number of
GUIDs that were found. Or maybe I thought, "Hmmm, this function is
essentially an unbounded 'read' function for GUIDs, so why not return the
number read?" Whatever I thought, I followed it up by performing an
unusually sloppy edit. Sorry about that.

--
Doug Harrison
Visual C++ MVP
From: Doug Harrison [MVP] on
On Mon, 13 Aug 2007 08:36:57 -0500, "Ben Voigt [C++ MVP]"
<rbv(a)nospam.nospam> wrote:

>That's not true. It's illegal to use a null reference, but in the same way
>that it's illegal to use a null pointer.

Not quite. It's illegal to form a "null reference" in the first place, so
the error happens earlier. Unfortunately, the error is typically revealed
at the same time and in the same way as when using pointers. Put another
way, it's not "illegal to use a null reference," because "null references"
don't exist in correct programs, which of course, can and often do
(legally) have "null pointers". (I know you don't put much weight in what's
typically said about references, but see my other reply for more on that.)

--
Doug Harrison
Visual C++ MVP
From: Ben Voigt [C++ MVP] on

"Bo Persson" <bop(a)gmb.dk> wrote in message
news:5ibbgaF3op5viU1(a)mid.individual.net...
> Ben Voigt [C++ MVP] wrote:
> :: "Ulrich Eckhardt" <eckhardt(a)satorlaser.com> wrote in message
> :: news:tp06p4-ile.ln1(a)satorlaser.homedns.org...
> ::: Gerry Hickman wrote:
> :::::: void PopulateStrings(vector<string> * guids)
> :::::: {
> :::::: guids->clear();
> :::::: guids->push_back("test1");
> :::::: guids->push_back("test2");
> :::::: }
> :::::
> ::::: While this code will work, there is one thing I object to: in
> ::::: C++, where you have references, a pointer[1] means to me that
> ::::: something is optional,
> ::::: i.e. passing zero is okay, but you don't mean that. Still, you
> ::::: must handle that case, so either you just return (making it a
> ::::: non-error), throw an exception (making it a runtime error) or
> ::::: use assert() (making it
> ::::: a programmer's error).
> ::::
> :::: Does this only apply to the 'pointer' version, or does it apply
> :::: to the 'references' version too?
> :::
> ::: A reference can't be null, so this doesn't apply.
> ::
> :: That's not true. It's illegal to use a null reference, but in the
> :: same way that it's illegal to use a null pointer.
>
> There aren't any null references, only invalid ones. Like a reference to
> an object that has been destroyed.
>
> If someone passes an invalid reference to my functions, that is a bug in
> their code, not my problem. If someone passes a null pointer, I must
> handle that.

If someone passes a null or invalid pointer to my function, when the
function documentation forbids it, that is also a bug in their code. There
is no difference between pointers and references in this respect. A
reference is just syntactic sugar for a pointer.


From: Ulrich Eckhardt on
Ben Voigt [C++ MVP] wrote:
> "Bo Persson" <bop(a)gmb.dk> wrote in message
> news:5ibbgaF3op5viU1(a)mid.individual.net...
>> If someone passes an invalid reference to my functions, that is a bug in
>> their code, not my problem. If someone passes a null pointer, I must
>> handle that.
>
> If someone passes a null or invalid pointer to my function, when the
> function documentation forbids it, that is also a bug in their code.

Let's leave aside invalid pointers or references (e.g. to deleted objects or
uninitialised ones), because the mere copying of such singular values leads
to UB.

Then, there remains a function taking a pointer vs one taking a reference.
Creating an invalid reference is illegal anyway, so passing it to a
function is straight out. This means that even without looking at any
documentation I know that the reference can't be null.

> There is no difference between pointers and references in this respect.
> A reference is just syntactic sugar for a pointer.

It gives a different message to the reader. A pointer can be null, a
reference can't. The behaviour of a function when called with a null
pointer needs to be documented, even if it's just "Don't do it!". No such
requirement with a reference, all requirements are implicitly given by the
language.

Of course, the generated binary code is typically the same, but that's a
different issue.

Uli