Topic: No subject given


Author: pasa@lib.hu ("Balog Pal")
Date: Mon, 30 Aug 2004 23:12:32 GMT
Raw View
3220$Sy4.10474@newssvr29.news.prodigy.com> <41332135.7295EA4C@iobox.com>
Subject: Re: Multithreaded programming: suggested primitives
Date: Mon, 30 Aug 2004 23:58:52 +0100
Lines: 50
Organization: LiB
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.50.4942.400
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4942.400
Path: 195.56.19.188
NNTP-Posting-Host: 195.56.19.188
Message-ID: <4133a4b0@andromeda.datanet.hu>
X-Trace: 31 Aug 2004 00:05:36 +0200, 195.56.19.188


""Sergey P. Derevyago"" <non-existent@iobox.com> wrote in message
news:41332135.7295EA4C@iobox.com...

> >     All I'm trying to do is to get some minimal atomic
> > operations into the standard.  Without those, there are
> > things you can't do without dropping into assembler.
> >
> So what? Real-world C++ applications _do_ use assembler to fight
performance
> bottlenecks. IMHO these "minimal atomic operations" are _premature_
> optimization of C++ MT.

You miss some issues.
For one, some protocols have other properties than being faster. So using
those is not mere 'optimisation' or tuning for speed.

For the other, something is premature only when you do it out of order.
When you reach the point to discover the need for optimisation it's no
longer premature but the real goal.  An though anyone can really fall back
to assembly -- it may turn out way cumbersome. While the language could
allow most things at low cost.

> 2. Define a _minimal_ portable set of MT-related C++ objects and actions.
The
> goal is to perform those 20% of work which solves 80% of problems.

What is the gain of fighting to reduce the set to be minimal?  Who will hget
hurt if C++ have say 10 primitives instead of just 4?    Then leave people
wanting the rest to stay where they are now, or keep everyone inventing
their housegrown extensions?

> 3. Carefully design STL MT safety requirements and guarantees.
>
> I believe the last step requires about 80% of C++ MT efforts while we're
> still playing with low-level hardware-dependant bells and whistles...

Yes, revising the library is a plenty of work indeed -- but possibly it's
done already.  As STL is implemeted for MT platforms right now, and the
major implemeters may want to contribute their work to the standard.
Especially as that will save them some work afterwards.

And I wouldn;t call the low-level fundamentum 'bells and whistles'.  As that
will likely turn out the make-or-break for the next decade in language
preference.

Paul



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: lgalfaso@fd.com.ar (=?iso-8859-1?Q?Lucas_Galfas=F3?=)
Date: Mon, 12 Jan 2004 20:35:36 +0000 (UTC)
Raw View
""Jonathan Turkanis"" <technews@kangaroologic.com> wrote in message
news:btsc7v$as728$1@ID-216073.news.uni-berlin.de...
> "Lucas Galfas=F3" <lgalfaso@fd.com.ar> wrote in message:
>=20
> > Hi everyone, I do know if this was an expected feature (restriction)
> of the
> > standard, but
> > 1) You can declare a class with a template constructor that can take
> a
> > non-type template parameter.
> > 2) You cannot instantiate it.
> >
> > Ie
> >
> > struct foo {
> >   template <bool in>
> >   foo () { }
> > };
> >
> > int main ()
> > {
> >   foo b1; // no default constructor (and no workaround)
> >   return 0;
> > }
> >
>=20
> Are you refering to the fact that there is no way to explicitly
> specify the template argument list in a templated constructor
> invocation? If so, it is a known problem (see 14.8.1
> ([temp.arg.explicit]) par 5.) It is not limited to non-type template
> parameters or to constructors which take no arguments.

Something in this area, but no exactly

>=20
> Although it can be an inconvenience, there are several simple
> workarounds. For instance,
>=20
> 1. Make the constructor private, perform initialization in a private
> templated member function and use a static object generator to
> create instances. Usage: foo f =3D foo::create<3>();

This would solve the problem in my example, but is you have

struct bar : public foo
{
 bar () : ???_foo_??? {}
};

this solution will not work

>=20
> 2. Add a dummy parameter to the constructor which allows the template
> parameter to be deduced. E.g.:
>=20
>     template<int N> struct param_t { };
>     template<int N>
>     param_t<N> param() { return param_t<N>(); };
>=20
>     struct foo {
>         template<int N> foo(param_t<N>) { /* ... */ }
>     };
>=20
>     int main()
>     {
>         foo f(param<3>());
>         return 0;
>     }

With this solution, you cannot access the value N at compile time.


>=20
> Jonathan
>=20
>=20


Lucas/


>=20
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with=
 ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu   =
 ]
> [              --- Please see the FAQ before posting. ---              =
 ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                      =
 ]
>

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.555 / Virus Database: 347 - Release Date: 12/23/2003
=20


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: technews@kangaroologic.com ("Jonathan Turkanis")
Date: Tue, 13 Jan 2004 03:41:28 +0000 (UTC)
Raw View
"Lucas Galfas   " <lgalfaso@fd.com.ar> wrote in message
news:000001c3d94a$08665f80$f37bfea9@lucasxp1...
""Jonathan Turkanis"" <technews@kangaroologic.com> wrote in message
>news:btsc7v$as728$1@ID-216073.news.uni-berlin.de...
>> "Lucas Galfas   " <lgalfaso@fd.com.ar> wrote in message:
>>
>> > Hi everyone, I do know if this was an expected feature
(restriction)
>> of the
>> > standard, but
>> > 1) You can declare a class with a template constructor that can
take
>> a
>> > non-type template parameter.
>> > 2) You cannot instantiate it.
>> >
>> > Ie
>> >
>> > struct foo {
>> >   template <bool in>
>> >   foo () { }
>> > };
>> >
>> > int main ()
>> > {
>> >   foo b1; // no default constructor (and no workaround)
>> >   return 0;
>> > }
>> >
>>
>> Are you refering to the fact that there is no way to explicitly
>> specify the template argument list in a templated constructor
>> invocation? If so, it is a known problem (see 14.8.1
>> ([temp.arg.explicit]) par 5.) It is not limited to non-type
template
>> parameters or to constructors which take no arguments.
>
>Something in this area, but no exactly
>

Whew! At least I was close.

>>
>> Although it can be an inconvenience, there are several simple
>> workarounds. For instance,
>>
>> 1. Make the constructor private, perform initialization in a
private
>> templated member function and use a static object generator to
>> create instances. Usage: foo f = foo::create<3>();
>
>This would solve the problem in my example, but is you have
>
>struct bar : public foo
>{
>bar () : ???_foo_??? {}
>};
>
>this solution will not work
>

If you know what integral value xxx you want to use to construct the
base foo, you can use:

     bar() : foo(foo::create<xxx>()) { }

or

     bar() : foo(param<xxx>()) { }

If the value must be specified when a bar is constructed, you can use
either of the suggested techniques for bar. (I should have allowed the
foo constructor and initialization function to be protected for
derivation). To be more explicit:

1. Object generators:

    class foo {
    protected:
        foo() { }
        template<int N> init() { /* ... */ }
    public:
        template<int N>
        static foo create() { foo f; f.init<N>(); return f; }
    };

    class bar : public foo {
    protected:
        bar() { }
        template<int N> init() { foo::init<N>(); }
    public:
        template<int N>
        static bar create() { bar b; b.init<N>(); return b; }
    };

    int main()
    {
        bar b = bar::create<3>();
    }

Or:

    template<int N> bar(param_t<N> p) : foo(p) { }

What's wrong with these solutions? Could you be more specific what the
problem is?

>>
>> 2. Add a dummy parameter to the constructor which allows the
template
>> parameter to be deduced. E.g.:
>>
>>     template<int N> struct param_t { };
>>     template<int N>
>>     param_t<N> param() { return param_t<N>(); };
>>
>>     struct foo {
>>         template<int N> foo(param_t<N>) { /* ... */ }
>>     };
>>
>>     int main()
>>     {
>>         foo f(param<3>());
>>         return 0;
>>     }
>
>With this solution, you cannot access the value N at compile time.
>

Within the templated foo constructor, N is an integral constant
expression. What more do you want?

Best Regards,
Jonathan


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: lgalfaso@fd.com.ar (=?iso-8859-1?Q?Lucas_Galfas=F3?=)
Date: Tue, 13 Jan 2004 19:56:56 +0000 (UTC)
Raw View
Hello everybody,

> 1. Object generators:
>
>     class foo {
>     protected:
>         foo() { }
>         template<int N> init() { /* ... */ }
>     public:
>         template<int N>
>         static foo create() { foo f; f.init<N>(); return f; }
>     };
>
>     class bar : public foo {
>     protected:
>         bar() { }
>         template<int N> init() { foo::init<N>(); }
>     public:
>         template<int N>
>         static bar create() { bar b; b.init<N>(); return b; }
>     };
>
>     int main()
>     {
>         bar b = bar::create<3>();
>     }
>
> Or:
>
>     template<int N> bar(param_t<N> p) : foo(p) { }

Now you need to define operator=, but, what if an operator= could not be
defined (or you want it to be private or something else)?
Plus, you are fixing yourself to an intefase/solution. I think the problem
is that there is no mecanism to explicitly provide template argument to
constructors.


Lucas/

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.555 / Virus Database: 347 - Release Date: 12/23/2003


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: technews@kangaroologic.com ("Jonathan Turkanis")
Date: Thu, 15 Jan 2004 05:55:03 +0000 (UTC)
Raw View
"Lucas Galfas   " <lgalfaso@fd.com.ar> wrote in message:

> Hello everybody,
>
> > 1. Object generators:
> >
> >     class foo {
> >     protected:
> >         foo() { }
> >         template<int N> init() { /* ... */ }
> >     public:
> >         template<int N>
> >         static foo create() { foo f; f.init<N>(); return f; }
> >     };
> >
> >     class bar : public foo {
> >     protected:
> >         bar() { }
> >         template<int N> init() { foo::init<N>(); }
> >     public:
> >         template<int N>
> >         static bar create() { bar b; b.init<N>(); return b; }
> >     };
> >
> >     int main()
> >     {
> >         bar b = bar::create<3>();
> >     }
> >
> > Or:

I should have said: "2. Dummy paramters."

> >
> >     template<int N> bar(param_t<N> p) : foo(p) { }
>
> Now you need to define operator=, but, what if an operator= could
not be
> defined (or you want it to be private or something else)? <snip>

I'm not using an assignment operator, just a plain old
copy-constructor. The above code could be (equivalently) rewritten

    bar b(bar::create<3>());

> I think the problem
> is that there is no mecanism to explicitly provide template argument
to
> constructors.
>

That's what I thought the problem was. I agreed that it was
inconvenient, and offered two workarounds.

Best Regard,
Jonathan



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 30 Oct 2003 19:15:25 +0000 (UTC)
Raw View
kanze@gabi-soft.fr wrote:
+ pasa@lib.hu ("Balog Pal") wrote in message
+ news:<3f93158b@andromeda.datanet.hu>...
+> <thp@cs.ucr.edu> wrote in message news:bmorqk$jn4$1@glue.ucr.edu...
+
+> >   struct Widget {
+> >     int& r;
+> >     Widget(int* p) r(*p) {}
+> >   };
+
+> >   int i, j;
+> >   Widget a(&i);
+> >   Widget b(&j);
+
+> >   // Now "a.r" refers to i.  (Witness that &a.r == &i.)
+
+> >   a=b;
+
+> >   // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)
+
+> Did you try your example? As my compiler just rejected the code.
+
+> >   a=b;
+> error C2582: 'Widget' : 'operator =' function is unavailable
+
+> certainly.
+
+> > Here we have an allegedly stateless entity, namely a's reference
+> > member, changing its behavior in exactly the way one would expect if
+> > it had state, i.e., it now behaves just like the corresponding
+> > member of b.
+
+> Well, try and create an op= avoiding UB, then we can examine if what
+> you write actually happens or not.
+
+ You mean something like:
+
+    Widget&
+    Widget::operator=( Widget const& other )
+    {
+        if ( this != &other ) {
+            this->~Widget() ;
+            new ( this ) Widget( other ) ;
+        }
+        return *this ;
+
+ While exceedingly dangerous, there's no undefined behavior here.
+
+ On the other hand, the state of the reference hasn't changed; one
+ reference ceased to exist, and another was created.
+
+ But the arguments seem more theoretic than anything else.  Formally the
+ state of a reference cannot change, any more than the state of a
+ constant object can change.  Never the less, we speak of the state of a
+ constant object.  The "statelessness" of a reference, if such exists, is
+ a combination of many things, but mainly the fact that, even in the
+ cases where the reference actually does occupy memory, there is no way
+ to access that memory.

So, presumably the following class should work in the sense that
programs that handle it carefully can conform:

    class Widget {
       int& r;
       Widget( int& i ) r(i) {}
       void reat( int& i ) {
         this->~Widget();
         new(this) Widget(i);
       }
    };

I realize that reseat() only seems to reseat r and, in fact, reseat()
destructs and reconstructs the entire Widget surrounding r.  But, by
the as-if rule, an implementation is free to implement reseat by
simply reseating r, which is probably what the optimized code would
turn out to be in any case.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Thu, 30 Oct 2003 19:16:10 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bnno5s$3ui$1@glue.ucr.edu>...
> James Kuyper <kuyper@wizard.net> wrote:
...
> + See section 3.8p7. It specifies quite clearly the conditions
> + controlling whether or not a pointer or reference to an object that
> + has been destroyed can be safely used to refer to a new object created
> + at the same storage location. Those conditions are all being met in
> + this case.
>
> Thanks -- I stand corrected.  But then, I'm curious about the
> purported dangers in the case at hand, e.g., why it is like writing a
> union via one member and reading it via another and/or reading stack
> garbage via uninitialized automatic variables.

Well, it's hard to discuss the reasons why something is true, when
that something isn't true. Writing a union via one member and reading
it with another  has undefined behavior. Reading the values of
uninitialized variables has undefined behavior because they may not
contain valid values. Using a pointer or reference in the
circumstances described by 3.8.7 carries neither of those dangers.

> There is also the somewhat philosophical question of whether the
> evaluation of such an assignment expression "w1=w2":
>   1) reseats references to w1 to refer to w2's new clone.
>   2) changes the state of their referents to resemble w2.

I think that's pretty much the same as the difference between 6 and "a
half dozen".

> Finally, consider:
>
>   class Widget {
>   public:
>     int& r;
>     Widget() r(*new int) {}
>   } w1, w2;
>
> After evaluation of "w1=w2", is it guaranteed that "&w1.r == &w2.r"?

12.8p12: "A program is ill-formed if the class for which a copy
assignment operatore is implicitly defined has:
...
-- a non-static data member of reference type"


Therefore, nothing is guaranteed about the behavior of such code.
However, a suitably defined copy assignment operator could use
placement new to invoke the copy constructor, with the net effect of
re-seating r. In that case, &w1.r==&w2.r would be guaranteed.

> I think that was James' original point, but I got confused by the

Hey! I'm James too - you need to disambiguate us when we're both
participating in the same discussion. Note: "James K" is insufficient
for this purpose. :-)

> purported "dangers", which I still don't understand.  I followed the
> part where "w1=w2" has defined behavior but taking its behavior at
> face value may lead to undefined behavior.  My conjecture that such
> undefined behavior we follow from references to w1 suddenly dangling
> has been refuted.  So, how does unusual defined-or-undefined behavior
> enter here?

Copy constructors that throw are commonplace. However, copy assignment
operators that can throw are a serious problem, particularly if they
explicitly call this->~ClassName() before throwing. Such a copy
assignment operator also performs a slicing copy in the context of a
derived class, which is often undesirable.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Fri, 31 Oct 2003 17:04:49 +0000 (UTC)
Raw View
James Kuyper <kuyper@wizard.net> wrote:
+ thp@cs.ucr.edu wrote in message news:<bnno5s$3ui$1@glue.ucr.edu>...
+> James Kuyper <kuyper@wizard.net> wrote:
+ ...
+> + See section 3.8p7. It specifies quite clearly the conditions
+> + controlling whether or not a pointer or reference to an object that
+> + has been destroyed can be safely used to refer to a new object created
+> + at the same storage location. Those conditions are all being met in
+> + this case.
+>
+> Thanks -- I stand corrected.  But then, I'm curious about the
+> purported dangers in the case at hand, e.g., why it is like writing a
+> union via one member and reading it via another and/or reading stack
+> garbage via uninitialized automatic variables.
+
+ Well, it's hard to discuss the reasons why something is true, when
+ that something isn't true. Writing a union via one member and reading
+ it with another  has undefined behavior. Reading the values of
+ uninitialized variables has undefined behavior because they may not
+ contain valid values. Using a pointer or reference in the
+ circumstances described by 3.8.7 carries neither of those dangers.

Hmmmm.  IIRC, those analogies were from the other James K.  ;-)

+> There is also the somewhat philosophical question of whether the
+> evaluation of such an assignment expression "w1=w2":
+>   1) reseats references to w1 to refer to w2's new clone.
+>   2) changes the state of their referents to resemble w2.
+
+ I think that's pretty much the same as the difference between 6 and "a
+ half dozen".

Operationally, it makes no difference, but which way one views the
event affects the their sense of whether references as "stateful
entities", which in common parlance are usually call "objects".  IMHO,
if it walks like a duck and squawks like a duck, it must be a duck.

+> Finally, consider:
+>
+>   class Widget {
+>   public:
+>     int& r;
+>     Widget() r(*new int) {}
+>   } w1, w2;
+>
+> After evaluation of "w1=w2", is it guaranteed that "&w1.r == &w2.r"?
+
+ 12.8p12: "A program is ill-formed if the class for which a copy
+ assignment operatore is implicitly defined has:
+ ...
+ -- a non-static data member of reference type"
+
+
+ Therefore, nothing is guaranteed about the behavior of such code.
+ However, a suitably defined copy assignment operator could use
+ placement new to invoke the copy constructor, with the net effect of
+ re-seating r. In that case, &w1.r==&w2.r would be guaranteed.

I had in mind that weird operator-= based on placement new.

+> I think that was James' original point, but I got confused by the
+
+ Hey! I'm James too - you need to disambiguate us when we're both
+ participating in the same discussion. Note: "James K" is insufficient
+ for this purpose. :-)

Again I stand corrected.

+> purported "dangers", which I still don't understand.  I followed the
+> part where "w1=w2" has defined behavior but taking its behavior at
+> face value may lead to undefined behavior.  My conjecture that such
+> undefined behavior we follow from references to w1 suddenly dangling
+> has been refuted.  So, how does unusual defined-or-undefined behavior
+> enter here?
+
+ Copy constructors that throw are commonplace. However, copy assignment
+ operators that can throw are a serious problem, particularly if they
+ explicitly call this->~ClassName() before throwing. Such a copy
+ assignment operator also performs a slicing copy in the context of a
+ derived class, which is often undesirable.

It would be interesting (but dangerous) to have an operator that
would, in effect, reseat a given reference member of a struct-or-class
object while preserving the state of the object's other members --
(un)fortunately, I don't see how this placement new trick could be
used to accomplish that.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Sun, 19 Oct 2003 19:28:37 +0000 (UTC)
Raw View
In article <bmfrjj$5oo$2@glue.ucr.edu>, thp@cs.ucr.edu writes
>We are talking about behavior, not implementation.  So, by what
>behavioral test do you determine that a reference never has location?

Turn that round, how do you determine that they do. I know of no way to
determine the location of a reference only ways to determine the
location of the object referred to.


--
Francis Glassborow      ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Sun, 19 Oct 2003 19:29:01 +0000 (UTC)
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ In article <bmlco0$kei$1@glue.ucr.edu>, thp@cs.ucr.edu writes
+>
+>class Widget {
+>  int& r;
+>  Widget() r(*new int) {}
+>};
+>
+>In what way do distinct instances of Widget differ if r has no state,
+>no location, and no space that are associated with the instance of
+>Widget, not with their referents?
+>
+>Tom Payne
+>
+ We can argue philosophy for ever and a day. Being an Oxford University
+ graduate means that I have been exposed to such debates since my late
+ adolescent years.

So, how do Oxford graduates explain sudden shifts in behavior by
stateless entities?  Consider:

  struct Widget {
    int& r;
    Widget(int* p) r(*p) {}
  };

  int i, j;
  Widget a(&i);
  Widget b(&j);

  // Now "a.r" refers to i.  (Witness that &a.r == &i.)

  a=b;

  // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)

Here we have an allegedly stateless entity, namely a's reference
member, changing its behavior in exactly the way one would expect if
it had state, i.e., it now behaves just like the corresponding member
of b.  When struct members of other types do that, we describe/explain
the phenomenon as a "change of state".

Anyone accepts that references are stateless should be astonished.  By
contrast, those who expect references to behave like implicitly
dereferenced pointers should expect exactly the above behavior.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ahp6@email.byu.edu ("Adam H. Peterson")
Date: Sun, 19 Oct 2003 23:46:08 +0000 (UTC)
Raw View
> So, how do Oxford graduates explain sudden shifts in behavior by
> stateless entities?  Consider:
>
>   struct Widget {
>     int& r;
>     Widget(int* p) r(*p) {}
>   };
>
>   int i, j;
>   Widget a(&i);
>   Widget b(&j);
>
>   // Now "a.r" refers to i.  (Witness that &a.r == &i.)
>
>   a=b;
>
>   // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)

This looks to me like it should not compile (ignoring the typo syntax
problem).  This would be tantamount to reseating a reference, which
can't be done without UB.

GCC doesn't seem to like it:

Main.cpp: In member function `Widget& Widget::operator=(const Widget&)':
Main.cpp:32: non-static reference member `int&Widget::r', can't use
default assignment operator

And that is consistent with what I remember: that classes with reference
or const (nonstatic) members must provide their own assignment operators
  if they are to be assignable.

Adam Peterson

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: m.collett@auckland.ac.nz (Matthew Collett)
Date: Sun, 19 Oct 2003 23:48:04 +0000 (UTC)
Raw View
In article <bmorqk$jn4$1@glue.ucr.edu>, thp@cs.ucr.edu wrote:

>   struct Widget {
>     int& r;
>     Widget(int* p): r(*p) {}
                    ^ Missing ':' inserted
>   };
>
>   int i, j;
>   Widget a(&i);
>   Widget b(&j);
>
>   // Now "a.r" refers to i.  (Witness that &a.r == &i.)
>
>   a=b;
>
>   // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)

My compiler says [sic]:

Error   : using implicit copy assigment for class with const or
reference member ('Widget')

Which apart from the typo is pretty much what I expected.  You can't
reseat references, and assignment doesn't provide a magic method of
doing so.

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken.          -- Aristotle

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pasa@lib.hu ("Balog Pal")
Date: Sun, 19 Oct 2003 23:48:15 +0000 (UTC)
Raw View
<thp@cs.ucr.edu> wrote in message news:bmorqk$jn4$1@glue.ucr.edu...

>   struct Widget {
>     int& r;
>     Widget(int* p) r(*p) {}
>   };
>
>   int i, j;
>   Widget a(&i);
>   Widget b(&j);
>
>   // Now "a.r" refers to i.  (Witness that &a.r == &i.)
>
>   a=b;
>
>   // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)

Did you try your example? As my compiler just rejected the code.

>   a=b;
error C2582: 'Widget' : 'operator =' function is unavailable

certainly.

> Here we have an allegedly stateless entity, namely a's reference
> member, changing its behavior in exactly the way one would expect if
> it had state, i.e., it now behaves just like the corresponding member
> of b.

Well, try and create an op= avoiding UB, then we can examine if what you
write actually happens or not.

> When struct members of other types do that, we describe/explain
> the phenomenon as a "change of state".

True. If you change r to int *, the compiler will be glad to make op= and it
will change state indeed.    Cool example to show you wrong IMHO.

> Anyone accepts that references are stateless should be astonished.  By
> contrast, those who expect references to behave like implicitly
> dereferenced pointers should expect exactly the above behavior.

Khm, can we conclude then, that the later reasoning is only good to create
confusion and just waiting to fall on face?

Paul


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Mon, 20 Oct 2003 16:15:29 +0000 (UTC)
Raw View
pasa@lib.hu ("Balog Pal") wrote in message
news:<3f93158b@andromeda.datanet.hu>...
> <thp@cs.ucr.edu> wrote in message news:bmorqk$jn4$1@glue.ucr.edu...

> >   struct Widget {
> >     int& r;
> >     Widget(int* p) r(*p) {}
> >   };

> >   int i, j;
> >   Widget a(&i);
> >   Widget b(&j);

> >   // Now "a.r" refers to i.  (Witness that &a.r == &i.)

> >   a=b;

> >   // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)

> Did you try your example? As my compiler just rejected the code.

> >   a=b;
> error C2582: 'Widget' : 'operator =' function is unavailable

> certainly.

> > Here we have an allegedly stateless entity, namely a's reference
> > member, changing its behavior in exactly the way one would expect if
> > it had state, i.e., it now behaves just like the corresponding
> > member of b.

> Well, try and create an op= avoiding UB, then we can examine if what
> you write actually happens or not.

You mean something like:

    Widget&
    Widget::operator=( Widget const& other )
    {
        if ( this != &other ) {
            this->~Widget() ;
            new ( this ) Widget( other ) ;
        }
        return *this ;

While exceedingly dangerous, there's no undefined behavior here.

On the other hand, the state of the reference hasn't changed; one
reference ceased to exist, and another was created.

But the arguments seem more theoretic than anything else.  Formally the
state of a reference cannot change, any more than the state of a
constant object can change.  Never the less, we speak of the state of a
constant object.  The "statelessness" of a reference, if such exists, is
a combination of many things, but mainly the fact that, even in the
cases where the reference actually does occupy memory, there is no way
to access that memory.

--
James Kanze           GABI Software        mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Mon, 20 Oct 2003 16:39:58 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bmorqk$jn4$1@glue.ucr.edu>...
> Francis Glassborow <francis@robinton.demon.co.uk> wrote:
...
> +>In what way do distinct instances of Widget differ if r has no state,
> +>no location, and no space that are associated with the instance of
> +>Widget, not with their referents?
...
> So, how do Oxford graduates explain sudden shifts in behavior by
> stateless entities?  Consider:
>
>   struct Widget {
>     int& r;
>     Widget(int* p) r(*p) {}
>   };
>
>   int i, j;
>   Widget a(&i);
>   Widget b(&j);
>
>   // Now "a.r" refers to i.  (Witness that &a.r == &i.)
>
>   a=b;
>
>   // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)

'r' does have state, but that code doesn't properly demonstrate that
fact. Section 12.8p12:

"... A program is ill-formed if the class for which a copy assignment
constructor is implicitly defined has:

-- a nonstatic data member of const type, or
-- a nonstatic data member of reference type, or
-- a nonstatic data member of class type (or array thereof) with an
inaccessible copy assignment operator.
-- a base class with an inaccessible copy assignment operator.
"

You have to use placement new to reseat a reference.

    a.~Widget(); // Needed to match up ctor calls with dtor calls.
    new(&a) Widget(&j);


This is definitely NOT a recommended programming technique.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Mon, 20 Oct 2003 22:38:57 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote:
+ Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ + In article <bmlco0$kei$1@glue.ucr.edu>, thp@cs.ucr.edu writes
+ +>
+ +>class Widget {
+ +>  int& r;
+ +>  Widget() r(*new int) {}
+ +>};
+ +>
+ +>In what way do distinct instances of Widget differ if r has no state,
+ +>no location, and no space that are associated with the instance of
+ +>Widget, not with their referents?
+ +>
+ +>Tom Payne
+ +>
+ + We can argue philosophy for ever and a day. Being an Oxford University
+ + graduate means that I have been exposed to such debates since my late
+ + adolescent years.

Please ignore/forgive the following craziness on my part.  I unsuccessfully
requested that it be withdrawn.

\begin{nonsense}

+ So, how do Oxford graduates explain sudden shifts in behavior by
+ stateless entities?  Consider:
+
+  struct Widget {
+    int& r;
+    Widget(int* p) r(*p) {}
+  };
+
+  int i, j;
+  Widget a(&i);
+  Widget b(&j);
+
+  // Now "a.r" refers to i.  (Witness that &a.r == &i.)
+
+  a=b;
+
+  // Suddenly "a.r" refers to j.  (Witness that &a.r == &j.)
+
+ Here we have an allegedly stateless entity, namely a's reference
+ member, changing its behavior in exactly the way one would expect if
+ it had state, i.e., it now behaves just like the corresponding member
+ of b.  When struct members of other types do that, we describe/explain
+ the phenomenon as a "change of state".
+
+ Anyone accepts that references are stateless should be astonished.  By
+ contrast, those who expect references to behave like implicitly
+ dereferenced pointers should expect exactly the above behavior.

\end{nonsense}

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Mon, 20 Oct 2003 22:39:17 +0000 (UTC)
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ In article <bmfrjj$5oo$2@glue.ucr.edu>, thp@cs.ucr.edu writes
+>We are talking about behavior, not implementation.  So, by what
+>behavioral test do you determine that a reference never has location?
+
+ Turn that round, how do you determine that they do. I know of no way to
+ determine the location of a reference only ways to determine the
+ location of the object referred to.

I don't claim that they *are* objects --- only that they *behave* as
world certain hypothetical objects whenever their behavior is defined.

Unfortunately, the term "object" underwent a transformation during the
standardization of C++.  At the time of the ARM, it was described in
implementation terms: a segment of memory holding a value.  IIRC, in
the final standard that notion was drop in favor of a simple listing
of kinds of entities that standard means my the term "object".

The former use of "object" was current when the slogan "References
aren't objects" first gained currency.  It's easy enough to from first
principles that (except in infrequent cases where referents can be
determined at compile time) keeping track of which pointers point to
what requres memory as does keeping track of the values of other kinds
objects.

Tom

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 20 Oct 2003 23:56:20 +0000 (UTC)
Raw View
kanze@gabi-soft.fr writes:

> You mean something like:
>
>     Widget&
>     Widget::operator=( Widget const& other )
>     {
>         if ( this != &other ) {
>             this->~Widget() ;
>             new ( this ) Widget( other ) ;
>         }
>         return *this ;
>
> While exceedingly dangerous, there's no undefined behavior here.

It depends if the new can throw.  In that case, unless *this is never
to be destroyed or otherwise used again, there's undefined behavior
somewhere down the pike.


--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Mon, 27 Oct 2003 01:43:32 +0000 (UTC)
Raw View
kanze@gabi-soft.fr wrote:
+ thp@cs.ucr.edu wrote in message news:<bn5eu3$3ve$1@glue.ucr.edu>...
+> kanze@gabi-soft.fr wrote:
+> > dave@boost-consulting.com (David Abrahams) wrote in message
+> > news:<usmlnsdp2.fsf@boost-consulting.com>...
+> >> kanze@gabi-soft.fr writes:
+
+> >> > You mean something like:
+
+> >> >     Widget&
+> >> >     Widget::operator=( Widget const& other )
+> >> >     {
+> >> >         if ( this != &other ) {
+> >> >             this->~Widget() ;
+> >> >             new ( this ) Widget( other ) ;
+> >> >         }
+> >> >         return *this ;
+
+> >> > While exceedingly dangerous, there's no undefined behavior here.
+
+> >> It depends if the new can throw.
+
+> > Or likely if someone derives from the class, or any one of a number
+> > of other horrible scenarios.
+
+> >>  In that case, unless *this is never to be destroyed or otherwise
+> >> used again, there's undefined behavior somewhere down the pike.
+
+> > I think Herb Sutter has a whole list of things which can go wrong with
+
+> Hmmmmm.  Either this construct conforms or it doesn't.  If it
+> conforms, I'd expect it not to engender undefined behavior.  But, I'm
+> probably missing something.
+
+ The construct in itself conforms.  But in real life, code doesn't live
+ in a vacuum.  There are too many things that other code can do which
+ will render it non-conforming.
+
+> > I'm not recommending this solution -- it was mentioned simply with
+> > regards to its relevence to reseating references; such an operator=
+> > will
+
+> At that point we are into a serious philosophical issue: either we
+> acknowledge that references are stateful or we must claim that one
+> reference ceases to exist and another appears in its place.  Sort of
+> like the doctrine of transsubstantiation.
+
+ Sort of, but not really different than when the local variables of
+ successively called functions occupy the same address on the stack.  Or,
+ much closer to home, in an implementation of a discriminate union.  (In
+ fact, I imagine that the assignment operators in a discriminate union
+ probably would do something very similar to this.  In this case, there
+ isn't really any other solution.)

Thanks.  IIUC:

   Widget w1, w2;
   Widget* p = &w1;
   w1 = w2;   // p now dangles, since its w1 has now been destructed.
   *p;        // Dereferencing of a dangling pointer.

Right?

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Mon, 27 Oct 2003 18:02:30 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
>
> Thanks.  IIUC:
>
>    Widget w1, w2;
>    Widget* p = &w1;
>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
>    *p;        // Dereferencing of a dangling pointer.
>
> Right?
>
> Tom Payne
>

Why would p be a dangling pointer after the assignment of w2 to w1?
w1 is still a valid Widget, only its value has been updated to be the
same as w2.  So p is still a valid pointer, but the value of the
object to which it points has been modified.  Nothing else has
happened, so the dereference of p is still valid.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: belvis@pacbell.net (Bob Bell)
Date: Mon, 27 Oct 2003 22:33:50 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
> Thanks.  IIUC:
>
>    Widget w1, w2;
>    Widget* p = &w1;
>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
>    *p;        // Dereferencing of a dangling pointer.
>
> Right?

It's not a dangling pointer; p still points to w1. However, w1 has
changed identity. The Widget that was originally constructed in w1 was
destroyed and a new one was constructed at the same address. Because
the address of the Widget didn't change, p is still OK.

Bob

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Tue, 28 Oct 2003 10:00:15 +0000 (UTC)
Raw View
Randy Maddox <rmaddox@isicns.com> wrote:
+ thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
+>
+> Thanks.  IIUC:
+>
+>    Widget w1, w2;
+>    Widget* p = &w1;
+>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
+>    *p;        // Dereferencing of a dangling pointer.
+>
+> Right?
+>
+> Tom Payne
+>
+
+ Why would p be a dangling pointer after the assignment of w2 to w1?
+ w1 is still a valid Widget, only its value has been updated to be the
+ same as w2.  So p is still a valid pointer, but the value of the
+ object to which it points has been modified.  Nothing else has
+ happened, so the dereference of p is still valid.

The Widget that p pointed to has been destroyed, i.e., its destructor,
~Widget(), has been executed.  As of that return from the return from
that invocation of ~Widget(), p dangled.  IIUC, it continues to
dangle, in spite of the subsequent construction of another Widget at
the site of p's former referent.  But, I can't cite chapter and verse
to back that up.

Tom Payne


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Tue, 28 Oct 2003 21:10:44 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bnkjgn$7vq$1@glue.ucr.edu>...
> Randy Maddox <rmaddox@isicns.com> wrote:
> + thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
> +>
> +> Thanks.  IIUC:
> +>
> +>    Widget w1, w2;
> +>    Widget* p = &w1;
> +>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
> +>    *p;        // Dereferencing of a dangling pointer.
> +>
> +> Right?
> +>
> +> Tom Payne
> +>
> +
> + Why would p be a dangling pointer after the assignment of w2 to w1?
> + w1 is still a valid Widget, only its value has been updated to be the
> + same as w2.  So p is still a valid pointer, but the value of the
> + object to which it points has been modified.  Nothing else has
> + happened, so the dereference of p is still valid.
>
> The Widget that p pointed to has been destroyed, i.e., its destructor,
> ~Widget(), has been executed.  As of that return from the return from
> that invocation of ~Widget(), p dangled.  IIUC, it continues to
> dangle, in spite of the subsequent construction of another Widget at
> the site of p's former referent.  But, I can't cite chapter and verse
> to back that up.

See section 3.8p7. It specifies quite clearly the conditions
controlling whether or not a pointer or reference to an object that
has been destroyed can be safely used to refer to a new object created
at the same storage location. Those conditions are all being met in
this case.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Tue, 28 Oct 2003 23:02:48 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bnkjgn$7vq$1@glue.ucr.edu>...
> Randy Maddox <rmaddox@isicns.com> wrote:
> + thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
> +>
> +> Thanks.  IIUC:
> +>
> +>    Widget w1, w2;
> +>    Widget* p = &w1;
> +>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
> +>    *p;        // Dereferencing of a dangling pointer.
> +>
> +> Right?
> +>
> +> Tom Payne
> +>
> +
> + Why would p be a dangling pointer after the assignment of w2 to w1?
> + w1 is still a valid Widget, only its value has been updated to be the
> + same as w2.  So p is still a valid pointer, but the value of the
> + object to which it points has been modified.  Nothing else has
> + happened, so the dereference of p is still valid.
>
> The Widget that p pointed to has been destroyed, i.e., its destructor,
> ~Widget(), has been executed.  As of that return from the return from
> that invocation of ~Widget(), p dangled.  IIUC, it continues to
> dangle, in spite of the subsequent construction of another Widget at
> the site of p's former referent.  But, I can't cite chapter and verse
> to back that up.
>
> Tom Payne
>

In the specific case of the Widget class used in this thread I believe
you may be correct that the assignment operator does destroy the
Widget being assigned to and then copy construct a new Widget in the
same location.  In general, however, it is not the case that
assignment involves destruction.  And even if this specific case does,
that makes no difference.  Prior to the assignment p pointed to a
Widget object.  After the assignment p still points to a valid Widget
object.  During the assignment, if the Widget assignment operator does
indeed destroy and reconstruct, there is a time after that destruction
and prior to reconstruction when p points to uninitialized storage,
but that is only for a fleeting instant.  After that instant, all is
good again.

I believe the reason you are not able to cite chapter and verse to the
contrary is that such does not exist.  If it were not for the
reconstruction in the same location, then p would be a pointer to
uninitialized storage, which is still not quite the same as a dangling
pointer that points to storage that has been freed.  That is quite a
different situation from what we have here.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Wed, 29 Oct 2003 23:46:26 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
> kanze@gabi-soft.fr wrote:

> > Sort of, but not really different than when the local variables of
> > successively called functions occupy the same address on the stack.
> > Or, much closer to home, in an implementation of a discriminate
> > union.  (In fact, I imagine that the assignment operators in a
> > discriminate union probably would do something very similar to this.
> > In this case, there isn't really any other solution.)

> Thanks.  IIUC:

>    Widget w1, w2;
>    Widget* p = &w1;
>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
>    *p;        // Dereferencing of a dangling pointer.

> Right?

Sort of.  I think it is a little bit more complex than that; the address
of w1 doesn't change, so p rebecomes valid after assignment.  Problems
creep in if 1) the copy constructor throws -- in that case, p dangles,
and even calling w1's destructor causes undefined behavoir, 2) the copy
constructor accesses through p; during assignment, p does dangle for a
little bit, or 3) someone tries to derive from Widget.

--
James Kanze           GABI Software        mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Wed, 29 Oct 2003 23:48:59 +0000 (UTC)
Raw View
James Kuyper <kuyper@wizard.net> wrote:
+ thp@cs.ucr.edu wrote in message news:<bnkjgn$7vq$1@glue.ucr.edu>...
+> Randy Maddox <rmaddox@isicns.com> wrote:
+> + thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
+> +>
+> +> Thanks.  IIUC:
+> +>
+> +>    Widget w1, w2;
+> +>    Widget* p = &w1;
+> +>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
+> +>    *p;        // Dereferencing of a dangling pointer.
+> +>
+> +> Right?
+> +>
+> +> Tom Payne
+> +>
+> +
+> + Why would p be a dangling pointer after the assignment of w2 to w1?
+> + w1 is still a valid Widget, only its value has been updated to be the
+> + same as w2.  So p is still a valid pointer, but the value of the
+> + object to which it points has been modified.  Nothing else has
+> + happened, so the dereference of p is still valid.
+>
+> The Widget that p pointed to has been destroyed, i.e., its destructor,
+> ~Widget(), has been executed.  As of that return from the return from
+> that invocation of ~Widget(), p dangled.  IIUC, it continues to
+> dangle, in spite of the subsequent construction of another Widget at
+> the site of p's former referent.  But, I can't cite chapter and verse
+> to back that up.
+
+ See section 3.8p7. It specifies quite clearly the conditions
+ controlling whether or not a pointer or reference to an object that
+ has been destroyed can be safely used to refer to a new object created
+ at the same storage location. Those conditions are all being met in
+ this case.

Thanks -- I stand corrected.  But then, I'm curious about the
purported dangers in the case at hand, e.g., why it is like writing a
union via one member and reading it via another and/or reading stack
garbage via uninitialized automatic variables.

There is also the somewhat philosophical question of whether the
evaluation of such an assignment expression "w1=w2":
  1) reseats references to w1 to refer to w2's new clone.
  2) changes the state of their referents to resemble w2.

Finally, consider:

  class Widget {
  public:
    int& r;
    Widget() r(*new int) {}
  } w1, w2;

After evaluation of "w1=w2", is it guaranteed that "&w1.r == &w2.r"?
If so, it would seem that we have a conforming mechanism for changing
the states of w1.r.

I think that was James' original point, but I got confused by the
purported "dangers", which I still don't understand.  I followed the
part where "w1=w2" has defined behavior but taking its behavior at
face value may lead to undefined behavior.  My conjecture that such
undefined behavior we follow from references to w1 suddenly dangling
has been refuted.  So, how does unusual defined-or-undefined behavior
enter here?

Thanks again,
Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ahp6@email.byu.edu ("Adam H. Peterson")
Date: Thu, 30 Oct 2003 03:05:52 +0000 (UTC)
Raw View
> Finally, consider:
>
>   class Widget {
>   public:
>     int& r;
>     Widget() r(*new int) {}
>   } w1, w2;
>
> After evaluation of "w1=w2", is it guaranteed that "&w1.r == &w2.r"?
> If so, it would seem that we have a conforming mechanism for changing
> the states of w1.r.

Again, here "w1=w2" is illegal because you don't provide an assignment
operator and the compiler is forbidden from providing it for you.

Adam Peterson

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 30 Oct 2003 08:47:05 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bnno5s$3ui$1@glue.ucr.edu>...
> James Kuyper <kuyper@wizard.net> wrote:
> + thp@cs.ucr.edu wrote in message news:<bnkjgn$7vq$1@glue.ucr.edu>...
> +> Randy Maddox <rmaddox@isicns.com> wrote:
> +> + thp@cs.ucr.edu wrote in message news:<bndt91$d1g$1@glue.ucr.edu>...
> +> +>
> +> +> Thanks.  IIUC:
> +> +>
> +> +>    Widget w1, w2;
> +> +>    Widget* p = &w1;
> +> +>    w1 = w2;   // p now dangles, since its w1 has now been destructed.
> +> +>    *p;        // Dereferencing of a dangling pointer.
> +> +>
> +> +> Right?
> +> +>
> +> +> Tom Payne
> +> +>
> +> +
> +> + Why would p be a dangling pointer after the assignment of w2 to w1?
> +> + w1 is still a valid Widget, only its value has been updated to be the
> +> + same as w2.  So p is still a valid pointer, but the value of the
> +> + object to which it points has been modified.  Nothing else has
> +> + happened, so the dereference of p is still valid.
> +>
> +> The Widget that p pointed to has been destroyed, i.e., its destructor,
> +> ~Widget(), has been executed.  As of that return from the return from
> +> that invocation of ~Widget(), p dangled.  IIUC, it continues to
> +> dangle, in spite of the subsequent construction of another Widget at
> +> the site of p's former referent.  But, I can't cite chapter and verse
> +> to back that up.
> +
> + See section 3.8p7. It specifies quite clearly the conditions
> + controlling whether or not a pointer or reference to an object that
> + has been destroyed can be safely used to refer to a new object created
> + at the same storage location. Those conditions are all being met in
> + this case.
>
> Thanks -- I stand corrected.  But then, I'm curious about the
> purported dangers in the case at hand, e.g., why it is like writing a
> union via one member and reading it via another and/or reading stack
> garbage via uninitialized automatic variables.

Here's two:

void F()
{
   Widget w1, w2;

   try {
      w1 = w2;
   }
   catch (...) {
      // if we ever get here, we've got big trouble
      // because w1 has already been destroyed
   }
}

class Derived : public Widget { };

void G()
{
   Derived w1, w2;

   w1 = w2;  // whoops! the static type of w1 is Derived, but it's
             // actually been changed to Widget
}

> There is also the somewhat philosophical question of whether the
> evaluation of such an assignment expression "w1=w2":
>   1) reseats references to w1 to refer to w2's new clone.
>   2) changes the state of their referents to resemble w2.

You mean:

void F()
{
   Widget w1, w2;
   Widget& r1 = w1, r2 = w2;

   w1 = w2;

   // do something with r1 here.
}

Did r1 get "reseated" to refer to a different Widget? Good question. I
don't consider it reseating because the original w1 was destroyed and
a new Widget was constructed in its place.

I would guess that this is undefined behavior, based on the idea that
a reference is valid only as long as the underlying object survives,
but r1's underlying object's lifetime ended inside the copy assignment
operator. Then again, the citation of 3.8p7 given above may mean I'm
wrong here...

I'm not sure what your 2) comment means.

> Finally, consider:
>
>   class Widget {
>   public:
>     int& r;
>     Widget() r(*new int) {}
>   } w1, w2;
>
> After evaluation of "w1=w2", is it guaranteed that "&w1.r == &w2.r"?
> If so, it would seem that we have a conforming mechanism for changing
> the states of w1.r.

Not sure whether &w1.r == &w2.r would be true or not without seeing
the copy constructor. Even if it is true, it does not demonstrate
changing Widget::r because we're still talking about
destroying/creating, not modification.

> I think that was James' original point, but I got confused by the
> purported "dangers", which I still don't understand.  I followed the
> part where "w1=w2" has defined behavior but taking its behavior at
> face value may lead to undefined behavior.  My conjecture that such
> undefined behavior we follow from references to w1 suddenly dangling
> has been refuted.  So, how does unusual defined-or-undefined behavior
> enter here?

See above.

Bob

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Tue, 14 Oct 2003 21:05:19 +0000 (UTC)
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ In article <pan.2003.10.11.09.07.27.420248@knm.org.pl>, Marcin 'Qrczak'
+ Kowalczyk <qrczak@knm.org.pl> writes
+>Explanation of references in terms of pointers with some changed rules is
+>easy and unambiguous. I don't know any other explanation which is as short
+>and clear.
+
+ So how do you explain them to people who know nothing about pointers?

By first explaining pointers.  ;-)

+ That is a serious question, and the answer is more likely to describe
+ what a reference really is in C++ than by taking some short cut based on
+ looking under the hood and referring to a common implementation policy.

Who's looking under the hood.  The hypothsis is that (with the
exceptions already mentioned) the behavior of a program wouldn't
change if references were replaced by similarly initialized
automatically dereferenced pointers.  That statement says nothing
about what happens under the hood.

+ And as has already been pointed out, there is a fundamental difference
+ illustrated by the fact that you cannot have an array of references.

We differ on the concept of "fundamental".  The prohibition on arrarys
of references seems a somewhat arbitrary restriction, which may have
been imposed for sound software-engineering reasons.  Nevertheless, if
all such restrictions were taken into account, i.e., if someone said
that references are automatically dereferenced pointers such that ...,
where ... included all possible differences, I think you'd still
object.  Right?

+ The nearest simple definition that I can come up with is:
+
+ In C++ a reference is a statically typed name that must be bound to an
+ existing object with an appropriate type at the point of first use.

We've had this conversation before but let's try again: What's the
name associated with the reference returned by int& f(){return *new
int;}.  Before you say, whatever name you subsequently assign to it,
note that:

  - It's a reference before that assignment occurs.

  - Instead of an int, I could return an object of a user defined type
    and call a member function that would print out the first 1000
    digits of pi without ever assigning a name, e.g., "f().printPi();".
    The point is that I don't have to assign a name to it to do useful
    work.  (Or some that's not so useful.)

[...]
+ Any attempt to describe a reference as something else but with added
+ constraints is bound to fail because a C++ reference is nothing more nor
+ less than a C++ reference (and as we all know it is not a Java
+ reference)

Hmmmmm:

  "There's glory for you!"
  "I don't know what you mean by 'glory,' " Alice said.
  Humpty Dumpty smiled contemptuously. "Of course you don't --
  till I tell you.  I meant 'there's a nice knock-down argument for you!' "
  "But 'glory' doesn't mean 'a nice knock-down argument,' " Alice objected.
  "When I use a word," Humpty Dumpty said, in rather a scornful tone,
  "it means just what I choose it to mean -- neither more nor less."
  "The question is, " said Alice, "whether you can make words mean so many
  different things."
  "The question is," said Humpty Dumpty. "which is to be master -- that's
  all."                         [Through the Looking Glass, Lewis Carroll]


Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Tue, 14 Oct 2003 22:53:59 +0000 (UTC)
Raw View
In article <bmfrd5$5oo$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>+ So how do you explain them to people who know nothing about pointers?
>
>By first explaining pointers.  ;-)

A fairly pointless exercise when they only wanted to know about
references.

>
>+ That is a serious question, and the answer is more likely to describe
>+ what a reference really is in C++ than by taking some short cut based on
>+ looking under the hood and referring to a common implementation policy.
>
>Who's looking under the hood.  The hypothsis is that (with the
>exceptions already mentioned) the behavior of a program wouldn't
>change if references were replaced by similarly initialized
>automatically dereferenced pointers.  That statement says nothing
>about what happens under the hood.

Except that you would have defined away all the elements that actually
make up a pointer (like having a value, being storable etc.)

>
>
>+ And as has already been pointed out, there is a fundamental difference
>+ illustrated by the fact that you cannot have an array of references.
>
>We differ on the concept of "fundamental".  The prohibition on arrarys
>of references seems a somewhat arbitrary restriction,

Not at all. We could have had some other reference like entity such as
those used by Java but in C++ references are not objects and so cannot
be collected in arrays or in any other form of collection. Not being
able to have an array of references is a consequence of what a C++
reference is, not some arbitrary constraint.


> which may have
>been imposed for sound software-engineering reasons.  Nevertheless, if
>all such restrictions were taken into account, i.e., if someone said
>that references are automatically dereferenced pointers such that ...,
>where ... included all possible differences, I think you'd still
>object.  Right?

Yes, because that may be what a Java reference is but it isn't what a
C++ one is. For example I cannot have a reference to a reference
(exactly because a reference is not an object)

>
>+ The nearest simple definition that I can come up with is:
>+
>+ In C++ a reference is a statically typed name that must be bound to an
>+ existing object with an appropriate type at the point of first use.
>
>We've had this conversation before but let's try again: What's the
>name associated with the reference returned by int& f(){return *new
>int;}.  Before you say, whatever name you subsequently assign to it,
>note that:

Perhaps I am happier with unutterable names than you. Just because you
cannot say something's name does not mean that it does not have one.
>
>  - It's a reference before that assignment occurs.

Indeed but to say that it does not have a name is rather like saying
that an anonymous namespace does not have a name. It does, just one we
can never utter.

>
>  - Instead of an int, I could return an object of a user defined type
>    and call a member function that would print out the first 1000
>    digits of pi without ever assigning a name, e.g., "f().printPi();".
>    The point is that I don't have to assign a name to it to do useful
>    work.  (Or some that's not so useful.)

So?

--
Francis Glassborow      ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 15 Oct 2003 04:43:10 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bm8qkb$806$1@glue.ucr.edu>...
> Bob Bell <belvis@pacbell.net> wrote:
> + thp@cs.ucr.edu wrote in message news:<bm45nk$t5l$1@glue.ucr.edu>...
> +> Stroustrup accepts the automatically-dereferenced-pointer perspective
> +> as harmless:
> +>
> +>    The obvious implementation of a reference is as a constant pointer
> +>    that is dereferenced each time it is used.  It doesn't do much harm
> +>    thinking about references that way, as long as one remembers that a
> +>    reference isn't an object that can be manipulated the way a pointer
> +>    is: ... In some cases, the compiler can optimize away a reference
> +>    so that there no object representing that reference at run time.
> +>                               [The C++ Programming Language, page 98]
> +
> + The key phrase is "as long as one remembers that a reference isn't an
> + object that can be manipulated the way a pointer is". It strikes me
> + that proponents of the "references are really pointers" view may not
> + be keeping this in mind.
>
> But, similarly, automatically dereferenced pointers couldn't be
> manipulated the way other pointers are.  The reason is not that they
> wouldn't be pointers but rather because they would be automatically
> derefereced at all attempts to manipulate them.  So that "key phrase"
> has nothing to do with the question of whether or not automatically
> dereferenced pointers would behave the same way as references behave,
> which IMHO is the relevant issue.

The phrase "as long as one remembers that a reference isn't an object
that can be manipulated the way a pointer is" is precisely why you
can't have an array of references. If you forget that phrase, and
simply think of references as a special kind of pointer, you might
find it odd that you can't have arrays of references.

Bob

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 16 Oct 2003 02:56:56 +0000 (UTC)
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ In article <bmfrd5$5oo$1@glue.ucr.edu>, thp@cs.ucr.edu writes
+>+ So how do you explain them to people who know nothing about pointers?
+>
+>By first explaining pointers.  ;-)
+
+ A fairly pointless exercise when they only wanted to know about
+ references.

If they had no need to know about pointers, I'd describe references as
"object-valued objects", i.e., objects that hold bit-string
representations of other objects the way that int objects hold
bit-string representations for integers.

+>+ That is a serious question, and the answer is more likely to describe
+>+ what a reference really is in C++ than by taking some short cut based on
+>+ looking under the hood and referring to a common implementation policy.
+>
+>Who's looking under the hood.  The hypothsis is that (with the
+>exceptions already mentioned) the behavior of a program wouldn't
+>change if references were replaced by similarly initialized
+>automatically dereferenced pointers.  That statement says nothing
+>about what happens under the hood.
+
+ Except that you would have defined away all the elements that actually
+ make up a pointer (like having a value, being storable etc.)

I'm not defining away anything.  I'm simply saying that the
implictly-dereferenced-pointer perspective on references is not based
on matters of implementation, which is what I thought you meant by
"taking some short cut based on looking under the hood and referring
to a common implementation policy".

+>+ And as has already been pointed out, there is a fundamental difference
+>+ illustrated by the fact that you cannot have an array of references.
+>
+>We differ on the concept of "fundamental".  The prohibition on arrarys
+>of references seems a somewhat arbitrary restriction,
+
+ Not at all. We could have had some other reference like entity such as
+ those used by Java but in C++ references are not objects and so cannot
+ be collected in arrays or in any other form of collection. Not being
+ able to have an array of references is a consequence of what a C++
+ reference is, not some arbitrary constraint.

As I said, we differ on the notion of "fundamental".  Also on the
notion of "arbitrary".

But perhaps the differences on this matter go deeper.  For reasons
I've never understood, languages designers are referred to as
"creators".  The cover of my copy of of The C++ Programming Language
had on the on it: "Bjarne Stroustrup, The Creator of C++".  In fact,
he neither discovered nor created references.  (Nor has he claimed
to.)  The notion of "reference" had been around for a long before C++.
When he adopted/adapted it into C++, (per D&E 3.7) he did so to deal
with a specific problem.  And he placed a lot of restrictions on the
use of references because of misadventures he had with Algol68
references.  These restrictions are not a matter of substance (what is
a reference) but of style (how to use them safely).  When one puts a
safety device on a car or a bicycle, it doesn't become something else.
It simply becomes a slight variant of a well-known concept.

Another difficulty in these discussions is the use of the verb "to be"
and its variants.  (In the infamous words of a former president, "It
all depends on what the meaning of 'is' is.")  The best way to cut
through such Clintonian nonsense is to take an operational
(behavioral) approach: something is as something does.  Would a
program function the same way if one replaced all post-initialization
occurrences of references with dereferenced occurrences of similarly
initialized pointers?  AFAIK, the answer is "yes" with a couple of
easily handled caveats regarding initialization from rvalues and and
preventing objects from become POD.

+>which may have
+>been imposed for sound software-engineering reasons.  Nevertheless, if
+>all such restrictions were taken into account, i.e., if someone said
+>that references are automatically dereferenced pointers such that ...,
+>where ... included all possible differences, I think you'd still
+>object.  Right?
+
+ Yes, because that may be what a Java reference is but it isn't what a
+ C++ one is. For example I cannot have a reference to a reference
+ (exactly because a reference is not an object)

The metaphyisics is misleading.  You can't have a reference to a
referece because Stroustrup got bit by one when he programmed in
Algol68, so he ruled them out.

+>+ The nearest simple definition that I can come up with is:
+>+
+>+ In C++ a reference is a statically typed name that must be bound to an
+>+ existing object with an appropriate type at the point of first use.
+>
+>We've had this conversation before but let's try again: What's the
+>name associated with the reference returned by int& f(){return *new
+>int;}.  Before you say, whatever name you subsequently assign to it,
+>note that:
+
+ Perhaps I am happier with unutterable names than you. Just because you
+ cannot say something's name does not mean that it does not have one.
+>
+>  - It's a reference before that assignment occurs.
+
+ Indeed but to say that it does not have a name is rather like saying
+ that an anonymous namespace does not have a name. It does, just one we
+ can never utter.

Good grief!

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 16 Oct 2003 02:56:57 +0000 (UTC)
Raw View
Bob Bell <belvis@pacbell.net> wrote:
+ thp@cs.ucr.edu wrote in message news:<bm8qkb$806$1@glue.ucr.edu>...
+> Bob Bell <belvis@pacbell.net> wrote:
+> + thp@cs.ucr.edu wrote in message news:<bm45nk$t5l$1@glue.ucr.edu>...
+> +> Stroustrup accepts the automatically-dereferenced-pointer perspective
+> +> as harmless:
+> +>
+> +>    The obvious implementation of a reference is as a constant pointer
+> +>    that is dereferenced each time it is used.  It doesn't do much harm
+> +>    thinking about references that way, as long as one remembers that a
+> +>    reference isn't an object that can be manipulated the way a pointer
+> +>    is: ... In some cases, the compiler can optimize away a reference
+> +>    so that there no object representing that reference at run time.
+> +>                               [The C++ Programming Language, page 98]
+> +
+> + The key phrase is "as long as one remembers that a reference isn't an
+> + object that can be manipulated the way a pointer is". It strikes me
+> + that proponents of the "references are really pointers" view may not
+> + be keeping this in mind.
+>
+> But, similarly, automatically dereferenced pointers couldn't be
+> manipulated the way other pointers are.  The reason is not that they
+> wouldn't be pointers but rather because they would be automatically
+> derefereced at all attempts to manipulate them.  So that "key phrase"
+> has nothing to do with the question of whether or not automatically
+> dereferenced pointers would behave the same way as references behave,
+> which IMHO is the relevant issue.
+
+ The phrase "as long as one remembers that a reference isn't an object
+ that can be manipulated the way a pointer is" is precisely why you
+ can't have an array of references. If you forget that phrase, and
+ simply think of references as a special kind of pointer, you might
+ find it odd that you can't have arrays of references.

Not so much odd as confining.  The prohibition on arrays of references
is a stylistic restriction cannonized into the specifications of the
language for presumably sound safety reasons.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Thu, 16 Oct 2003 02:57:33 +0000 (UTC)
Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote in message news:<fCLSkIGD1Hj$EwPT@robinton.demon.co.uk>...
> In article <bmfrd5$5oo$1@glue.ucr.edu>, thp@cs.ucr.edu writes
...
> Perhaps I am happier with unutterable names than you. Just because you
> cannot say something's name does not mean that it does not have one.

When posting to a C++ newsgroup, it is wise to stick the
standard-defined meanings of those terms that are defined by the C++
standard. Section 3p3 defines that "a _name_ is a use of an identifier
(2.10) that denotes an entity or _label_ ...".

The only identifier in that expression was 'f', and it denotes a
function, not an int. The int whose reference is returned by that
function call is never denoted by any identifier. C++ doesn't have any
concept of "unnutterable names". The definition of an identifier
(2.10p1) requires that it contain at least one nondigit, so something
that is unutterable can't qualify.

> >  - It's a reference before that assignment occurs.
>
> Indeed but to say that it does not have a name is rather like saying
> that an anonymous namespace does not have a name. It does, just one we
> can never utter.

The official term for "anonymous namespace" in the standard is
"unnamed namespace". Section 7.3p2 defines namespaces as being
"optionally named". The standard defines anonymous namespaces as
acting as though they have a unique name in each translation unit; it
does not require that there actually be such a name, and I suspect
that most implementations don't use any kind of hidden name for that
purpose.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 16 Oct 2003 08:48:01 +0000 (UTC)
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ In article <bm8qkb$806$1@glue.ucr.edu>, thp@cs.ucr.edu writes
+>   In some cases, the compiler can optimize away a reference
+>   so that there no object representing that reference at run
+>   time.
+>
+>And that passage explicitly addresses matters of implementation.
+>IMHO, that passage is a red herring, since what it claimed about
+>references is equally true of pointers in similar cases.
+
+ Actually I think it is worse because I do not think that a reference is
+ ever 'an object'. A pointer variable is an object in its own right, it
+ has state and location (you can take its address). A reference variable
+ is not, it has no state and no location, it only has the state and
+ location of the object to which it refers (which may or may not have a
+ name of its own)

class Widget {
  int& r;
  Widget() r(*new int) {}
};

In what way do distinct instances of Widget differ if r has no state,
no location, and no space that are associated with the instance of
Widget, not with their referents?

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 16 Oct 2003 20:06:11 +0000 (UTC)
Raw View
In article <8b42afac.0310150705.747a5c30@posting.google.com>, James
Kuyper <kuyper@wizard.net> writes
>The official term for "anonymous namespace" in the standard is
>"unnamed namespace". Section 7.3p2 defines namespaces as being
>"optionally named". The standard defines anonymous namespaces as
>acting as though they have a unique name in each translation unit; it
>does not require that there actually be such a name, and I suspect
>that most implementations don't use any kind of hidden name for that
>purpose.

Except that as names declared in an unnamed namespace have external
linkage and can be used in templates (an exposed by use of export) they
actually do have to have some unique identifier that is used by the
implementation. The compiler may not need one but the linker almost
certainly does.

--
Francis Glassborow      ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Fri, 17 Oct 2003 04:08:06 +0000 (UTC)
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
+ In article <bm8qkb$806$1@glue.ucr.edu>, thp@cs.ucr.edu writes
+>   In some cases, the compiler can optimize away a reference
+>   so that there no object representing that reference at run
+>   time.
+>
+>And that passage explicitly addresses matters of implementation.
+>IMHO, that passage is a red herring, since what it claimed about
+>references is equally true of pointers in similar cases.
+
+ Actually I think it is worse because I do not think that a reference is
+ ever 'an object'. A pointer variable is an object in its own right, it
+ has state and location (you can take its address). A reference variable
+ is not, it has no state and no location, it only has the state and
+ location of the object to which it refers (which may or may not have a
+ name of its own)

We are talking about behavior, not implementation.  So, by what
behavioral test do you determine that a reference never has location?

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Fri, 17 Oct 2003 04:11:07 +0000 (UTC)
Raw View
In article <bmlco0$kei$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>
>class Widget {
>  int& r;
>  Widget() r(*new int) {}
>};
>
>In what way do distinct instances of Widget differ if r has no state,
>no location, and no space that are associated with the instance of
>Widget, not with their referents?
>
>Tom Payne
>
We can argue philosophy for ever and a day. Being an Oxford University
graduate means that I have been exposed to such debates since my late
adolescent years. They may be fun and mind sharpening but at the end of
the day they usually have no resolution.

I say r refers to an unnamed (or one with an unutterable name) instance
of an int. You want to say that r is the name of a dynamically provided
int. Your view leads you to talk about automatically dereferenced
pointers my view just uses the behaviour of the object referred to. You
have to explain why &r resolves to a pointer to the object and not to a
pointer to r. I have to explain that the addressof operator always
applies to objects and not a name used to designate an object.

I can explain references to someone who knows nothing about pointers,
you need to first explain a pointer (a topic that experience has shown
causes many humans great difficulty)

Explain references anyway you like but when it comes down to it they are
exactly what they are and many explanations in terms of something else
such as pointers leads to false expectations which then have to be
corrected.

For many people the description of a pass by reference or return by
reference as one that makes an already existing object available for use
elsewhere, whereas pass and return by value results in a copy is all
they need to know in order to write good, consistent high level code.


--
Francis Glassborow      ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Wed, 22 Oct 2003 01:47:54 +0000 (UTC)
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message
news:<usmlnsdp2.fsf@boost-consulting.com>...
> kanze@gabi-soft.fr writes:

> > You mean something like:

> >     Widget&
> >     Widget::operator=( Widget const& other )
> >     {
> >         if ( this != &other ) {
> >             this->~Widget() ;
> >             new ( this ) Widget( other ) ;
> >         }
> >         return *this ;

> > While exceedingly dangerous, there's no undefined behavior here.

> It depends if the new can throw.

Or likely if someone derives from the class, or any one of a number of
other horrible scenarios.

>  In that case, unless *this is never to be destroyed or otherwise used
> again, there's undefined behavior somewhere down the pike.

I think Herb Sutter has a whole list of things which can go wrong with
it:-).

I'm not recommending this solution -- it was mentioned simply with
regards to its relevence to reseating references; such an operator= will
"reseat" references in Widget.

--
James Kanze           GABI Software        mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Wed, 22 Oct 2003 01:48:00 +0000 (UTC)
Raw View
David Abrahams <dave@boost-consulting.com> wrote:
+ kanze@gabi-soft.fr writes:
+
+> You mean something like:
+>
+>     Widget&
+>     Widget::operator=( Widget const& other )
+>     {
+>         if ( this != &other ) {
+>             this->~Widget() ;
+>             new ( this ) Widget( other ) ;
+>         }
+>         return *this ;
+>
+> While exceedingly dangerous, there's no undefined behavior here.
+
+ It depends if the new can throw.  In that case, unless *this is never
+ to be destroyed or otherwise used again, there's undefined behavior
+ somewhere down the pike.

AFAIK, we're dealing with placement-new here, which AFAIK shouldn't
throw so long as it's placing on a valid location for the type.  By
definition *this is such a location.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Wed, 22 Oct 2003 15:50:29 +0000 (UTC)
Raw View
kanze@gabi-soft.fr wrote:
+ dave@boost-consulting.com (David Abrahams) wrote in message
+ news:<usmlnsdp2.fsf@boost-consulting.com>...
+> kanze@gabi-soft.fr writes:
+
+> > You mean something like:
+
+> >     Widget&
+> >     Widget::operator=( Widget const& other )
+> >     {
+> >         if ( this != &other ) {
+> >             this->~Widget() ;
+> >             new ( this ) Widget( other ) ;
+> >         }
+> >         return *this ;
+
+> > While exceedingly dangerous, there's no undefined behavior here.
+
+> It depends if the new can throw.
+
+ Or likely if someone derives from the class, or any one of a number of
+ other horrible scenarios.
+
+>  In that case, unless *this is never to be destroyed or otherwise used
+> again, there's undefined behavior somewhere down the pike.
+
+ I think Herb Sutter has a whole list of things which can go wrong with

Hmmmmm.  Either this construct conforms or it doesn't.  If it
conforms, I'd expect it not to engender undefined behavior.  But, I'm
probably missing something.

+
+ I'm not recommending this solution -- it was mentioned simply with
+ regards to its relevence to reseating references; such an operator= will

At that point we are into a serious philosophical issue: either we
acknowledge that references are stateful or we must claim that one
reference ceases to exist and another appears in its place.  Sort of
like the doctrine of transsubstantiation.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Wed, 22 Oct 2003 20:07:25 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bn2t81$cht$1@glue.ucr.edu>...
> David Abrahams <dave@boost-consulting.com> wrote:
> + kanze@gabi-soft.fr writes:
...
> + It depends if the new can throw.  In that case, unless *this is never
> + to be destroyed or otherwise used again, there's undefined behavior
> + somewhere down the pike.
>
> AFAIK, we're dealing with placement-new here, which AFAIK shouldn't
> throw so long as it's placing on a valid location for the type.  By
> definition *this is such a location.

A new-expression does two things: it calls the appropriate overload of
operator new() to allocate memory, and it calls the appropriate
constructor to initialize it. Placement new skips the first part, but
the second part can still throw.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pasa@lib.hu ("Balog Pal")
Date: Wed, 22 Oct 2003 23:42:32 +0000 (UTC)
Raw View
<thp@cs.ucr.edu> wrote in message news:bn5eu3$3ve$1@glue.ucr.edu...

> Hmmmmm.  Either this construct conforms or it doesn't.  If it
> conforms, I'd expect it not to engender undefined behavior.  But, I'm
> probably missing something.

Something having defined behavior does not mean that behavior makes sense in
the program too.   Also, having defined behavior within the function may
pretty well lead to undefined behavior elsewhere.  A simplistic ecample of
that is calling delete on a pointer, then jusing that same pointer later
somewhere. delete's behavior is efined, but if the code later does not
expect someone deleted what belong so the pointer, it falls on face.

that explicit dtor, then placement new kills and reconstructs the object,
anyone down the path should better be aware of that happened, of face
potential problems.
One easy example of that is when you actually had a derived object passed --
that as killed, and some base object created in its place.

> At that point we are into a serious philosophical issue: either we
> acknowledge that references are stateful or we must claim that one
> reference ceases to exist and another appears in its place.

Cerainly the later thing happens. The whole object ceases to exist there,
and a new one gets created. just like

int arr[10] = {0};
for(int i=0;i<10;++i)
{
 int & item = arr[i];
 ...
}

here item looks like changing state, while in fact it is a new reference
every time in the iteration.   Hope it's no more surprising than if we had a
string or anything else as item.

Paul




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 23 Oct 2003 06:01:55 +0000 (UTC)
Raw View
James Kuyper <kuyper@wizard.net> wrote:
+ thp@cs.ucr.edu wrote in message news:<bn2t81$cht$1@glue.ucr.edu>...
+> David Abrahams <dave@boost-consulting.com> wrote:
+> + kanze@gabi-soft.fr writes:
+ ...
+> + It depends if the new can throw.  In that case, unless *this is never
+> + to be destroyed or otherwise used again, there's undefined behavior
+> + somewhere down the pike.
+>
+> AFAIK, we're dealing with placement-new here, which AFAIK shouldn't
+> throw so long as it's placing on a valid location for the type.  By
+> definition *this is such a location.
+
+ A new-expression does two things: it calls the appropriate overload of
+ operator new() to allocate memory, and it calls the appropriate
+ constructor to initialize it. Placement new skips the first part, but
+ the second part can still throw.

Agreed, but I don't see how it could throw in the case at hand --- it
seems to have been given nothing to throw about.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ahp6@email.byu.edu ("Adam H. Peterson")
Date: Thu, 23 Oct 2003 06:14:45 +0000 (UTC)
Raw View
> AFAIK, we're dealing with placement-new here, which AFAIK shouldn't
> throw so long as it's placing on a valid location for the type.  By
> definition *this is such a location.


Placement new invokes constructors, and one of the motivations for
exceptions in the first place was to signal the failure of a
construction, so I think that in general it is not at all unlikely for
placement new to throw.

OTOH, I see nothing in the construction process of the Widget given as
example in this branch of the thread that would cause it to throw.

Adam Peterson

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 23 Oct 2003 06:14:53 +0000 (UTC)
Raw View
thp@cs.ucr.edu writes:

| David Abrahams <dave@boost-consulting.com> wrote:
| + kanze@gabi-soft.fr writes:
| +
| +> You mean something like:
| +>
| +>     Widget&
| +>     Widget::operator=( Widget const& other )
| +>     {
| +>         if ( this != &other ) {
| +>             this->~Widget() ;
| +>             new ( this ) Widget( other ) ;
| +>         }
| +>         return *this ;
| +>
| +> While exceedingly dangerous, there's no undefined behavior here.
| +
| + It depends if the new can throw.  In that case, unless *this is never
| + to be destroyed or otherwise used again, there's undefined behavior
| + somewhere down the pike.
|
| AFAIK, we're dealing with placement-new here, which AFAIK shouldn't
| throw so long as it's placing on a valid location for the type.  By
| definition *this is such a location.

I think Dave was not talking of the storage allocator operator new(),
but of the the implied constructor call.

--
                                                       Gabriel Dos Reis
                                           gdr@integrable-solutions.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Thu, 23 Oct 2003 06:15:52 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bn2t81$cht$1@glue.ucr.edu>...
> David Abrahams <dave@boost-consulting.com> wrote:
> + kanze@gabi-soft.fr writes:

> +> You mean something like:

> +>     Widget&
> +>     Widget::operator=( Widget const& other )
> +>     {
> +>         if ( this != &other ) {
> +>             this->~Widget() ;
> +>             new ( this ) Widget( other ) ;
> +>         }
> +>         return *this ;

> +> While exceedingly dangerous, there's no undefined behavior here.

> + It depends if the new can throw.  In that case, unless *this is never
> + to be destroyed or otherwise used again, there's undefined behavior
> + somewhere down the pike.

> AFAIK, we're dealing with placement-new here, which AFAIK shouldn't
> throw so long as it's placing on a valid location for the type.  By
> definition *this is such a location.

We're also dealing with a copy constructor, which formally can do
anything the user wants, including throwing all sorts of exceptions.
Realistically, I think that any class which supports deep copy will have
a copy constructor which can throw std::bad_alloc.

If the copy constructor throws, the object isn't constructed, and trying
to use it, or calling its destructor later, are undefined behavior.

--
James Kanze           GABI Software        mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Thu, 23 Oct 2003 20:26:30 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bn5eu3$3ve$1@glue.ucr.edu>...
> kanze@gabi-soft.fr wrote:
> + dave@boost-consulting.com (David Abrahams) wrote in message
> + news:<usmlnsdp2.fsf@boost-consulting.com>...
> +> kanze@gabi-soft.fr writes:
> +
> +> > You mean something like:
> +
> +> >     Widget&
> +> >     Widget::operator=( Widget const& other )
> +> >     {
> +> >         if ( this != &other ) {
> +> >             this->~Widget() ;
> +> >             new ( this ) Widget( other ) ;
> +> >         }
> +> >         return *this ;
> +
> +> > While exceedingly dangerous, there's no undefined behavior here.
> +
> +> It depends if the new can throw.
> +
> + Or likely if someone derives from the class, or any one of a number of
> + other horrible scenarios.
> +
> +>  In that case, unless *this is never to be destroyed or otherwise used
> +> again, there's undefined behavior somewhere down the pike.
> +
> + I think Herb Sutter has a whole list of things which can go wrong with
>
> Hmmmmm.  Either this construct conforms or it doesn't.  If it
> conforms, I'd expect it not to engender undefined behavior.  But, I'm
> probably missing something.

Whether or not it has defined behavior depends upon the behavior of the constructor.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: Thu, 23 Oct 2003 21:57:55 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bn5eu3$3ve$1@glue.ucr.edu>...
> kanze@gabi-soft.fr wrote:
> > dave@boost-consulting.com (David Abrahams) wrote in message
> > news:<usmlnsdp2.fsf@boost-consulting.com>...
> >> kanze@gabi-soft.fr writes:

> >> > You mean something like:

> >> >     Widget&
> >> >     Widget::operator=( Widget const& other )
> >> >     {
> >> >         if ( this != &other ) {
> >> >             this->~Widget() ;
> >> >             new ( this ) Widget( other ) ;
> >> >         }
> >> >         return *this ;

> >> > While exceedingly dangerous, there's no undefined behavior here.

> >> It depends if the new can throw.

> > Or likely if someone derives from the class, or any one of a number
> > of other horrible scenarios.

> >>  In that case, unless *this is never to be destroyed or otherwise
> >> used again, there's undefined behavior somewhere down the pike.

> > I think Herb Sutter has a whole list of things which can go wrong with

> Hmmmmm.  Either this construct conforms or it doesn't.  If it
> conforms, I'd expect it not to engender undefined behavior.  But, I'm
> probably missing something.

The construct in itself conforms.  But in real life, code doesn't live
in a vacuum.  There are too many things that other code can do which
will render it non-conforming.

> > I'm not recommending this solution -- it was mentioned simply with
> > regards to its relevence to reseating references; such an operator=
> > will

> At that point we are into a serious philosophical issue: either we
> acknowledge that references are stateful or we must claim that one
> reference ceases to exist and another appears in its place.  Sort of
> like the doctrine of transsubstantiation.

Sort of, but not really different than when the local variables of
successively called functions occupy the same address on the stack.  Or,
much closer to home, in an implementation of a discriminate union.  (In
fact, I imagine that the assignment operators in a discriminate union
probably would do something very similar to this.  In this case, there
isn't really any other solution.)

--
James Kanze           GABI Software        mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/     http://www.gabi-soft.fr
                    Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pasa@lib.hu ("Balog Pal")
Date: Wed, 8 Oct 2003 23:17:40 +0000 (UTC)
Raw View
.09.169398@knm.org.pl>
Subject: Re: Fancy pointers that behave like Java-style reference?
Date: Wed, 8 Oct 2003 22:54:19 +0100
Lines: 73
Organization: LiB
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.50.4922.1500
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4925.2800
Path: monor-216.dialin.datanet.hu
NNTP-Posting-Host: monor-216.dialin.datanet.hu
Message-ID: <3f847fe2@andromeda.datanet.hu>
X-Trace: 8 Oct 2003 23:21:38 +0200, monor-216.dialin.datanet.hu

""Marcin 'Qrczak' Kowalczyk"" <qrczak@knm.org.pl> wrote in message
news:pan.2003.10.08.06.47.09.169398@knm.org.pl...

> > r is not a "pointer to variable x that is handily dereferened" but
simply
> > equivalent with x.
>
> This is a popular myth.

Is it?

> Well, in this case they are equivalent because the
> initialization expression of the reference is so simple that it's easy to
> infer at compile time the pointed to variable, but it's a wrong way to
> think about references because it doesn't work in the general case.

It seems to me you're talking on implementation level where I was talking on
conceptual level.

> OTOH  the automatically dereferenced pointer view works always.

That clearly is an implementatoin view. Whoever wants to think in
implementation terms is welcome to do that, though IMHO it's more productive
for a programmer to rgarp the concept, and leave the implementation details
blackboxed.    At least until he must face them for some reason.

> Using your view some people think that with
>    int &r = a[i];
> accessing r will evaluate a[i] each time.

hmm, that way of thinking didn;t occour to me even as one possible way of
thinking. Really. I try to fit it into my terms, and fail.   a[i] denotes an
integer object (one without its own name), r binds a name to that very
integer.  The expression is evaluated only to denote the object.  C++ never
carries ecpressions, just results of them, why would one think differently
here?

> You can't say that r is another
> name for a[i]; you must say that it's another name for the object which
> a[i] referred to at that point of time

Certainly.   When I say int a = b * c; a will have the result, no matter
what happens to b or c or * ever after.

> in other words - it's an automatically dereferenced pointer to that
object.

And in yet other words just having int i; you could think of it as an
automatically dereferenced pointer to an int.   But I doubt many people
actually think that way.

And going back to the original example -- the compiler can pretty well
create that int in register, say SI, and have ri just refer to that same
register. No pointrs even on assy level.  If the target processor have many
registers even your array example may be coded that way or anything else --
from the language user perspective that should be transparent.

> > Certainly in some situations the compiler must communicate it to a point
far
> > away -- and having no magic way it will likely pass the address of x,
that
> > is really similar to the use of a const pointer.
>
> I would say differently. Certainly in some situations the compiler doesn't
> have to communicate the address which is known statically, and as an
> optimization in these cases it can omit the physical creation of the
> reference.

Optimisation is even more implementation bound term.

Paul


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk")
Date: Thu, 9 Oct 2003 15:26:36 +0000 (UTC)
Raw View
On Wed, 08 Oct 2003 23:17:40 +0000, Balog Pal wrote:

> It seems to me you're talking on implementation level where I was talking on
> conceptual level.

I'm talking about both. The possible "naive implementation" (without
optimizations) is often a useful model to have in mind in order to
understand C++ features.

>> Using your view some people think that with
>>    int &r = a[i];
>> accessing r will evaluate a[i] each time.
>
> hmm, that way of thinking didn;t occour to me even as one possible way of
> thinking.

Questions whether a[i] is evaluated each time have appeared on
pl.comp.lang.c (which is a group for both C and C++).

Another example:
   int *p = p1;
   int &r = *p;
   p = p2; // Does r change too? You told it's an alias for *p! :-)

> And in yet other words just having int i; you could think of it as an
> automatically dereferenced pointer to an int.   But I doubt many people
> actually think that way.

Indeed, because it's always known statically what it would point to, so
you can always talk about the pointed to object directly. For references
it is generally not known what they point to, except in useless cases used
in examples - a reference which points to a named variable is indeed
equivalent with that variable and that's why nobody makes such references.
Your "some situations the compiler must communicate it to a point far away"
cover 99% of cases. References found in real life require storage, so
it's strange to begin explaining them with unnatural cases which don't
and set other cases as special.

The reference is a fancy kind of pointer with * put implicitly before it
and with some changed rules (it's const, there are no null references,
and a reference to a const type can be bound to a temporary - did I miss
some?). What's wrong with this view? It's easy to understand and correct.
Other explanations resort to magic ("the compiler somehow communicates")
which doesn't provide a clue on what is stored at which place.

--
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Thu, 9 Oct 2003 17:29:55 +0000 (UTC)
Raw View
"Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl> wrote:
+ On Wed, 08 Oct 2003 23:17:40 +0000, Balog Pal wrote:
[...]
+> And in yet other words just having int i; you could think of it as an
+> automatically dereferenced pointer to an int.   But I doubt many people
+> actually think that way.
+
+ Indeed, because it's always known statically what it would point to, so
+ you can always talk about the pointed to object directly. For references
+ it is generally not known what they point to, except in useless cases used
+ in examples - a reference which points to a named variable is indeed
+ equivalent with that variable and that's why nobody makes such references.
+ Your "some situations the compiler must communicate it to a point far away"
+ cover 99% of cases. References found in real life require storage, so
+ it's strange to begin explaining them with unnatural cases which don't
+ and set other cases as special.
+
+ The reference is a fancy kind of pointer with * put implicitly before it
+ and with some changed rules (it's const, there are no null references,
+ and a reference to a const type can be bound to a temporary - did I miss
+ some?). What's wrong with this view? It's easy to understand and correct.
+ Other explanations resort to magic ("the compiler somehow communicates")
+ which doesn't provide a clue on what is stored at which place.

Agreed.

Whatever int& f(){return *new int;} returns is not a "name" and not an
"alternative" to something else -- it's the *only* handle the program
has on the new int that f creates.  So, discussions of the
references-are-aliases perspective inevitably degenerate into
humpty-dumpty stuff about the meaning of "alias".

Stroustrup accepts the automatically-dereferenced-pointer perspective
as harmless:

   The obvious implementation of a reference is as a constant pointer
   that is dereferenced each time it is used.  It doesn't do much harm
   thinking about references that way, as long as one remembers that a
   reference isn't an object that can be manipulated the way a pointer
   is: ... In some cases, the compiler can optimize away a reference
   so that there no object representing that reference at run time.
                              [The C++ Programming Language, page 98]

In fact, under equivalent circumstances a reference and the
corresponding constant pointer have *exactly* the same need for
run-time storage.  (Perhaps Stroustrup is referring to the fact that
POD struct-or-class objects are required to conform to C's layout
rules, which require that space be allocated to objects whose need for
space has been optimized away, and that the presence of a reference
member makes an objects non-POD.)

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ahp6@email.byu.edu ("Adam H. Peterson")
Date: Thu, 9 Oct 2003 19:12:59 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote:
<snip>
> Agreed.
>
> Whatever int& f(){return *new int;} returns is not a "name" and not an
> "alternative" to something else -- it's the *only* handle the program
> has on the new int that f creates.  So, discussions of the
> references-are-aliases perspective inevitably degenerate into
> humpty-dumpty stuff about the meaning of "alias".

Consider this, though.  You can't determine whether storage has been
allocated for a reference, except possibly through mathematical proofs
that there's no other way to do it.

If you have:

int &i=f();

How do you get the address of i?  The expression &i will only give you
the address of the anonymous value returned through f().  Likewise for
&(f()).

In the code segment:

int j=0;
int &k=j;
int &l=k;

The only way to distinguish the original "name" of i from the "aliases"
or "automatically dereferenced pointers" j and k is to look up at their
declaration.  You can't get the address of these "automatically
dereferenced pointers" to find out where in memory they're stored.

 > Stroustrup accepts the automatically-dereferenced-pointer perspective
 > as harmless:
 >
 >    The obvious implementation of a reference is as a constant pointer
 >    that is dereferenced each time it is used.  It doesn't do much harm
 >    thinking about references that way, as long as one remembers that a
 >    reference isn't an object that can be manipulated the way a pointer
 >    is: ... In some cases, the compiler can optimize away a reference
 >    so that there no object representing that reference at run time.
 >                               [The C++ Programming Language, page 98]

I'll accept it as mostly harmless as well.  But calling a concept
harmless is a weak way of establishing it as a foundational argument.
The concept that the earth is flat is mostly harmless as well.  (The
auto-deref-pointer concept has more merit than the flat-earth concept,
but I'm making a point.)

Adam Peterson

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pasa@lib.hu ("Balog Pal")
Date: Fri, 10 Oct 2003 01:20:31 +0000 (UTC)
Raw View
4@andromeda.datanet.hu> <pan.2003.10.09.06.59.59.162012@knm.org.pl>
Subject: Re: No subject given
Date: Thu, 9 Oct 2003 23:59:50 +0100
Lines: 149
Organization: LiB
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.50.4922.1500
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4925.2800
Path: monor-206.dialin.datanet.hu
NNTP-Posting-Host: monor-206.dialin.datanet.hu
Message-ID: <3f85df20@andromeda.datanet.hu>
X-Trace: 10 Oct 2003 00:20:16 +0200, monor-206.dialin.datanet.hu

""Marcin 'Qrczak' Kowalczyk"" <qrczak@knm.org.pl> wrote in message
news:pan.2003.10.09.06.59.59.162012@knm.org.pl...

> Another example:
>    int *p = p1;
>    int &r = *p;
>    p = p2; // Does r change too? You told it's an alias for *p! :-)

Is that really that mysterious?  Reference refers to an object. Just like a
'regular' name refers to an object.  In the original example we had a named
object, so the reference created vas an alias of that _name_. By referring
to the very same object.

Here *p is not an object, it is an _expression_.  Which, after evaluated
produces an object.  then you bind the name 'r' to that object. Which had no
initial name, so it is not an alias here. But if you then say int &r1 = r;
r1 will be an alias to r.

> > And in yet other words just having int i; you could think of it as an
> > automatically dereferenced pointer to an int.   But I doubt many people
> > actually think that way.
>
> Indeed, because it's always known statically what it would point to, so
> you can always talk about the pointed to object directly.

What you mean by 'statically known'?  Known by who, the programmer or the
compiler? And what is really known?    This just beats me.    The programmer
(unless peeking the assy output) known not where the object is, only its
behavior. (static, auto, temporary...)
And should the programmer care about more than defined behavior?
Or if you mean the compiler, what difference is it to the compiler if r
denotes result of lea [ebx + 0x10] or of [ebp + 0x40], or eax just got from
some expression?


> For references
> it is generally not known what they point to,

Excuse me, I'd immediately resign if I could not tell in a short time what
references in my code are bound to.    [or anything else for that
matter... ]
Not the address ceratinly, but the meaning in conceptual terms.    How could
I tell what the program does otherwise?    Or that it does what is in the
contract?

> except in useless cases used
> in examples - a reference which points to a named variable is indeed
> equivalent with that variable and that's why nobody makes such references.

If you change cv qualifiers it will not be such a rare case.  And even  a
simple alias can be good, if you for some reason have a long-spanning
variable with different roles along the path.  [But you'll need lengthy
functions to make sense, which are generally to avoid.]

> Your "some situations the compiler must communicate it to a point far
away"
> cover 99% of cases.

Well, I'd say over 90% too, as nowadays we tend to pass lot of stuff by cont
ref instead of value as an optimisation trick.    If we had MOJO working
fine and some support from language that ratio would go down likely.  But
that's another story again.

Okey most uses of refs are in params and return types.   And unless inlined
the compiler will pass some address most likely.

Just comes to mind, what if the compiler "cheated" and passed short objects
(say fitting in a register) by value instead of constref?  [think
templates<int> or <some*>].    When we can tell the difference?     Aliasing
and cast away const?   The first generally can be set to 'assume no', the
other is more tricky.    Let's assume that also explained to the compiler.
Then it has a free way, does it?    null ref is illegal, so why not use the
object directly?

> References found in real life require storage, so
> it's strange to begin explaining them with unnatural cases which don't
> and set other cases as special.

But that is the whole point.  From conceptual view you need no storage for
the reference. The compiler will use storage if no other way is discovered,
but I do NOT call that necessity.  ref is not an object.   We should better
not think of it as if it were.

> The reference is a fancy kind of pointer with * put implicitly before it
> and with some changed rules

Yeah, and a quadrilateral is a triangle with one side broken to two.  Or a
circle bashed on sides.

> (it's const, there are no null references,
> and a reference to a const type can be bound to a temporary - did I miss
> some?).

Probably not -- but those differences are sufficient to say it's something
different.
As a pointer is also nothing but an integer. But one which we will use in a
special way to access a memory location.   As everything finally converts to
the same little machine code and will use raw registers and memory -- we
still prefer to use *abstractions*.  And a pointer is one such abstraction
of a concept. And so is a reference.

To me ref means its implicit 'there IS an object' and a pointer -- when
passed as param to a function -- also means 'there IS a case when it is
NULL'.  In my code.  And in code I'd prefer to read.

> What's wrong with this view? It's easy to understand and correct.

To me it is a way to the goo world.  We can call anythng 'goo' and try to
use some qualifiers time-to-time to be somewhat more specific.   After all
where it's important one can use enough qualifiers on the spot to tell
anything he wants.   So it is not an incorrect or wrong way of doing things.

But I think it is way suboptimal.   I prefer more solid use of terms -- that
may look rigid, but retains more implicit information.

Or using other example: when we talk/chatter, we just use words as they
come.  But a writer, or especially a poet will carefully chose words that
fit.  As Francis said he can call a spade a spade, or sometaomes call it a
bloody shovel, and there is a difference.

To me
x += 1;   ++x;
!x; x != 0;

and similar expressions that compile to the same object code also bring
different meaning in code -- they have nuances.    While references and
pointers are not even nuances, but bring in wast difference, making then
just not interchangeable.    For me.  And a couple of programmers I know.

And honestly I see no benefit in washing away the difference.    It's no
problem to point out facts like refs are indeed implemented as pointers in
99% of cases, or that in really big need you can just cheat at will writing
prototypes for a win32 DLL.    but the concepts should better keep distinct
in the mind after that pointed out.

> Other explanations resort to magic ("the compiler somehow communicates")
> which doesn't provide a clue on what is stored at which place.

And magic is allowed. Suppose an implementation that can store stuff in
registers -- and use small numbers passed in the 'ref value' to denote a
register, other values denoting address.  As ref is never null, and never
subject to pointer math, why not?

OTOH I like magic. :)    much more fun than thinking everyting as boring
uniform bits. :->

Paul


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Fri, 10 Oct 2003 15:54:23 +0000 (UTC)
Raw View
"Adam H. Peterson" <ahp6@email.byu.edu> wrote:
+ thp@cs.ucr.edu wrote:
+ <snip>
+> Agreed.
+>
+> Whatever int& f(){return *new int;} returns is not a "name" and not an
+> "alternative" to something else -- it's the *only* handle the program
+> has on the new int that f creates.  So, discussions of the
+> references-are-aliases perspective inevitably degenerate into
+> humpty-dumpty stuff about the meaning of "alias".
+
+ Consider this, though.  You can't determine whether storage has been
+ allocated for a reference, except possibly through mathematical proofs
+ that there's no other way to do it.
+
+ If you have:
+
+ int &i=f();
+
+ How do you get the address of i?  The expression &i will only give you
+ the address of the anonymous value returned through f().  Likewise for
+ &(f()).
+
+ In the code segment:
+
+ int j=0;
+ int &k=j;
+ int &l=k;
+
+ The only way to distinguish the original "name" of i from the "aliases"
                                                     ^
                                                     j?
+ or "automatically dereferenced pointers" j and k is to look up at their
                                           ^
                                           l?
+ declaration.  You can't get the address of these "automatically
+ dereferenced pointers" to find out where in memory they're stored.

Of course.  C++ references are automatically dereferenced in all
contexts, even when they are operands of unary-&.  So what?

+ > Stroustrup accepts the automatically-dereferenced-pointer perspective
+ > as harmless:
+ >
+ >    The obvious implementation of a reference is as a constant pointer
+ >    that is dereferenced each time it is used.  It doesn't do much harm
+ >    thinking about references that way, as long as one remembers that a
+ >    reference isn't an object that can be manipulated the way a pointer
+ >    is: ... In some cases, the compiler can optimize away a reference
+ >    so that there no object representing that reference at run time.
+ >                               [The C++ Programming Language, page 98]
+
+ I'll accept it as mostly harmless as well.  But calling a concept
+ harmless is a weak way of establishing it as a foundational argument.
+ The concept that the earth is flat is mostly harmless as well.  (The
+ auto-deref-pointer concept has more merit than the flat-earth concept,
+ but I'm making a point.)

And, the spherical-earth hypothesis is "mostly harmless".

IMHO, comparing the perspectives that references are "aliases" vs.
"automatically dereferenced pointers" is pretty much equivalent to
comparing the flat-earth and the sherical-earth hypotheses.  One
persepctive is way more accurate and helpful than the other.

Tom Payne









---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Fri, 10 Oct 2003 20:45:32 +0000 (UTC)
Raw View
"Balog Pal" <pasa@lib.hu> wrote:
+ ""Marcin 'Qrczak' Kowalczyk"" <qrczak@knm.org.pl> wrote
[...]
+> Another example:
+>    int *p = p1;
+>    int &r = *p;
+>    p = p2; // Does r change too? You told it's an alias for *p! :-)
+
+ Is that really that mysterious?  Reference refers to an object. Just like a
+ 'regular' name refers to an object.  In the original example we had a named
+ object, so the reference created vas an alias of that _name_. By referring
+ to the very same object.
+
+ Here *p is not an object, it is an _expression_.  Which, after evaluated
+ produces an object.  then you bind the name 'r' to that object. Which had no
+ initial name, so it is not an alias here. But if you then say int &r1 = r;
+ r1 will be an alias to r.

I realize that you know what you mean when you say that "references are
simply aliases, but consider

  #define r *p

IMHO, it would be legitimate to say that "r is an alias for *p" and
thus to misinterpret the meaning when C++ experts say that "references
are simply aliases".  Marcin says he has witnessed such
misinterpretation and considers it legitimate.

[...]
+> References found in real life require storage, so
+> it's strange to begin explaining them with unnatural cases which don't
+> and set other cases as special.
+
+ But that is the whole point.  From conceptual view you need no storage for
+ the reference. The compiler will use storage if no other way is discovered,
+ but I do NOT call that necessity.  ref is not an object.   We should better
+ not think of it as if it were.

Under similar circumstance pointers need no storage, with the one
exception that for C compatibilty pointer members of POD objects
cannot be optimized away, whether they need storage or not.

[...]

+ It's no problem to point out facts like refs are indeed implemented as
+ pointers in 99% of cases

It's my undestanding that both pointers and references are C++ notions
and both are implemented in terms of machine code where the notions of
pointer and reference are usually implemented in terms of addresses.
I understand what it means to say that one of these notions behaves
like some hypothetical variant of the other, but I don't understand
what it means to say that one is implemented "as" the other, since
AFAIK neither is an implementation-level notion.  Perhaps this is an
elliptical construction meaning "references are implemented as
pointers are implemented".  But if both are implemented the same way,
why is one considered an object and the other not?

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: belvis@pacbell.net (Bob Bell)
Date: Sat, 11 Oct 2003 01:46:02 +0000 (UTC)
Raw View
thp@cs.ucr.edu wrote in message news:<bm45nk$t5l$1@glue.ucr.edu>...
> "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl> wrote:
> + The reference is a fancy kind of pointer with * put implicitly before it
> + and with some changed rules (it's const, there are no null references,
> + and a reference to a const type can be bound to a temporary - did I miss
> + some?). What's wrong with this view? It's easy to understand and correct.
> + Other explanations resort to magic ("the compiler somehow communicates")
> + which doesn't provide a clue on what is stored at which place.
>
> Agreed.
>
> Whatever int& f(){return *new int;} returns is not a "name" and not an
> "alternative" to something else -- it's the *only* handle the program
> has on the new int that f creates.  So, discussions of the
> references-are-aliases perspective inevitably degenerate into
> humpty-dumpty stuff about the meaning of "alias".

No. int& f(){return *new int;} (besides being poor code) returns a
reference to a dynamically allocated int. The idea that aliases must
be restricted to named objects is silly, and only obscures the issues.

#include <iostream>

int& f()
{
   return *new int(0);
}

int main()
{
   int& x = f();

   std::cout << x << "\n";
   std::cout << &x << "\n";
}

prints

0
0x8057f08

Here, x is a reference (or alias if you prefer) to a (unnamed)
dynamically allocated int. x was initialized by calling f(), which
created a (unnamed) dynamically allocated int and returned a reference
to it.

How does this support "references are really pointers"?

> Stroustrup accepts the automatically-dereferenced-pointer perspective
> as harmless:
>
>    The obvious implementation of a reference is as a constant pointer
>    that is dereferenced each time it is used.  It doesn't do much harm
>    thinking about references that way, as long as one remembers that a
>    reference isn't an object that can be manipulated the way a pointer
>    is: ... In some cases, the compiler can optimize away a reference
>    so that there no object representing that reference at run time.
>                               [The C++ Programming Language, page 98]

The key phrase is "as long as one remembers that a reference isn't an
object that can be manipulated the way a pointer is". It strikes me
that proponents of the "references are really pointers" view may not
be keeping this in mind.

> In fact, under equivalent circumstances a reference and the
> corresponding constant pointer have *exactly* the same need for
> run-time storage.  (Perhaps Stroustrup is referring to the fact that
> POD struct-or-class objects are required to conform to C's layout
> rules, which require that space be allocated to objects whose need for
> space has been optimized away, and that the presence of a reference
> member makes an objects non-POD.)

It seems to me that paying too much attention to the implementation
view is leading to these (IMHO) incorrect views of references. Here's
another example:

const int& x = 3 + 4;

"3 + 4" computes a result, which isn't named anywhere. x is a
reference to that result.


const int& x = 3 + 4;

It could be implemented as

const int compiler_generated_temp_name = 3 + 4;
const int* x = &compiler_generated_temp_name;
// followed by automatic dereferencing of x

or

const int x = 3 + 4;

or

// everywhere x appears, just substitute "7"

How does this support "references are really pointers"?

Focusing on the implementation of references in order to argue about
them makes as much sense as focusing on v-tables in order to argue
about virtual functions.

Bob

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk")
Date: Mon, 13 Oct 2003 04:28:29 +0000 (UTC)
Raw View
On Sat, 11 Oct 2003 01:46:02 +0000, Bob Bell wrote:

> const int& x = 3 + 4;
>
> It could be implemented as
>
> const int compiler_generated_temp_name = 3 + 4;
> const int* x = &compiler_generated_temp_name;
> // followed by automatic dereferencing of x
>
> or
>
> const int x = 3 + 4;
>
> or
>
> // everywhere x appears, just substitute "7"
>
> How does this support "references are really pointers"?

I don't say that they are exactly the same as pointers. I say that they
differ from automatically dereferenced const pointers only in that they
can't be null and that a reference to const can be bound to a temporary.

If you have:
   const int temp = 3 + 4;
   const int *const p = &temp;
and don't take &p anywhere, the compiler can compile *p the same as temp
or just as 7. This optimization ability is not caused by differences
between references and pointers, but by the fact that p and *p are const.

Explanation of references in terms of pointers with some changed rules is
easy and unambiguous. I don't know any other explanation which is as short
and clear.

--
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: thp@cs.ucr.edu
Date: Mon, 13 Oct 2003 04:28:35 +0000 (UTC)
Raw View
Bob Bell <belvis@pacbell.net> wrote:
+ thp@cs.ucr.edu wrote in message news:<bm45nk$t5l$1@glue.ucr.edu>...
+> "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl> wrote:
+> + The reference is a fancy kind of pointer with * put implicitly before it
+> + and with some changed rules (it's const, there are no null references,
+> + and a reference to a const type can be bound to a temporary - did I miss
+> + some?). What's wrong with this view? It's easy to understand and correct.
+> + Other explanations resort to magic ("the compiler somehow communicates")
+> + which doesn't provide a clue on what is stored at which place.
+>
+> Agreed.
+>
+> Whatever int& f(){return *new int;} returns is not a "name" and not an
+> "alternative" to something else -- it's the *only* handle the program
+> has on the new int that f creates.  So, discussions of the
+> references-are-aliases perspective inevitably degenerate into
+> humpty-dumpty stuff about the meaning of "alias".
+
+ No. int& f(){return *new int;} (besides being poor code) returns a
+ reference to a dynamically allocated int. The idea that aliases must
+ be restricted to named objects is silly, and only obscures the issues.
+
+ #include <iostream>
+
+ int& f()
+ {
+   return *new int(0);
+ }
+
+ int main()
+ {
+   int& x = f();
+
+   std::cout << x << "\n";
+   std::cout << &x << "\n";
+ }
+
+ prints
+
+ 0
+ 0x8057f08
+
+ Here, x is a reference (or alias if you prefer) to a (unnamed)
+ dynamically allocated int. x was initialized by calling f(), which
+ created a (unnamed) dynamically allocated int and returned a reference
+ to it.
+
+ How does this support "references are really pointers"?

The point to introducing int& f(){return *new int;} is to show that
the notion that references-are-aliases is somewhat absurd, since f()
is neither a "name" nor an "alternative".

+> Stroustrup accepts the automatically-dereferenced-pointer perspective
+> as harmless:
+>
+>    The obvious implementation of a reference is as a constant pointer
+>    that is dereferenced each time it is used.  It doesn't do much harm
+>    thinking about references that way, as long as one remembers that a
+>    reference isn't an object that can be manipulated the way a pointer
+>    is: ... In some cases, the compiler can optimize away a reference
+>    so that there no object representing that reference at run time.
+>                               [The C++ Programming Language, page 98]
+
+ The key phrase is "as long as one remembers that a reference isn't an
+ object that can be manipulated the way a pointer is". It strikes me
+ that proponents of the "references are really pointers" view may not
+ be keeping this in mind.

But, similarly, automatically dereferenced pointers couldn't be
manipulated the way other pointers are.  The reason is not that they
wouldn't be pointers but rather because they would be automatically
derefereced at all attempts to manipulate them.  So that "key phrase"
has nothing to do with the question of whether or not automatically
dereferenced pointers would behave the same way as references behave,
which IMHO is the relevant issue.

+> In fact, under equivalent circumstances a reference and the
+> corresponding constant pointer have *exactly* the same need for
+> run-time storage.  (Perhaps Stroustrup is referring to the fact that
+> POD struct-or-class objects are required to conform to C's layout
+> rules, which require that space be allocated to objects whose need for
+> space has been optimized away, and that the presence of a reference
+> member makes an objects non-POD.)
+
+ It seems to me that paying too much attention to the implementation
+ view is leading to these (IMHO) incorrect views of references.
[...]
+ Focusing on the implementation of references in order to argue about
+ them makes as much sense as focusing on v-tables in order to argue
+ about virtual functions.

I don't disagree with that, but I was responding to and commenting
on a particular phrase in the cited passage from Stroustrup:

   In some cases, the compiler can optimize away a reference
   so that there no object representing that reference at run
   time.

And that passage explicitly addresses matters of implementation.
IMHO, that passage is a red herring, since what it claimed about
references is equally true of pointers in similar cases.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 13 Oct 2003 15:59:27 +0000 (UTC)
Raw View
In article <pan.2003.10.11.09.07.27.420248@knm.org.pl>, Marcin 'Qrczak'
Kowalczyk <qrczak@knm.org.pl> writes
>Explanation of references in terms of pointers with some changed rules is
>easy and unambiguous. I don't know any other explanation which is as short
>and clear.

So how do you explain them to people who know nothing about pointers?
That is a serious question, and the answer is more likely to describe
what a reference really is in C++ than by taking some short cut based on
looking under the hood and referring to a common implementation policy.

And as has already been pointed out, there is a fundamental difference
illustrated by the fact that you cannot have an array of references.

The nearest simple definition that I can come up with is:

In C++ a reference is a statically typed name that must be bound to an
existing object with an appropriate type at the point of first use.

We would then have to cover what is meant by appropriate type and what
we mean by point of first use (which has to cover call sites binding
arguments to parameters)

Any attempt to describe a reference as something else but with added
constraints is bound to fail because a C++ reference is nothing more nor
less than a C++ reference (and as we all know it is not a Java
reference)





--
Francis Glassborow      ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 13 Oct 2003 15:59:42 +0000 (UTC)
Raw View
In article <bm8qkb$806$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>   In some cases, the compiler can optimize away a reference
>   so that there no object representing that reference at run
>   time.
>
>And that passage explicitly addresses matters of implementation.
>IMHO, that passage is a red herring, since what it claimed about
>references is equally true of pointers in similar cases.

Actually I think it is worse because I do not think that a reference is
ever 'an object'. A pointer variable is an object in its own right, it
has state and location (you can take its address). A reference variable
is not, it has no state and no location, it only has the state and
location of the object to which it refers (which may or may not have a
name of its own)


--
Francis Glassborow      ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Balog Pal (mh)" <pasa@lib.hu>
Date: Tue, 19 Jun 2001 00:02:53 GMT
Raw View
n9imm2j.it.news_comp.std.c++_expires-2001-09-01@nightrunner.nmhq.net>
Subject: Re: C++0x
Date: Mon, 18 Jun 2001 21:52:16 +0200
Lines: 73
X-Newsreader: Microsoft Outlook Express 4.72.3110.5
X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3
Path: www.lib.hu
NNTP-Posting-Host: www.lib.hu
Message-ID: <3b2e5c03@andromeda.datanet.hu>
X-Trace: 18 Jun 2001 21:52:35 +0200, www.lib.hu

Niklas Matthies wrote in message ...

>> void * a_ptr = operator new(1000);
>>
>> What object is it pointing to?
>
>Well, you caught me, it's not at "any given time",

But what is the problem here? op new allocates raw memory. And that it
returns, and address to absolutely raw memory block.

Later, we could "convert" it to a typed pointer using placement-new syntax,
if that is what we allocated raw memory for.

> but only after it has
>been initialized, or simply has been decided to have a certain type that
>doesn't have trap representations. Note that this is not much different
>than
>
>   T *t_ptr = (T *) operator new(100 * sizeof(T));
>
>where T is an object type. Should t_ptr here considered to point to a T
>just because its type is T*?

Definitely not without a good cast. And a reinterpret_cast for that case.
However

T * pT = new (a_ptr) T;

would make perfect sense, placement new taking pointers to raw, providing
pointers to object.

>The type of a pointer merely indicates
>intent, not any actual quality of the storage pointed to.


And that's why reinterpret_cast more closely applies to conversuion than
static_cast, if applied to raw.

>> Whichever way you cut it, neither C nor C++ is consistent in its view
>> of what void* is.
>
>I didn't mean to claim that. I'm arguing that a arithmetics-enabled
>void* is not any more inconsistent and unsound than the current one.


Yep, as it applies well to the usage where we want math, and for the other
usage math will not come to picture anyway.

>> C is more nearly so, because it largely treats void* values as
>> pointers to untyped memory.


I honestly didn't follow what C does lately, IIRC void * there converted to
typed pointers silently, what IMHO is something completely unreasonable, and
only reflect the disrespect of the type system C poured on the world. No, I
retract that, replace C with "a big bunch of C programmers I was unfortunate
enough to meet either in life or in code". I hope everyone around is more
luckier. ;-)

>I don't quite follow this. If C treats void*s as pointers to untyped
>memory and you mean to imply by this that C++ does not, then it seems
>strange that C allows implicit conversion to typed pointers and C++ does
>not.


While the raw pointer should be much less convertible to a type than a
sometype pointer.

Paul



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Usenet admin <usenet@gps.leeds.ac.uk>
Date: Mon, 22 Jan 2001 17:03:16 GMT
Raw View
Newsgroups: comp.std.c++
Path: not-for-mail
From: eennjp@electeng.leeds.ac.uk
Subject: Re: Feature request: Forward declaration of typedefs
User-Agent: tin/1.4.2-20000205 ("Possession") (UNIX) (Linux/2.0.36 (i686))
Sender: Neil J Pilgrim <eennjp@een-pc245.leeds.ac.uk>
Organization: University of Leeds
Message-ID: <G7KpL8.DJF@leeds.ac.uk>
References: <g5ha6.13725$pp2.1251725@news3.cableinet.net>
X-Nntp-Posting-Host: een-pc245.leeds.ac.uk
Date: Mon, 22 Jan 2001 16:53:31 GMT
Lines: 49

Wilka <jvyxn@evghnyvfgvp.pbz> wrote:
> things like "class std::string;" are illegal because std::string isn't a
> class, but it's such a common thing to want to do (mostly for user defined
> types) that it probably should be possible. Obvious you can't use 'class'
> for this purpose, but I can't think of a reason not to allow, e.g.

> typename std::string;

> struct something
> {
>    something(const std::string& str);
>     std::string foo() const;
> };

> It could also be extended to work with enums, and possibly nested types,
[snip]

I have had this problem too, with something like:

class Foo
{
  typedef char SomeImportantTypeToAbstract;
  //...other stuff...
};

and yes, Foo::SomeImportantTypeToAbstract cannot be used as you say. The
problem, AFAICT, is that we're trying to access something 'in' a class,
ie. essentially incrementally define a class? This cannot be done with
classes, but can with namespaces. So the above could be rearranged to:

namespace FooSpace
{
  class Foo
  {
  // ... other stuff ...
  };
  typedef char SomeImportantTypeToAbstract;
};

and (guess, not actually tried):

using FooSpace::SomeImportantTypeToAbstract;

Could someone confirm whether this is possible?

Thanks

--
Neil

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: 2000/11/30
Raw View
In article <200011192231.OAA00340@news.nwlink.com>,
  "Gary Hinger" <garyh@zipperint.com> wrote:

> No, in reality, NULL is defined as an integral constant expression
> equal to zero. Therefore (char)NULL is an acceptable character for
> terminating a string.

Only in C++, not in C.  And even in C++, some compilers warn if you
do.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/29
Raw View
>> NULL represents a null pointer constant, not a character.
>>
>> When you say (char)NULL, you are making it clear that you have
>> misunderstood this difference. In the bit you quoted, David Tribble
>> explains this well (note his use of the word "mistakenly"):

Gary Hinger wrote:
> No, in reality, NULL is defined as an integral constant expression
> equal to zero.

Only in C++, and then only because C++ doesn't have the concept of
a built-in null pointer constant (other than integer zero).

> Therefore (char)NULL is an acceptable character for terminating a
> string.

Only by accident; certainly not by design.  And then only in C++,
not in C.

> Consider the following function:
>
> void my_strlen( char const *const ptr )
> {
>     assert( ptr != NULL );
>     for (int i = NULL; ptr[i] != (char)NULL; i++);
>     return i;
> }
>
> This may seem awkward but it is perfectly legal. It isn't even
> "deprecated" as far as I know.

Only in C++.  It may well work with some C compilers, but it's not
portable C.

You are living in a state of sin if you use NULL as an integer
constant (in either language), and most especially if you use it
when you mean '\0'.  NULL should only be used as a null pointer
constant, regardless of what its value may actually be.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/21
Raw View
Gary Hinger wrote:
...
> No, in reality, NULL is defined as an integral constant expression equal to
> zero. Therefore (char)NULL is an acceptable character for terminating a
> string. Consider the following function:

This thread is cross-posted to comp.std.c, not just in comp.std.c++. In
C, (void *)0 is also a valid value for NULL, and there's no guarantee in
the C standard that (char)(void*)0 is the same as (char)0, though AFAIK
that is in fact the case on most systems.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/11/21
Raw View
Keith Thompson wrote:
...
> NULL is (a macro that expands to) a null pointer constant.  In C, it
> can legally be defined as (void*)0; casting that value to a character
> type may or may not yield a null character.  This may be different in
> C++.

It is. (void *)0 is not a legal null pointer constant in C++.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Gary Hinger" <garyh@zipperint.com>
Date: 2000/11/18
Raw View
u.edu> <m3u29nhq45.fsf@merlin.codesourcery.com> <3A0CCBE5.EC4ED6FF@wizard.net> <3A13F739.72C55869@physik.tu-muenchen.de> <3A14249D.C001BBB1@tribble.com>
Subject: Re: What is the macro NULL according to standard C++?
Date: Fri, 17 Nov 2000 15:10:50 -0800
Lines: 37
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.00.2615.200
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200
Path: unassigned.zipperint.com
NNTP-Posting-Host: unassigned.zipperint.com
Message-ID: <3a15bacb$1_2@news.nwlink.com>
X-Trace: 17 Nov 2000 15:10:03 -0800, unassigned.zipperint.com
Organization: Northwest Link

I thought that the NUL character is defined as character 0. Are you
suggesting - in theory or in practice - that there are implementations where
strings are terminated by characters other than (char)NULL?

David R Tribble <david@tribble.com> wrote in message
news:3A14249D.C001BBB1@tribble.com...
> Christopher Eltschka wrote:
> > I guess there's much legacy code which relies on 0 being a null
> > pointer constant, but I cannot imagine that there is much code
> > which relies on NULL being usable in integer contexts.
> > Why should someone write NULL, if all he means is 0 (which is
> > typed much easier, and doesn't need a header).
>
> Because that someone mistakenly believes that NULL also specifies
> the character code for the NUL character, e.g.,
>
>     memset(buf, NULL, sizeof(buf));
>
> This is real code I've seen.  The tragedy is that many C compilers,
> including many Unix C compilers, accept this without complaint.
> Fortunately, it's not portable C code.
>
> But the real tragedy is that this is perfectly valid and portable
> C++ code.
>
> --
> David R. Tribble, mailto:david@tribble.com, http://david.tribble.com
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
> [ Note that the FAQ URL has changed!  Please update your bookmarks.     ]
>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Richard Heathfield <binary@eton.powernet.co.uk>
Date: Sun, 19 Nov 2000 00:49:01 GMT
Raw View
[Why did you change the subject line? Oh well...]

Gary Hinger wrote:
>
<snip>
>
> I thought that the NUL character is defined as character 0.

As far as the ISO/EIC 9899:1999 Standard is concerned, the word "NUL"
does not occur and thus has no meaning within the Standard.

In practice, ASCII and EBCDIC both equate NUL with 0. But neither ASCII
nor EBCDIC is assumed to be the only possible source character set in C.

> Are you
> suggesting - in theory or in practice - that there are implementations where
> strings are terminated by characters other than (char)NULL?

You are confusing NULL with NUL. NUL has no meaning within the C
Standard, but NULL does.

If NUL did have a meaning, it would be the character constant '\0'.

NULL represents a null pointer constant, not a character.

When you say (char)NULL, you are making it clear that you have
misunderstood this difference. In the bit you quoted, David Tribble
explains this well (note his use of the word "mistakenly"):

>
> David R Tribble <david@tribble.com> wrote in message
> news:3A14249D.C001BBB1@tribble.com...

<snip>

> > Because that someone mistakenly believes that NULL also specifies
> > the character code for the NUL character, e.g.,
> >
> >     memset(buf, NULL, sizeof(buf));
> >
> > This is real code I've seen.  The tragedy is that many C compilers,
> > including many Unix C compilers, accept this without complaint.
> > Fortunately, it's not portable C code.

--
Richard Heathfield
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Gary Hinger" <garyh@zipperint.com>
Date: 2000/11/20
Raw View
<200011172310.PAA14513@news.nwlink.com> <3A16C41D.87F8A20@eton.powernet.co.uk>
Subject: Re: What is the macro NULL according to standard C++?
Date: Sun, 19 Nov 2000 14:31:38 -0800
Lines: 22
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.00.2615.200
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200
Path: unassigned.zipperint.com
NNTP-Posting-Host: unassigned.zipperint.com
Message-ID: <3a1854cf_1@news.nwlink.com>
X-Trace: 19 Nov 2000 14:31:43 -0800, unassigned.zipperint.com
Organization: Northwest Link

> NULL represents a null pointer constant, not a character.
>
> When you say (char)NULL, you are making it clear that you have
> misunderstood this difference. In the bit you quoted, David Tribble
> explains this well (note his use of the word "mistakenly"):

No, in reality, NULL is defined as an integral constant expression equal to
zero. Therefore (char)NULL is an acceptable character for terminating a
string. Consider the following function:

void my_strlen( char const *const ptr )
{
    assert( ptr != NULL );
    for (int i = NULL; ptr[i] != (char)NULL; i++);
    return i;
}

This may seem awkward but it is perfectly legal. It isn't even "deprecated"
as far as I know.



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/11/20
Raw View
"Gary Hinger" <garyh@zipperint.com> wrote...
>
> No, in reality, NULL is defined as an integral constant expression
> equal to zero. Therefore (char)NULL is an acceptable character for
> terminating a string. Consider the following function:
>
> void my_strlen( char const *const ptr )
> {
>     assert( ptr != NULL );
>     for (int i = NULL; ptr[i] != (char)NULL; i++);
>     return i;
> }
>
> This may seem awkward but it is perfectly legal. It isn't even
> "deprecated" as far as I know.

I presume Gary is reading this thread in comp.std.c++. Sadly for him,
this was X-posted to comp.std.c where it is not quite perfectly legal.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Keith Thompson <kst@cts.com>
Date: 2000/11/20
Raw View
"Gary Hinger" <garyh@zipperint.com> writes:
> I thought that the NUL character is defined as character 0. Are you
> suggesting - in theory or in practice - that there are implementations where
> strings are terminated by characters other than (char)NULL?

I don't think the standard uses the name NUL to refer to character 0,
but it's true that strings are terminated by (char)0.

NULL is (a macro that expands to) a null pointer constant.  In C, it
can legally be defined as (void*)0; casting that value to a character
type may or may not yield a null character.  This may be different in
C++.

In any case, using NULL (which is intended to be used in a pointer
context) as a null character is horribly bad style in either language.
We have a perfectly good syntax for the null character: '\0'.  (Since
this is cross-posted to comp.std.c and comp.std.c++, I'll mention that
'\0' is of type int in C but of type char in C++.  Due to implicit
conversions, this seldom matters in C.)

--
Keith Thompson (The_Other_Keith) kst@cts.com  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Team-Rocket@gmx.net (Niklas Matthies)
Date: 2000/11/20
Raw View
On Mon, 20 Nov 2000 13:03:19 GMT, Gary Hinger <garyh@zipperint.com> wrote=
:
[=B7=B7=B7]
> > NULL represents a null pointer constant, not a character.
> >
> > When you say (char)NULL, you are making it clear that you have
> > misunderstood this difference. In the bit you quoted, David Tribble
> > explains this well (note his use of the word "mistakenly"):
>=20
> No, in reality, NULL is defined as an integral constant expression
> equal to zero. Therefore (char)NULL is an acceptable character for
> terminating a string.

Note that this thread is crossposted to comp.std.c, and that in C, NULL
may be an integral constant expression with value zero casted to void*,
which is not suitable for the abovementioned use.

-- Niklas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]