Topic: C++0x


Author: Hyman Rosen <hyrosen@mail.com>
Date: Thu, 20 Jun 2002 17:29:57 GMT
Raw View
Nate Hayes wrote:
> In other words, I would like to see the core C++ language "disentangled"
> from the STL specification, etc.

Chapters 1-16 are the core language.
Chapters 17-27 are the STL specification, etc.
That's not separate enough?

---
[ 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: "Nate Hayes" <nhayes@cyberoptics.com>
Date: Tue, 18 Jun 2002 20:09:09 GMT
Raw View
I love C++, and I have been programming it for many years. But my impression
is that it is getting bloated and complex.

I would like to see the core C++ language specification separated from the
STL and other building-blocks. Make the core C++ language spec more
organized, easy to read, and easy to understand. Keep that in one neat,
separate document. Then you can have other documents and/or specifications
for STL and/or other augmentations of the core system.

In other words, I would like to see the core C++ language "disentangled"
from the STL specification, etc.

--nate


"David Bradley" <dbradley@ZAPSPAM.Netscape.com> wrote in message
news:3D060785.6010406@ZAPSPAM.Netscape.com...
In comp.lang.c++.moderated Herb Sutter voiced concern over the fact of
going forward with the next standardization process while the existing
features in the current standard aren't fully implemented by many
mainstream vendors. So as not to misstate Herb, here's a link to the
message.
http://groups.google.com/groups?as_umsgid=fga7gu4vskatgurv744blktnbcllrprv0d
%404ax.com&lr=&hl=en

In my opinion waiting for this adoption would be a mistake. I think the
lack of adoption is something that the committee should be looking at.
Is the language too complex? Are there ways to make it easier to
implement while not sacrificing too much from the users' side?

If C++ evolves into an even more complex language, will there be anyone
left who wants to implement a compiler for it?

---
[ 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                       ]





---
[ 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: David Bradley <dbradley@ZAPSPAM.Netscape.com>
Date: Wed, 12 Jun 2002 18:27:36 GMT
Raw View
thp@cs.ucr.edu wrote:
> .... or who is willing to invest the effort necessary to really learn it.

There is that side of the equation as well. But it's not always a one
for one relationship. Often something simple and powerful from the users
perspective is difficult and adds to the complexity of the parser.

I guess what I'm wondering is if there are some tradeoffs that could be
made that would make parsing easier while not causing users a lot of grief.

An example is the recent discussion in comp.lang.c++.moderated
concerning the use of <> in templates.

---
[ 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: David Bradley <dbradley@ZAPSPAM.Netscape.com>
Date: Tue, 11 Jun 2002 15:04:56 GMT
Raw View
In comp.lang.c++.moderated Herb Sutter voiced concern over the fact of
going forward with the next standardization process while the existing
features in the current standard aren't fully implemented by many
mainstream vendors. So as not to misstate Herb, here's a link to the
message.
http://groups.google.com/groups?as_umsgid=fga7gu4vskatgurv744blktnbcllrprv0d%404ax.com&lr=&hl=en

In my opinion waiting for this adoption would be a mistake. I think the
lack of adoption is something that the committee should be looking at.
Is the language too complex? Are there ways to make it easier to
implement while not sacrificing too much from the users' side?

If C++ evolves into an even more complex language, will there be anyone
left who wants to implement a compiler for it?

---
[ 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, 12 Jun 2002 03:22:56 GMT
Raw View
David Bradley <dbradley@zapspam.netscape.com> wrote:
[...]
: If C++ evolves into an even more complex language, will there be anyone
: left who wants to implement a compiler for it?

.... or who is willing to invest the effort necessary to really learn it.

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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Mon, 2 Jul 2001 18:21:48 GMT
Raw View
On Wed, 27 Jun 2001 00:31:24 GMT, Allan W <allan_w@my-dejanews.com> wrote:
> Niklas Matthies wrote:
> > The discussion was (in large parts) about the desire for a pointer type
> > that allows pointer arithmetics, but doesn't allow dereferencing without
> > explicit conversion to an object pointer. A "byte" type wouldn't help
> > with this.
>
> How many people in this newsgroup couldn't whip out a class like that
> in ten minutes flat?
>
>     class VoidPtr {
>         void * p;
>     public:
>         VoidPtr(void*v) : p(v) {}
>         VoidPtr(const VoidPtr &v) : p(v.p) {}
>         VoidPtr &operator+=(size_t t) { p+=t; return *this; }
>         VoidPtr &operator-=(size_t t) { p-=t; return *this; }
>         template<class C>ConvertTo() { return static_cast<C*>(p); }
>         ///etc///
>     };

The ConvertTo<T>() is one reason why this is only a partial solution.
If you implement such a type, you want it to be usable as a drop-in
replacement for void* without having to think about using special
functions like ConvertTo<T>(). Alas, it is not possible to implement it
in such a way.

-- Niklas Matthies

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 27 Jun 2001 20:12:16 GMT
Raw View
In article <7f2735a5.0106261616.33d7d99b@posting.google.com>, Allan W
<allan_w@my-dejanews.com> writes
>If void is a type, I would be able to declare variables that use
>that type, right?

That is why it is an incomplete type (that cannot be completed). Of
course this is all really a hack that is playing games with the type
system but nonetheless it is a convenient fiction because we do not have
to write special rules for it, just use those that apply to incomplete
types.




Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: nevin@enteract.com (Nevin Liber)
Date: Thu, 28 Jun 2001 00:40:44 GMT
Raw View
In article <remove.haberg-1506011202170001@du136-226.ppp.su-anst.tninet.se>,
Hans Aberg <remove.haberg@matematik.su.se> wrote:

>I have an idea of a type "byte" that stands for the underlying raw memory
>management. Ideally, this should be an 8-bit type; not a C/C++ byte (the
>latter which may vary with the compiler). This idea would perhaps fall
>into the task of making systems and distributed programming easier in C++

The problem is, on an architecture where the "C/C++ byte" (I assume you
mean "char", "signed char" or "unsigned char" here) isn't 8 bits, one
of your "bytes" isn't necessarily (or likely to be) addressable.

I'm not really sure how this would fit in at all with the rest of C/C++.
For example, it would be hard to store a pointer to byte in a void *.
It seems to me this would invoke a huge run time cost.
--
 Nevin ":-)" Liber <mailto:nevin@enteract.com> (773) 961-1620

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 28 Jun 2001 21:28:49 GMT
Raw View
In article <9hdu5i$ih4$1@bob.news.rcn.net>, nevin@enteract.com (Nevin
Liber) wrote:
>>I have an idea of a type "byte" that stands for the underlying raw memory
>>management. Ideally, this should be an 8-bit type; not a C/C++ byte (the
>>latter which may vary with the compiler). This idea would perhaps fall
>>into the task of making systems and distributed programming easier in C++
>
>The problem is, on an architecture where the "C/C++ byte" (I assume you
>mean "char", "signed char" or "unsigned char" here) isn't 8 bits, one
>of your "bytes" isn't necessarily (or likely to be) addressable.

As I indicated, I really mean an 8 bit byte here so that it can be sent
over the network and has many bits in both places.

>I'm not really sure how this would fit in at all with the rest of C/C++.
>For example, it would be hard to store a pointer to byte in a void *.
>It seems to me this would invoke a huge run time cost.

As I said, it would probably fit into the picture of distributed and
systems programming, because then one needs to ensure that the bits are
equal in programs that may have compiled with different compiler.

It is sure that this will cause overheads, but the alternative would be
not have program interaction at all. So I figure the trick will be to
figure how to be able to convert between compiler and bit binary models.

One way to focus on the problem might be say when using Unicode: Suppose
that we choose 32-bit Unicode characters when communicating with other
programs. But the compiler perhaps prefers say 64-bit numbers, because say
it faster with the CPU architecture. Then one would want to be able
convert between the two in order to make sure that speed is optimized as
well as ensuring the bits come our right when communicating with other
programs.

Or take a program in cryptology or compression that makes use of a
variable size encoding, and that we first want to build it in memory
before sending it elsewhere: Then surely alignments will go off, but it is
still is necessary that the bits fall into place. In this case I am not
sure what C++ should have in order to ensure that the bits can be packed
like that, but some hooks should be present, I think.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Thu, 28 Jun 2001 21:27:56 GMT
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote (abridged):
> That is why it is an incomplete type (that cannot be completed). Of
> course this is all really a hack that is playing games with the type
> system but nonetheless it is a convenient fiction because we do not have
> to write special rules for it, just use those that apply to incomplete
> types.

There are already some special rules, at least for templates. Eg:

    template <typename T)
    T demo( T (*proc)() ) {
         return (*proc)();
    }

    void proc();

    void test() {
        demo<void>( &proc );
    }

should compile even though the code is apparently copying an incomplete
type. It might be useful if this were extended further. Eg I believe this:

    template <typename T)
    T demo2( T (*proc)() ) {
         T result = (*proc)();
         //...
         return result;
    }

is currently not supported despite its similarity to the previous
template. We have to draw the line somewhere, though. This:

    template <typename T)
    T demo2( T (*proc)() ) {
         T results[2];
         results[0] = (*proc)();
         results[1] = (*proc)();
         return results[ rand() % 2 ];
    }

is beginning to make me feel queasy. If it is supported, I would expect it
to behave as if sizeof(void) == 0, even if that means:

   (results+0) == (results+1)

Templates are easier to write if the type system behaves in a regular and
uniform way. Void is not as uniform as it could be.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 22 Jun 2001 17:54:32 GMT
Raw View
singh@garlic.com (Navi Singh) wrote (abridged):
> How about delete p setting p to NULL whenever feasible?  I think that
> would catch a lot of bugs up front with users getting NULL pointers as
> opposed to undefined pointers.

An implementation is permitted to do this already - it is included as a
possible "undefined behaviour".

On some platforms, some other value might be better than NULL. A value
like 0xdeadbeef might make it clearer in a debugger what has happened, or
might enable hardware checks for uses of such pointers.

The "undefined behaviour" clause gives an implementation the freedom to
apply more stringent checks than anything the standard could portably
mandate with defined behaviour. It's up to vendors to take advantage of
this. For some of this stuff, we should be lobbying vendors rather than
the standards committee.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Christopher Eltschka <celtschk@web.de>
Date: Tue, 26 Jun 2001 15:45:15 GMT
Raw View
news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies) writes:

[...]

> Note, however, that pointer arithmetics even on object pointers is not
> necessarily sane. One could argue that, more often than not, an object
> pointer just points to a single object and not into an array of objects,
> hence pointer arithmetics doesn't make sense and is dangerous in this
> common case.

Indeed, I think that it would have been cleaner to separate the
"pointing pointer" from the "iterating pointer", with an implicit
conversion ip->pp, but not the other way round. The only way (except
for a cast) to get an iterating pointer would be to have an array.

Of course, this would not have been possible in C++ due to C
compatibility.

[...]

---
[ 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: allan_w@my-dejanews.com (Allan W)
Date: Tue, 26 Jun 2001 19:29:39 CST
Raw View
remove.haberg@matematik.su.se (Hans Aberg) wrote:
> As for the type "void", it corresponds in math to the "empty set". So if
> there would be a runtime representation in C++, "void" could be treated as
> any other type, and "void*" would be a pointer to a such empty object. In
> fact I have experimented with such a runtime model. So there is nothing
> strange in treating "void" as a type.

If void is a type, I would be able to declare variables that use
that type, right?

    int main() {
        void v, q, r;

What could I do with these variables? I suppose I could copy them:

        void s(v);

Why not test them for equality?

        if (s==v)
            printf("==\n");
        else
            printf("!=\n");

Are they sortable?

        if (s<v)
            printf("<\n");
        else
            printf(">=\n");


Why not have an array of them?

        void t[10];

Now we have to be able to do pointer arithmetic, right?

        void *pt0 = &t[0];
        void *pt1a = &t[1];
        void &pt1b = pt0 + 1;

Can we agree that sizeof(void) cannot be zero? Because otherwise
this would fail:

        if (pt0<pt1a && (pt1a-1)==pt0 && pt1a==pt1b)
            printf("Success!\n");
        else
            printf("Failed!\n");

        return 0;
    }

Just a thought.

---
[ 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: allan_w@my-dejanews.com (Allan W)
Date: Wed, 27 Jun 2001 00:31:24 GMT
Raw View
Niklas Matthies wrote:
> The discussion was (in large parts) about the desire for a pointer type
> that allows pointer arithmetics, but doesn't allow dereferencing without
> explicit conversion to an object pointer. A "byte" type wouldn't help
> with this.

How many people in this newsgroup couldn't whip out a class like that
in ten minutes flat?

    class VoidPtr {
        void * p;
    public:
        VoidPtr(void*v) : p(v) {}
        VoidPtr(const VoidPtr &v) : p(v.p) {}
        VoidPtr &operator+=(size_t t) { p+=t; return *this; }
        VoidPtr &operator-=(size_t t) { p-=t; return *this; }
        template<class C>ConvertTo() { return static_cast<C*>(p); }
        ///etc///
    };

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 27 Jun 2001 10:58:25 GMT
Raw View
In article <7f2735a5.0106261616.33d7d99b@posting.google.com>,
allan_w@my-dejanews.com (Allan W) wrote:

>remove.haberg@matematik.su.se (Hans Aberg) wrote:
>> As for the type "void", it corresponds in math to the "empty set". So if
>> there would be a runtime representation in C++, "void" could be treated as
>> any other type, and "void*" would be a pointer to a such empty object. In
>> fact I have experimented with such a runtime model. So there is nothing
>> strange in treating "void" as a type.
>
>If void is a type, I would be able to declare variables that use
>that type, right?
>
>    int main() {
>        void v, q, r;
>
>What could I do with these variables?

If we compare with math, then
  S x;
corresponds in math to
  x in S
where S is a set. So if "void" corresponds to the empty set in math, and
  void v;
corresponds in math to saying that
  v in void
then this statement is always false (by the definition of the empty set).

But in a computer, there is also the notion of causality, so if one has a
function f there is a difference in passing nothing to f, which makes
nothing to happen, and passing an empty box to f, which causes f to
compute as if with no argument.

In C++, if one has
  A f();
  void g(B);
then it is not legal (unless they changed it to the standard) to write
(*)   B b;
      f(g(b));  // g return void, which f accepts in an argument
One must write:
(**)  B b;
      g(b);
      f();

But in a multi-threaded environment, this could make a difference, because
the latter example (**) could mean first start the process g(b), and then
start the process f() (at will, before g(b) has terminated), but the first
example (*) un-ambiguously would mean, start the process g(b), wait for
the result (which is void) and then start the process f.

So it seems that in a multi-threaded environment, algebraic expression
sort out process dependency, and using void (or "empty") and object is
important.

>Just a thought.

Just another thought.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "P.J. Plauger" <pjp@dinkumware.com>
Date: Wed, 20 Jun 2001 16:48:31 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message news:rhQPELAqwyL7EwrA@ntlworld.com...

> The serious problem is that C has different rules. As a result, in C it
> is considered to be bad practice to cast the return value from malloc
> because that can hide the failure to include a header file (probably no
> longer true in a strictly conforming C99 program) but in C++ it is
> required to cast the return value from an allocator for raw memory.

The C ``rule'' is just a style guide, one rendered less important by the
C99 change you allude to. We write code all the time that compiles as both
C and C++, using the large common subset. This particular difference is
hardly a serious problem.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.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                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 20 Jun 2001 23:42:15 GMT
Raw View
In article
<slrn9iulkc.1f8.news_comp.std.c++_expires-2001-09-01@nightrunner.nmhq.net>,
news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies) wrote:
>... I don't agree, though, that this makes allowing
>pointer arithmetics with void* unsound, since there's nothing
>particularly type-specific about the moving of a pointer, *in
>particular* when talking about an untyped pointer.

Perhaps it is so that for backwards compatibility, one does not want void*
pointer arithmetic.

But if one introduces some new raw memory types, such arithmetic could
come in very handy: Suppose for example one has a type "bit" that lines up
the memory in bits. Then one could examine the runtime binary structure
bit by bit by conversions back and forth to the "bit*" type:
  struct A {
    char c;
    int n;
  };
Here we do not know how the struct is padded: Perhaps the compiler finds
it better to pad the char c to an int (which we assume is larger than a
char) in order to avoid alignment problems. Then
  A a = ...;
  (bit*)(&a)[k]; // k'th bit from base of "a" in compiler's bit memory model.
gives us a chance to examine _all_ bits in "a", also those that are just
padding.

If now the new C++ revision should support distributed programming, where
has to know the exact binary model, one perhaps must add some constructs
anyhow.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Thu, 21 Jun 2001 23:27:28 GMT
Raw View
On Wed, 20 Jun 2001 23:42:15 GMT, Hans Aberg <remove.haberg@matematik.su.se> wrote:
> >... I don't agree, though, that this makes allowing
> >pointer arithmetics with void* unsound, since there's nothing
> >particularly type-specific about the moving of a pointer, *in
> >particular* when talking about an untyped pointer.
>
> Perhaps it is so that for backwards compatibility, one does not want
> void* pointer arithmetic.

I'm not quite sure how you think that allowing pointer arithmetics on
void* would break backward compatibility.

-- Niklas Matthies

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 22 Jun 2001 15:45:44 GMT
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote (abridged):
> Have no fear, suggestions will be rigorously analysed
> for benefit versus cost but the time for that is a little later. For now
> I would like to see the brain storming rules applied -- anything goes
> and people must not be overtly negative about other peoples suggestions.
> When we have a stack of suggestions, then will be the time to winnow thw
> wheat from the chaff.

Is someone collecting the suggestions onto a web-page somewhere, so we can
check whether our pet feature has been overlooked, and avoid repeating
suggestions already made?

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 22 Jun 2001 17:51:26 GMT
Raw View
In article
<slrn9j4mb0.1aj.news_comp.std.c++_expires-2001-09-01@nightrunner.nmhq.net>,
news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies) wrote:
>> Perhaps it is so that for backwards compatibility, one does not want
>> void* pointer arithmetic.
>
>I'm not quite sure how you think that allowing pointer arithmetics on
>void* would break backward compatibility.

"Backwards compatibility" in the programmer sense that the opinions was
that it somehow may cause programmer errors, that is, not the compiler
sense. -- I did not follow this part of the discussions, so I can not help
you out on this.

#define THEM the principal C++ language designers

Perhaps some of THEM*) can help out and tell why void* pointer arithmetic
ain't allowed.

*) A so called C++ joke.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Mon, 18 Jun 2001 18:15:34 GMT
Raw View
On Sat, 16 Jun 2001 12:04:55 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> In article <slrn9ikudt.m3q.news_comp.std.c++_expires-
> 2001-09-01@ns.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
> 2001-09-01@nmhq.net> writes
> >There is (at least) a third view of a void*. One can view a void* as a
> >pointer that can point to objects of different types, but where at any
> >given time, it is well-defined at which specific object it points to --
> >it's just that the compiler can't know in the general case.
>
> void * a_ptr = operator new(1000);
>
> What object is it pointing to?

Well, you caught me, it's not at "any given time", 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*? The type of a pointer merely indicates
intent, not any actual quality of the storage pointed to.

> 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.

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

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.

-- Niklas Matthies

---
[ 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: "Balog Pal (mh)" <pasa@lib.hu>
Date: Tue, 19 Jun 2001 00:02:37 GMT
Raw View
Francis Glassborow wrote in message ...

>In article <slrn9ikudt.m3q.news_comp.std.c++_expires-
>2001-09-01@ns.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
>2001-09-01@nmhq.net> writes
>>There is (at least) a third view of a void*. One can view a void* as a
>>pointer that can point to objects of different types, but where at any
>>given time, it is well-defined at which specific object it points to --
>>it's just that the compiler can't know in the general case.


That is actually not a third view, but one from the opposite end.

In another messaeg few days before [ 3b286bc4@andromeda.datanet.hu ] I
described the two common usages of void *. Getting not a ringle reaction
either no one read it or everyone agrees? :->

Let's call them sometype * [ex usage A, type info is dissociated at the
moment, and will be reassigned later] and raw * [ex usage B, this is pointer
to I_dont_care] for the rest of the discussion.    The pointer to
i_dont_know is that same, just looking from the compiler's perspective.

They could work like that  [this is not any proposal, just theoretic
discussion]:

sometype *:
  - any typed pointer implicitly converts to it.
  - it can be converted to any typed pointer via static_cast
  - usage is limited to passing around.

raw *:
  - any typed pointer pointing to data implicitly converts to it. (pointers
to functions do not)
  - sometype * implicitly converts to it (or not, that worth considering)
  - can't be converted to other pointers (except by using reinterpret_cast)
  - pointer-math works, using machine byte step
  - it would worth considerind to allow dereference, producing the machine
byte representing type (unsigned char). [both allowing and forbidding have a
set of good argumens pro & contra]

>void * a_ptr = operator new(1000);


>What object is it pointing to?

That is clearly a raw *.

>From another message:

>Certainly void as it was defined in C for return types is a type,
>and incomplete one that may never be completed.
>Therefore void* is a pointer to void.

void being an incomplete type will worth a separate discussion, as soon as I
get time to write down my thoughts but even if we just accept the premissa,
I can't see hot 'therefore' comes from that.

As I claimed earlier, void is just void, a nothing. you can't have objects
of that type in memory, or anywhere. No bacause the type info is
insufficient, or incomplete, but bacause the type info explicitly says so. I
can't take the address of void and stuff it to a pointer. Not any pointer,
ever can really point to void.

Bjarne could have picked up some other name instead of void *, and probably
discussions like this would never occour, it's just the 'Nomen est omen'
playing tricks on us.

BTW in practice the distinct uses of void * almost never clash, and I don't
remember real problems neither from the lack of distinction, nor from the
fact void * having the name it has. Novices must be told once, that void *
is just a name we use for something else, and that's it.

Allowing the pointer math on it would be a good idea exactly for that
reason, as by the time it could happen, pointer math should be extinct
anyway for almost all other uses it had before.

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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 19 Jun 2001 00:04:19 GMT
Raw View
In article <slrn9imm2j.it.news_comp.std.c++_expires-2001-09-01@nightrunn
er.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
2001-09-01@nmhq.net> writes
>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.

If void* points to untyped memory then it can be used anyway the
programmer chooses (though s/he better know what s/he is doing). If a
void* points to an object (of unspecified type) then it is important to
tell the compiler what that type is (and C++ requires you to do that
explicitly, just in case)


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Navi Singh" <singh@garlic.com>
Date: Tue, 19 Jun 2001 00:40:09 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
> Have no fear, suggestions will be rigorously analysed
> for benefit versus cost but the time for that is a little later. For now
> I would like to see the brain storming rules applied -- anything goes
> and people must not be overtly negative about other peoples suggestions.
> When we have a stack of suggestions, then will be the time to winnow thw
> wheat from the chaff.

How about delete p setting p to NULL whenever feasible?  I think that would
catch a lot of bugs up front with users getting NULL pointers as opposed to
undefined pointers.

Navi



---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 19 Jun 2001 17:06:20 GMT
Raw View
In article <3b2e58da@andromeda.datanet.hu>, Balog Pal (mh) <pasa@lib.hu>
writes
>BTW in practice the distinct uses of void * almost never clash, and I don't
>remember real problems neither from the lack of distinction, nor from the
>fact void * having the name it has. Novices must be told once, that void *
>is just a name we use for something else, and that's it.

The serious problem is that C has different rules. As a result, in C it
is considered to be bad practice to cast the return value from malloc
because that can hide the failure to include a header file (probably no
longer true in a strictly conforming C99 program) but in C++ it is
required to cast the return value from an allocator for raw memory.



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Tue, 19 Jun 2001 19:28:45 GMT
Raw View
On Tue, 19 Jun 2001 00:04:19 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> In article <slrn9imm2j.it.news_comp.std.c++_expires-2001-09-01@nightrunn
> er.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
> 2001-09-01@nmhq.net> writes
> >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.
>
> If void* points to untyped memory then it can be used anyway the
> programmer chooses (though s/he better know what s/he is doing). If a
> void* points to an object (of unspecified type) then it is important to
> tell the compiler what that type is (and C++ requires you to do that
> explicitly, just in case)

I agree with this. I don't agree, though, that this makes allowing
pointer arithmetics with void* unsound, since there's nothing
particularly type-specific about the moving of a pointer, *in
particular* when talking about an untyped pointer.

-- Niklas Matthies

---
[ 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: "Balog Pal" <pasa@lib.hu>
Date: Thu, 14 Jun 2001 17:32:13 GMT
Raw View
"Scott" <scottm@toast.net> wrote in message news:38716.nw.scottm@toast.net...

> >For usage that makes sense, but for the pointer math I'd fing much more
> >convenient to make it work like unsigned char * does without a cast. When
> >void * is used as raw memory pointer, it is practically a pointer to the
> >machine byte. Thus the 'element size' for the pointer math operations should
> >assume one byte units, instead of forbidding the math completely.
>
> It could, but it would be a special case then.

(please see my other posts for the day too.)

void * is already a special case, so I see nothing wrong with that, and knowing it is not really a pointer to void I'd not think to tie the step to sizeof(void) in any case. And actually it does not work that way, doing math for void * is forbidden (special case! :) as opposed to work with 0 step, or whatever number sizeof(void) happens to summon.

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: "Balog Pal" <pasa@lib.hu>
Date: Thu, 14 Jun 2001 17:32:21 GMT
Raw View
"Bjarne Stroustrup" <bs@research.att.com> wrote in message news:GEty5D.JoG@research.att.com...

> > For usage that makes sense, but for the pointer math I'd find much more
> > convenient to make it work like unsigned char * does without a cast. When
> > void * is used as raw memory pointer, it is practically a pointer to the
> > machine byte. Thus the 'element size' for the pointer math operations should
> > assume one byte units, instead of forbidding the math completely.
>
> For byte-sized units, cast to an appropriate char type. For word-sized units
> cast to an appropriate integral type, struct, or whatever, for Foo-sized
> units, cast to Foo*.
>
> In other words, I don't think you can assume that a byte is always the right
> unit for what's pointed to by a void*.

When *math* comes around I found nothing but machine byte makes sense as a unit. That 'always cast to appropriate' stuff confuse the two very distinct uses of void *:

Usage A: void * is a pointer to Sometype in tranzit.
As a plenty of the world is not C++, often we must temporarily use untyped storage to pass a pointer, until it reaches its destination. In those cases the type information is either passed along with the pointer, or is implicit at the destination.
The first thing that happens at destination is casting the arrived void * (btw during tranzit it may even lose pointerness, and be some kind of int) to the type it was originally.  Thus making the transfer transparent. Real work never happens with any intermediate forms, only the typed ones before start and after arrival. Including any attempt to do pointer math.

Should we have a 'perfect world' where our pointers magically arrive with all the type information intact, we'd never use void * for that purpose, it is merely a trick. As it is, having type info is essential.

Usage B: void * is a pointer to raw, that was originally Anytype.
the functions dealing with this usage look like

func([const] void *, size_t); // common call: func(&foo, sizeof(foo));

As opposed to use A, func has no info about the original type in any way, nor does it need that knowledge. The data passed is treated as a bunch of raw bytes, and is likely placed to some buffers, and at some point offered to similar functions (like memcpy() or write()).
Here poiner math does make sense, for example the first x bytes go to the remainder place in a buffer, then it is flushed, and the pointer must advance that amount.  The data is processed only by such functions, it is never dereferenced.

This usage is a firm part of programming, we hardly could live without it, and it will not go away.

Having no type info at all thinking any units beyond the common one (byte) does not make sense. If the units actually have some real type, using void * instead of it is an error.
And having the math vork natively in byte units IMO makes perfect sense, from this theoretical point of view.

>From the practical point of view, it is much worse. In the current situation the only way to do math with originally void * is to cast it. Especially in the days of old C++, and on 16 bit platforms I had quite many problemsdue to that req. before static_cast<> all we had was C-cast, that rendered the compiler mute, while doing routine mistakes of casting away const, or casting to wrong __near, __far, __huge qualifiers. Or doing the cast right at the moment, and having a big problem later, when porting, or fhanging the input param, or chosing another memory model by compiler options. With the introduced bug compiled silently.   And even with the mostly tamed static_cast and flat memory models used today, I still feel unsafe with that necessary cast, that still introduces redundancy, an extraneous variable, and producing an alias that can be dereferenced.  The obligation to cast introduces a great deal of danger.

And what I gain on the other side? I can't remember a single case when the 'error: no math with void *' would catch a bug for me.

(see a few more points in Niklas Matthies' posts)

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: "Balog Pal" <pasa@lib.hu>
Date: Thu, 14 Jun 2001 18:06:15 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote in message news:3B27E13E.E671469D@acm.org...

> An object of type (void*) is not just an address in memory.
> Its type matters (as I'm sure you would agree) and C++ ties
> pointer arithmetic to that type in a consistent way right
> now.  An exception may have some justification, but the fact
> that it would be an exception weighs heavily against it.

In the case you build a theory on sand, more precisely, you claim that a mistake once made should be carried to the end.

The confusion is brought in by the fact void * is named as it is. Look at this:

T is a type.
T* is a poiner to type T.
void is NOTHING.
void * is NOT a pointer to void. It is a pointer to something, or a pointer to anything.

When it was created, it should have been named something like 'generic *' or 'any *'. But following the usual C++ keyword overload it was named void *. Well, 99% of the time it does not hurt, and we treat it correctly. But in the case the distinction must be made clear.

void * is a big special case in the language, and any compiler code dealing with pointers will treat it as an exception, everytime. So you don't need any extra justification to make it work differently.

And coming from the fact void * is not a pointer to type void at all (you can't really point to nothing, can you? :) it need not blindly follow the 'step should be equal sizeof(void)' rule either.

For the pointer math we expect that adding 1 will advance to the next element. For the regular pointer it is sizeof(T) bytes forward. For void * it was 1 byte forward in ALL cases I would ever use math on a void *, and honestly I can't think a sane program that would require any other step.

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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 14 Jun 2001 19:09:44 GMT
Raw View
In article <3b286bc0@andromeda.datanet.hu>, Balog Pal <pasa@lib.hu>
writes
>void * is NOT a pointer to void. It is a pointer to something, or a pointer to
>anything.

You are arguing very abstract issues. Certainly void as it was defined
in C for return types is a type, and incomplete one that may never be
completed. Therefore void* is a pointer to void. There is another use of
void in C (and continued for compatibility in C++) that means that there
are no parameters in a function declaration. This is needed in C because
it allows declaring a function name without specifying its parameter
list. That means that there has to be a special syntax to signify a
function that has no parameters. In C++ int foo() always means exactly
the same as int foo(void)

Please note that the concepts of any* and generic* are very different.
In C void* is equivalent to any* (hence a void* rvalue can be assigned
to any pointer to data type) and in C++ void* is equivalent to generic*
and so requires a cast to convert it to the type of the pointer it is
being assigned to.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: James Dennett <jdennett@acm.org>
Date: Thu, 14 Jun 2001 21:27:24 GMT
Raw View
Balog Pal wrote:
>
> "Scott" <scottm@toast.net> wrote in message news:38716.nw.scottm@toast.net...
>
> > >For usage that makes sense, but for the pointer math I'd fing much more
> > >convenient to make it work like unsigned char * does without a cast. When
> > >void * is used as raw memory pointer, it is practically a pointer to the
> > >machine byte. Thus the 'element size' for the pointer math operations should
> > >assume one byte units, instead of forbidding the math completely.
> >
> > It could, but it would be a special case then.
>
> (please see my other posts for the day too.)
>
> void * is already a special case, so I see nothing wrong with that, and knowing it is not really a pointer to void I'd not think to tie the step to sizeof(void) in any case. And actually it does not work that way, doing math for void * is forbidden (special case! :) as opposed to work with 0 step, or whatever number sizeof(void) happens to summon.
>

It's not a special case.  sizeof(void) isn't 0, it's undefined -- you
can't apply sizeof to an incomplete type.  void* is a pointer to void,
and template type deduction can use that fact.  You can't do pointer
arithmetic on void* for the same reason you can't do pointer
arithmetic on pointers to a "forward declared" struct type.
The difference is that the struct type can be completed, and
void cannot.

Your claim that it is not a "pointer to void" appears to contradict
the Standard, and the vernacular.  Can you back this claim up with
any evidence based on the Standard?

-- James Dennett

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Thu, 14 Jun 2001 22:49:14 GMT
Raw View
On Wed, 13 Jun 2001 22:13:38 GMT, James Dennett <jdennett@acm.org> wrote:
> Niklas Matthies wrote:
> > On Wed, 13 Jun 2001 01:11:40 GMT, James Dennett <jdennett@acm.org> wrote:
> > > Niklas Matthies wrote:
> > > > On Tue, 12 Jun 2001 21:06:54 GMT, Bjarne Stroustrup <bs@research.att.com> wrote:
> > > > > Balog Pal (mh)" <pasa@lib.hu> writes
> > > > > > Bjarne Stroustrup wrote in message ...
> > > > > >
> > > > > > >> One always ends up doing lots of casting to some flavour of char*.
> > > > > > >
> > > > > > >That's a feature, not a bug. The point is that it forces you to
> > > > > > >explicitly cast to some type. You cannot by mistake pass void*
> > > > > > >along and use it as a pointer to some type without thinking about
> > > > > > >what that type is.
> > > > >
> > > > > > For usage that makes sense, but for the pointer math I'd fing much
> > > > > > more convenient to make it work like unsigned char * does without a
> > > > > > cast. When void * is used as raw memory pointer, it is practically a
> > > > > > pointer to the machine byte. Thus the 'element size' for the pointer
> > > > > > math operations should assume one byte units, instead of forbidding
> > > > > > the math completely.
> > > > >
> > > > > For byte-sized units, cast to an appropriate char type. For word-sized
> > > > > units cast to an appropriate integral type, struct, or whatever, for
> > > > > Foo-sized units, cast to Foo*.
> > > > >
> > > > > In other words, I don't think you can assume that a byte is always the
> > > > > right unit for what's pointed to by a void*.
> > > >
> > > > It is, in the sense that a void* can point to any byte, hence
> > > > arithmetics naturally should use the same granularity.
> > >
> > > Consistency seems natural to me.  Arithmetic on pointers changes
> > > address by a specified multiple of the size of the pointee type.
> > > sizeof(void) isn't defined, as void is an incomplete type.  You
> > > cannot perform arithmetic on incomplete types; nice and consistent.
> > >
> > > gcc did (maybe still does) allow arithmetic on void* as if it
> > > was char*.  I disapprove -- this is another irregularity in a
> > > language which has too many already.
> > >
> > > When accessing bytes, C++ indicates that you should use either
> > > char* or unsigned char*, because C++ calls bytes chars (as did
> > > C before it).  Cast just once if you need to get to bytes.
> >
> > Apparently you did not read the remainder of my post.
>
> I can assure you that I read it in its entirety.  I do not dispute any
> of your claims.  gcc implements rules which I think you would find
> reasonable; pointer arithmetic on (void *) is permitted as if it was
> (char *), but it cannot be dereferenced (of course).
>
> An object of type (void*) is not just an address in memory. Its type
> matters (as I'm sure you would agree) and C++ ties pointer arithmetic
> to that type in a consistent way right now.

I don't agree that `void' is consistent with the rest of the type
system. It is an "incomplete type" only for purposes of simplifying the
wording in the standard. Void really is not a type because there is
nothing that it "types", i.e. no value or object. Incomplete types other
than void are not incomplete types in the sense that values or objects
referred to having this incomplete type don't have a complete type (they
do have one), but that the compiler, at the current position in the
translation unit, doesn't have all information about the type.

Nevertheless the incomplete type is meant to be a placeholder for the
actual, completed type; there are merely some operations that are not
possible due to lack of that information about the completed version of
the type. Void conceptually doesn't say anything like this. It doesn't
stand for any "real" type of any value or object. Rather, "void" is a
way to say that we don't have a type because we have no value and no
object. Usage of void as a function return type or in cast operators
should make this obvious.

There are no values of type void. But there are values of incomplete
types other than void, the value simply is inaccessible because the
compiler, at that point in the translation unit, lacks the necessary
information to create code that accesses it; but the value nevertheless
is there. A void pointer doesn't point to an object of size zero (as has
been suggested in this thread), it doesn't point to any specific object
at all, and particularly the "void" in "void*" doesn't type any value or
object, it doesn't even type any (legal) expression. It is merely an
artificial construct, as witnessed by all the special wording the
standard contains for it. So void already is and has always been a
special case.

A void* points to some memory location. It is only natural to want to
move to the next or previous memory location; and what would be a more
appropriate way of doing this than incrementing or decrementing the
pointer? This can actually be seen as being consistent with object
pointers, which point to some object, and where incrementing and
decrementing moves to the next or previous object.

I'm not saying that the current semantics of void* are inherently wrong
and the extension discussed here is inherently right. I'm merely arguing
that this extended view is no more inconsistent or special case than the
current one, and that there are real situations that call out for a type
corresponding to this extended void*.

Bjarne Stroustrup reasons that void* requires explicit casts because of
safety considerations. While I don't dispute this for dereferencing
void*, I don't see what would be so particularly unsafe about allowing
pointer arithmetics on void*. Moreover, the desire for a void* that is
enabled with pointer arithmetics did _in particular_ arise from wanting
safer and more readable, straightforward code, as I illustrated in my
earlier post.

-- Niklas Matthies

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 15 Jun 2001 16:27:39 GMT
Raw View
On this discussion on void & void* (which I haven't followed too closely),
I can give an input:

I have an idea of a type "byte" that stands for the underlying raw memory
management. Ideally, this should be an 8-bit type; not a C/C++ byte (the
latter which may vary with the compiler). This idea would perhaps fall
into the task of making systems and distributed programming easier in C++

As for the type "void", it corresponds in math to the "empty set". So if
there would be a runtime representation in C++, "void" could be treated as
any other type, and "void*" would be a pointer to a such empty object. In
fact I have experimented with such a runtime model. So there is nothing
strange in treating "void" as a type.

Returning to the idea of the "byte" type, one could go a step further by a
type "bit" that lines up the memory into a string bits. One would then
have to augment this with other types "byte", "word", etc, describing the
hardware architecture.

This approach would have the advantage of making the choice of low and
bits described in a machine independent manner. -- That is, if one
describes a binary object relatively the "bit" model, it becomes hardware
independent. One can then convert it to more hardware efficient structures
using the other types "byte", "word".

I do not know what the exact details of this kind of model might be.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Fri, 15 Jun 2001 19:15:51 GMT
Raw View
On Fri, 15 Jun 2001 16:27:39 GMT, Hans Aberg <remove.haberg@matematik.su.se> wrote:
> On this discussion on void & void* (which I haven't followed too closely),
> I can give an input:
>
> I have an idea of a type "byte" that stands for the underlying raw memory
> management. Ideally, this should be an 8-bit type; not a C/C++ byte (the
> latter which may vary with the compiler). This idea would perhaps fall
> into the task of making systems and distributed programming easier in C++

The discussion was (in large parts) about the desire for a pointer type
that allows pointer arithmetics, but doesn't allow dereferencing without
explicit conversion to an object pointer. A "byte" type wouldn't help
with this.

> As for the type "void", it corresponds in math to the "empty set". So if
> there would be a runtime representation in C++, "void" could be treated as
> any other type, and "void*" would be a pointer to a such empty object. In
> fact I have experimented with such a runtime model. So there is nothing
> strange in treating "void" as a type.

The standard says that type void has an empty set of values. In other
words, there are no values of type void. This is very different from an
empty object, which has one (and only one) possible value, namely the
empty value. This shouldn't be confused.

-- Niklas Matthies

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 15 Jun 2001 19:23:38 GMT
Raw View
In article <slrn9iftcs.1ru.news_comp.std.c++_expires-2001-09-01@nightrun
ner.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
2001-09-01@nmhq.net> writes
>Bjarne Stroustrup reasons that void* requires explicit casts because of
>safety considerations. While I don't dispute this for dereferencing
>void*, I don't see what would be so particularly unsafe about allowing
>pointer arithmetics on void*. Moreover, the desire for a void* that is
>enabled with pointer arithmetics did _in particular_ arise from wanting
>safer and more readable, straightforward code, as I illustrated in my
>earlier post.

If we view void* as being a pointer to raw memory (as, effectively, C
does) then it makes perfectly good sense to allow both addition and
subtraction applied to void* values.

However if we view void* as being a pointer to an object of unspecified
type (which is closer to the C++ view) then we should not allow
addition/subtraction to be applied.

The problem is that void* actually conceals two quite distinct ideas
with very different semantics. If only we stopped overloading keywords,
life would be so much simpler even if we had a bigger vocabulary (That
reminds me of a competition many years ago to design a human language
that had only seven words, one thing that was obvious to any
mathematician is that you did not need a word for 'yes' because 'no no'
would mean the same. And that reminds me of negative binary which does
not need negative/positive signs)

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Fri, 15 Jun 2001 21:17:31 GMT
Raw View
On Fri, 15 Jun 2001 19:23:38 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> In article <slrn9iftcs.1ru.news_comp.std.c++_expires-2001-09-01@nightrun
> ner.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
> 2001-09-01@nmhq.net> writes
> >Bjarne Stroustrup reasons that void* requires explicit casts because of
> >safety considerations. While I don't dispute this for dereferencing
> >void*, I don't see what would be so particularly unsafe about allowing
> >pointer arithmetics on void*. Moreover, the desire for a void* that is
> >enabled with pointer arithmetics did _in particular_ arise from wanting
> >safer and more readable, straightforward code, as I illustrated in my
> >earlier post.
>
> If we view void* as being a pointer to raw memory (as, effectively, C
> does) then it makes perfectly good sense to allow both addition and
> subtraction applied to void* values.
>
> However if we view void* as being a pointer to an object of unspecified
> type (which is closer to the C++ view) then we should not allow
> addition/subtraction to be applied.

I agree with this to some extent.

Note, however, that pointer arithmetics even on object pointers is not
necessarily sane. One could argue that, more often than not, an object
pointer just points to a single object and not into an array of objects,
hence pointer arithmetics doesn't make sense and is dangerous in this
common case.

There is (at least) a third view of a void*. One can view a void* as a
pointer that can point to objects of different types, but where at any
given time, it is well-defined at which specific object it points to --
it's just that the compiler can't know in the general case. And because
the compiler doesn't know, it is the programmer's responsibility to
choose the right amount when moving it, not unlike it is the
programmer's responsibility to make sure that an object pointer points
into an appropriate array when performing pointer arithmetics on it.

Who says when you have an object pointer T* t_ptr pointing at a T, that
there's a T as well at t_ptr + 1?
What if t_ptr is actually pointing in here?
                                        |
                                        V
                    struct STU { S s; T t; U u; };

Should t_ptr + 1 not more naturally result in a U* pointing at u?
Ah, but the compiler generally doesn't know; hence we rely on the
programmer to do the right thing. Doesn't it seem logical to do the same
thing for void*, where the type itself already implies that it is the
programmer's job and not the compiler's to know what it points to?

And considering the example above, why should the memory at t_ptr + 1
(or at t_ptr, even) be less considered "raw memory" than what a void*
happens to points to?

-- Niklas Matthies

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 15 Jun 2001 22:44:29 GMT
Raw View
In article
<slrn9iklp4.td7.news_comp.std.c++_expires-2001-09-01@ns.nmhq.net>,
news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies) wrote:
>The discussion was (in large parts) about the desire for a pointer type
>that allows pointer arithmetics, but doesn't allow dereferencing without
>explicit conversion to an object pointer. A "byte" type wouldn't help
>with this.

The byte* would then be a raw memory pointer, and it could be
dereferenced, but its dereferencing would be considered raw memory, and
not a type for use with other (non-raw-memory) operations. For other
conversions, one would have to use explicit conversions. One can then have
pointer arithemtic, just as well for other types "bit" and "word".

Or something. (Just an input.)

>> As for the type "void", it corresponds in math to the "empty set". So if
>> there would be a runtime representation in C++, "void" could be treated as
>> any other type, and "void*" would be a pointer to a such empty object. In
>> fact I have experimented with such a runtime model. So there is nothing
>> strange in treating "void" as a type.
>
>The standard says that type void has an empty set of values. In other
>words, there are no values of type void. This is very different from an
>empty object, which has one (and only one) possible value, namely the
>empty value. This shouldn't be confused.

Let's analyze this with an analogy: If one has integers in math, they are
members of the set Z or "integer". So in a computer, there are integer
objects, and they have type integer.

The empty set has no members. So in a computer, if there is a type "empty"
corresponding to the empty set, there are no empty objects.

However, there is a difference between math and a computer in that in a
computer there is a notion of causality, whereas in math, logical
expressions just exists.

So if one should compute an expression f(x) in a computer, it is really an
expression of causality: First get a reference to the object x, hand that
over to the function f, and then compute f(x).

So, with respect to the empty object, there is a difference in f(x), hand
over an empty x, or hand over nothing. In the former case, f should start
to compute as if there where no argument provided, but in the latter case,
f should not start to compute at all.

So in order to capture that semantic difference due to the causality
present in a computer, I decided that one can hand over an empty object as
an indication that something has been handed over. But what has been
handed over has no value: It is like f(x) always hands over a box x when a
computation is supposed to start, and in this case the box is empty. The
object handed over is just an expression of the causality, and not an
expression of a value. The model does not in itself require any specific
implementation, only that one has somehow has handed over an empty box.

So I think one has to think a bit more about that causality aspect in
order to resolve such issues. (But I did not follow the details of the
discussion at hand.)

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 16 Jun 2001 12:04:55 GMT
Raw View
In article <slrn9ikudt.m3q.news_comp.std.c++_expires-
2001-09-01@ns.nmhq.net>, Niklas Matthies <news_comp.std.c++_expires-
2001-09-01@nmhq.net> writes
>There is (at least) a third view of a void*. One can view a void* as a
>pointer that can point to objects of different types, but where at any
>given time, it is well-defined at which specific object it points to --
>it's just that the compiler can't know in the general case.

void * a_ptr = operator new(1000);

What object is it pointing to? Whichever way you cut it, neither C nor
C++ is consistent in its view of what void* is. C is more nearly so,
because it largely treats void* values as pointers to untyped memory.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Wed, 13 Jun 2001 21:43:06 GMT
Raw View
On Wed, 13 Jun 2001 01:11:40 GMT, James Dennett <jdennett@acm.org> wrote:
> Niklas Matthies wrote:
> > On Tue, 12 Jun 2001 21:06:54 GMT, Bjarne Stroustrup <bs@research.att.com> wrote:
> > > Balog Pal (mh)" <pasa@lib.hu> writes
> > > > Bjarne Stroustrup wrote in message ...
> > > >
> > > > >> One always ends up doing lots of casting to some flavour of char*.
> > > > >
> > > > >That's a feature, not a bug. The point is that it forces you to
> > > > >explicitly cast to some type. You cannot by mistake pass void*
> > > > >along and use it as a pointer to some type without thinking about
> > > > >what that type is.
> > >
> > > > For usage that makes sense, but for the pointer math I'd fing much
> > > > more convenient to make it work like unsigned char * does without a
> > > > cast. When void * is used as raw memory pointer, it is practically a
> > > > pointer to the machine byte. Thus the 'element size' for the pointer
> > > > math operations should assume one byte units, instead of forbidding
> > > > the math completely.
> > >
> > > For byte-sized units, cast to an appropriate char type. For word-sized
> > > units cast to an appropriate integral type, struct, or whatever, for
> > > Foo-sized units, cast to Foo*.
> > >
> > > In other words, I don't think you can assume that a byte is always the
> > > right unit for what's pointed to by a void*.
> >
> > It is, in the sense that a void* can point to any byte, hence
> > arithmetics naturally should use the same granularity.
>
> Consistency seems natural to me.  Arithmetic on pointers changes
> address by a specified multiple of the size of the pointee type.
> sizeof(void) isn't defined, as void is an incomplete type.  You
> cannot perform arithmetic on incomplete types; nice and consistent.
>
> gcc did (maybe still does) allow arithmetic on void* as if it
> was char*.  I disapprove -- this is another irregularity in a
> language which has too many already.
>
> When accessing bytes, C++ indicates that you should use either
> char* or unsigned char*, because C++ calls bytes chars (as did
> C before it).  Cast just once if you need to get to bytes.

Apparently you did not read the remainder of my post.

-- Niklas Matthies

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 13 Jun 2001 22:13:38 GMT
Raw View
Niklas Matthies wrote:
>
> On Wed, 13 Jun 2001 01:11:40 GMT, James Dennett <jdennett@acm.org> wrote:
> > Niklas Matthies wrote:
> > > On Tue, 12 Jun 2001 21:06:54 GMT, Bjarne Stroustrup <bs@research.att.com> wrote:
> > > > Balog Pal (mh)" <pasa@lib.hu> writes
> > > > > Bjarne Stroustrup wrote in message ...
> > > > >
> > > > > >> One always ends up doing lots of casting to some flavour of char*.
> > > > > >
> > > > > >That's a feature, not a bug. The point is that it forces you to
> > > > > >explicitly cast to some type. You cannot by mistake pass void*
> > > > > >along and use it as a pointer to some type without thinking about
> > > > > >what that type is.
> > > >
> > > > > For usage that makes sense, but for the pointer math I'd fing much
> > > > > more convenient to make it work like unsigned char * does without a
> > > > > cast. When void * is used as raw memory pointer, it is practically a
> > > > > pointer to the machine byte. Thus the 'element size' for the pointer
> > > > > math operations should assume one byte units, instead of forbidding
> > > > > the math completely.
> > > >
> > > > For byte-sized units, cast to an appropriate char type. For word-sized
> > > > units cast to an appropriate integral type, struct, or whatever, for
> > > > Foo-sized units, cast to Foo*.
> > > >
> > > > In other words, I don't think you can assume that a byte is always the
> > > > right unit for what's pointed to by a void*.
> > >
> > > It is, in the sense that a void* can point to any byte, hence
> > > arithmetics naturally should use the same granularity.
> >
> > Consistency seems natural to me.  Arithmetic on pointers changes
> > address by a specified multiple of the size of the pointee type.
> > sizeof(void) isn't defined, as void is an incomplete type.  You
> > cannot perform arithmetic on incomplete types; nice and consistent.
> >
> > gcc did (maybe still does) allow arithmetic on void* as if it
> > was char*.  I disapprove -- this is another irregularity in a
> > language which has too many already.
> >
> > When accessing bytes, C++ indicates that you should use either
> > char* or unsigned char*, because C++ calls bytes chars (as did
> > C before it).  Cast just once if you need to get to bytes.
>
> Apparently you did not read the remainder of my post.

I can assure you that I read it in its entirety.  I do not
dispute any of your claims.  gcc implements rules which I
think you would find reasonable; pointer arithmetic on
(void *) is permitted as if it was (char *), but it cannot
be dereferenced (of course).

An object of type (void*) is not just an address in memory.
Its type matters (as I'm sure you would agree) and C++ ties
pointer arithmetic to that type in a consistent way right
now.  An exception may have some justification, but the fact
that it would be an exception weighs heavily against it.

-- James Dennett

---
[ 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: "Balog Pal (mh)" <pasa@lib.hu>
Date: Tue, 12 Jun 2001 10:16:02 GMT
Raw View
Bjarne Stroustrup wrote in message ...

>> One always ends up doing lots of casting to some flavour of char*.
>
>That's a feature, not a bug. The point is that it forces you to explicitly
>cast to some type. You cannot by mistake pass void* along and use it as a
>pointer to some type without thinking about what that type is.


For usage that makes sense, but for the pointer math I'd fing much more
convenient to make it work like unsigned char * does without a cast. When
void * is used as raw memory pointer, it is practically a pointer to the
machine byte. Thus the 'element size' for the pointer math operations should
assume one byte units, instead of forbidding the math completely.

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: news_comp.std.c++_expires-2001-09-01@nmhq.net (Niklas Matthies)
Date: Tue, 12 Jun 2001 22:07:30 GMT
Raw View
On Tue, 12 Jun 2001 21:06:54 GMT, Bjarne Stroustrup <bs@research.att.com> wrote:
> Balog Pal (mh)" <pasa@lib.hu> writes
> > Bjarne Stroustrup wrote in message ...
> >
> > >> One always ends up doing lots of casting to some flavour of char*.
> > >
> > >That's a feature, not a bug. The point is that it forces you to
> > >explicitly cast to some type. You cannot by mistake pass void*
> > >along and use it as a pointer to some type without thinking about
> > >what that type is.
>
> > For usage that makes sense, but for the pointer math I'd fing much
> > more convenient to make it work like unsigned char * does without a
> > cast. When void * is used as raw memory pointer, it is practically a
> > pointer to the machine byte. Thus the 'element size' for the pointer
> > math operations should assume one byte units, instead of forbidding
> > the math completely.
>
> For byte-sized units, cast to an appropriate char type. For word-sized
> units cast to an appropriate integral type, struct, or whatever, for
> Foo-sized units, cast to Foo*.
>
> In other words, I don't think you can assume that a byte is always the
> right unit for what's pointed to by a void*.

It is, in the sense that a void* can point to any byte, hence
arithmetics naturally should use the same granularity. And for the
duration of having a void*, you are not interested in the type of the
object pointed to (oherwise you'd have chosen a pointer-to-type of the
object pointed to), so there is no "right unit" for that.

The usage Balog Pal refers to (I think) is where you want to use a
pointer just as you would use a byte array _index_: You want to perform
arithmetics on it, but you don't it to be able to dereference it on its
own. I.e. when you do "pointer walking" on binary data (read from a file
or whatever), you currently have to write something like:

   char *p = ...;
   p += some_computed_offset;
   T1 t1 = * (T1 *) p;
   p += some_other_computed_offset;
   T2 t2 = * (T2 *) p;
   p += yet_another_computed_offset;
   T3 t3 = * (T3 *) p;

This is unsafe in the sense that you are never interested in the char
value p points at, yet you could accidentally dereference it. When using
p, you are only interested in the memory position p points to, and don't
want to allow accesses to objects at that position without explicit
cast. Now void* allows you to denote such a position, but not to perform
arithmetics on it; and char* allows arithmetics on it, but also allows
accesses to the memory while you'd want the former without the latter.
So, in an attempt to play safe, you end up writing something like:

   void *p = ...;
   p = (void *) ((char *) p + some_computed_offset);
   T1 t1 = * (T1 *) p;
   p = (void *) ((char *) p + some_other_computed_offset);
   T2 t2 = * (T2 *) p;
   p = (void *) ((char *) p + yet_another_computed_offset);
   T3 t3 = * (T3 *) p;

or like:

   void *p = ...;
   size_t i = 0;
   i += some_computed_offset;
   T1 t1 = * (T1 *) ((char *) p + i);
   i += some_other_computed_offset;
   T2 t2 = * (T2 *) ((char *) p + i);
   i += yet_another_computed_offset;
   T3 t3 = * (T3 *) ((char *) p + i);

I guess this is the "lots of casting" Balog Pal was alluding to.
One would want to be able to write the first example above with void*
instead of char*, so that one can continue to perform arithmetics on the
pointer but be forced to cast it to an appropriate pointer type before
dereferencing.

Having written all this, it is of course possible to write a wrapper
class for void* that has the wanted properties (set aside that compilers
seem to have a harder time of optimizing the use of such class objects
compared with objects of some basic type); still the idea of having
provided void* with this functionality in the first place seems quite
reasonable; after all it is a pointer to any memory location, and the
basic addressable unit of memory _is_ a byte.

-- Niklas Matthies

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 13 Jun 2001 01:11:40 GMT
Raw View
Niklas Matthies wrote:
>
> On Tue, 12 Jun 2001 21:06:54 GMT, Bjarne Stroustrup <bs@research.att.com> wrote:
> > Balog Pal (mh)" <pasa@lib.hu> writes
> > > Bjarne Stroustrup wrote in message ...
> > >
> > > >> One always ends up doing lots of casting to some flavour of char*.
> > > >
> > > >That's a feature, not a bug. The point is that it forces you to
> > > >explicitly cast to some type. You cannot by mistake pass void*
> > > >along and use it as a pointer to some type without thinking about
> > > >what that type is.
> >
> > > For usage that makes sense, but for the pointer math I'd fing much
> > > more convenient to make it work like unsigned char * does without a
> > > cast. When void * is used as raw memory pointer, it is practically a
> > > pointer to the machine byte. Thus the 'element size' for the pointer
> > > math operations should assume one byte units, instead of forbidding
> > > the math completely.
> >
> > For byte-sized units, cast to an appropriate char type. For word-sized
> > units cast to an appropriate integral type, struct, or whatever, for
> > Foo-sized units, cast to Foo*.
> >
> > In other words, I don't think you can assume that a byte is always the
> > right unit for what's pointed to by a void*.
>
> It is, in the sense that a void* can point to any byte, hence
> arithmetics naturally should use the same granularity.

Consistency seems natural to me.  Arithmetic on pointers changes
address by a specified multiple of the size of the pointee type.
sizeof(void) isn't defined, as void is an incomplete type.  You
cannot perform arithmetic on incomplete types; nice and consistent.

gcc did (maybe still does) allow arithmetic on void* as if it
was char*.  I disapprove -- this is another irregularity in a
language which has too many already.

When accessing bytes, C++ indicates that you should use either
char* or unsigned char*, because C++ calls bytes chars (as did
C before it).  Cast just once if you need to get to bytes.

-- James Dennett

---
[ 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: scottm@toast.net (Scott)
Date: Wed, 13 Jun 2001 02:25:01 GMT
Raw View
In comp.std.c++, "Balog Pal (mh)" <pasa@lib.hu> wrote:

>For usage that makes sense, but for the pointer math I'd fing much more
>convenient to make it work like unsigned char * does without a cast. When
>void * is used as raw memory pointer, it is practically a pointer to the
>machine byte. Thus the 'element size' for the pointer math operations should
>assume one byte units, instead of forbidding the math completely.

It could, but it would be a special case then. Lots of compilers consider
void to be of size 0, which is accurate if you consider the number of
bytes moved by a return statement in a void function. To make void*
act like unsigned char* would require explaining to the compiler that
sometimes 0==1. Nobody likes that sort of thing in a compiler, compilers
are already deviant enough.

It's better just to cast to (unsigned char*) if you want machine bytes.
void* means "I don't know what's down there and I don't care".
unsigned char* means something else. Having them be different makes the
code self-documenting; it's easy to tell when the code is aware
of datatypes and when it isn't.

Next thing you know, you'll be asking that *(void*)x returns a byte, and
then where will you be? Putting unsigned char out of a job, that's where.

---
[ 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: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: Wed, 6 Jun 2001 21:29:55 GMT
Raw View
Bjarne Stroustrup <bs@research.att.com> wrote...
>
> In a language supporting low-level systems programming, something
> has to be able to refer to "raw memory", e.g. newly allocated
> memory, the result of a read from disc, etc. Before void*, C and
> C++ (and Unix) used char* to refer to such memory.

In my experience, void is inadequate for such low-level programming,
since you can't do arithmetic on void* pointers.

One always ends up doing lots of casting to some flavour of char*.

:(



---
[ 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: "Pavel Kuznetsov" <pavel_kuznetsov@no.spam.users.sourceforge.net>
Date: Tue, 5 Jun 2001 14:40:50 GMT
Raw View
> > would you wish to remove void*? ...

> Of course - it's a horribly un-typesafe concept.

ok, what would operator new()  return then?

--
Pavel Kuznetsov
mailto:pavel_kuznetsov@no.spam.users.sourceforge.net
remove "no.spam." from e-mail address


---
[ 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: "Balog Pal (mh)" <pasa@lib.hu>
Date: Tue, 5 Jun 2001 23:10:26 GMT
Raw View
>> > >> You mean you wanted a way to collect completely unrelated objects?
>> What could be a good reason for that?
>>
>The same good reason as having void*. Turning things
>around would you wish to remove void*?

No. I use void * time to time. A common use is to pass RAW memory around. I
write low level stuff, and at one end there are primitives that act on
blocks of arbitrary data, knowing nothing but size and address. void * is
perfect in that situation, taking any kind of stuff that has type at the
origin location. The importans thing here that no casting ever happens, and
the whole thing is safe.

I also use void * as "cookie". In some situations you must use a common
holder dor a piece of data reference, like in a message, or the dedicated
cookie holders like param for starting a thread, Itemdata field in a
listbox, listview, row, treeview item, etc. In that case the void * is cast
back to its original type, and what it is (well, what it supposed to be) is
given by the environment, the acceptor of the void *. After the cast
everything goes as normal. But I'd not call that a "polymorphic" behavior.

>As with other areas of
>C++ there are idioms that having a polymorphic void* would make
>possible. I am not precient enough to enumerate them but I don't
>rule them out either. Are they useful?

The usefullness comes from the only fact we have nothing better for those
situations. Wherever we have better tool  guess we use those. :-)

>I'd like to see RTTI implemented in 4 lines of code ;-).

Why, RTTI is mere 2 virtual functions. One that gets you a class identifier
(maybe an integes, enumerator, or a const char * to the class name as unique
string, or whatever) and another that retrieves the class' parent . Having
those two functions you can write every feature you can ask from RTTI.

With a little more effort you can add a pair of Create() and Clone()
functions, then you'll even have full support to implement polymorphic
containers and abstract factories. For the latter you need a Map of class
id's to Create() addresses, and there you are.


>I agree that
>there are other solutions either based on defining a common base class
>or a template envelope letter idiom with a virtual function.

Sure you need the base class with the virtual functions listed above.

>A good example here. What if you wanted to implement non-intrusive
persistence
>and wanted to be able to say commit() and rollback()? Note I don't mean the
>normal recursive tree traversal of MFC OWL etc.

Sorry I couln't decipher what you ask for, could you give a little more
description?

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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 4 Jun 2001 20:00:48 GMT
Raw View
Nick Thurn wrote:
>
> Balog Pal wrote:
> > "Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message news:KvPn34AGd8$6EwLL@ntlworld.com...
> >
> > > >> You mean you wanted a way to collect completely unrelated objects?
> > > >
> > > >Yes!
> >
> > What could be a good reason for that?
> >
> The same good reason as having void*. Turning things

The reason for void* in C++ is backwards compatibility with C. The
reason for having void* in C is the absence, in C, of polymorphic types
and generic programming constructs. I'm afraid I don't see those reasons
as applicable to this case, since C doesn't have container classes, and
C++ does have both polymorphic types and templates.

> around would you wish to remove void*? ...

Of course - it's a horribly un-typesafe concept.

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Tue, 5 Jun 2001 09:52:43 GMT
Raw View
James Kuyper Jr. wrote:
> Nick Thurn wrote:
> >
> > The same good reason as having void*. Turning things
>
> The reason for void* in C++ is backwards compatibility with C. The
> reason for having void* in C is the absence, in C, of polymorphic types
> and generic programming constructs. I'm afraid I don't see those reasons
> as applicable to this case, since C doesn't have container classes, and
> C++ does have both polymorphic types and templates.
>
> > around would you wish to remove void*? ...
>
> Of course - it's a horribly un-typesafe concept.
>
Since I'm in the habit of being dumb in public: didn't C get void* from
C++ way back in the early eighties? ;-)

cheers
Nick nick.thurn@db.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                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Sun, 3 Jun 2001 20:01:02 GMT
Raw View
"Hans Aberg" <remove.haberg@matematik.su.se> wrote in message news:remove.haberg-1405011715580001@du137-226.ppp.su-anst.tninet.se...

> Well, if there are so many cases, perhaps one can attempt layer the
> language: The highest level of the language would be required to not
> contain any "undefined" clauses. One should be able to program in it, and
> move to lower levels for reasons of optimization.

> With the example of the 0 pointer, one might introduce a high level 0
> pointer which throws an exception if somebody tries to access it
> dereferenced data.

I see no real reason for such layering at the language level. Everyone is allowed to write his own routine library, and then stick to use nothing other. Like for that pointer case a simple template like the auto_ptr could guard the pointer, and check for == 0 in operator *, throwing exception, or emailing your boss in a defined way.

Most undefied stuff is undefined for good reason: C++ is supposed to run on too many different platforms. And supporting a single defined behavior would make it impossible on some of those platforms, or invoke unwanted penalties for little gain. Also note, that something generally "undefined" may be quite well defined by the particular implementation.


> If one is pretty sure that the program does not need
> that, one should be able to replace it with the 0 pointer that does not
> throw an exception. This is way, it is possible to choose the
> safety/optimization trade-off.

Most class libraries do exactly that, and in more profound way. For debug build they're full of asserts checking arguments, state, consistency. Then all those asserts are gone in the release build.

> Much of the "undefined" seems to depend on the current hardware
> architecture, so one perhaps must wait for better CPU's before one can
> expect to remove them.

It's not that easy. Say a 80286 processor can very well trap on a 0 pointer in its protected mode, so a program running windows (3.0 standard mode :) or xenix, or its own protected environment can benefit on that. But another program for msdos, running in real mode will silently overwrite a few unused bytes in small model (with some luck having a "Null pointer assignment" warning message after the program exits) or overwrites the interrupt vector table in large model, most likely causing a freezeup. All on the same machine.

> On the other hand, no-one will develop in this
> respect better CPU's before one sets forth thinking on what is needed in
> order to remove those "undefined".

The processors claiming they support a multitask system, what is pretty widespread these days all have very good protection features, trapping all access to not owned memory, or executing illegal instructions. But even that  wil not undo undefinedness a bit. As a random illegal pointer can point anywhere. No memory protection system can figure out whether it is supposed to point where it does. It can be a good location from the CPU's and the opsystem's point of view, but still bad from the program's logic.

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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 3 Jun 2001 22:09:18 GMT
Raw View
In article <3b18dc11@andromeda.datanet.hu>, "Balog Pal" <pasa@lib.hu> wrote:
>> With the example of the 0 pointer, one might introduce a high level 0
>> pointer which throws an exception if somebody tries to access it
>> dereferenced data.
>
>I see no real reason for such layering at the language level. Everyone is
allowed to write his own routine library, and then stick to use nothing
other. Like for that pointer case a simple template like the auto_ptr
could guard the pointer, and check for == 0 in operator *, throwing
exception, or emailing your boss in a defined way.

Actually, there is a simple variation of the high level 0 pointer, when
making use of a polymorphic hierarchy:

One has a class "object" maintaining a polymorphic pointer to an object of
a class derived from a class "object_root":
  class object;

  class object_root { ... }

  class object {
    object_root data_;
  public:
    object(object_root* op = 0) : data_(op) {   }
  };

If one makes to maintain the class to maintain a reference to the object
pointed at by object::data_ (say by the use of  a ref count), then the 0
pointer object is simply:
  const object null;

Then whatever hardware support there is for 0 pointer checking, one way
for C++ to go would be to implement it so that it simplifies the writing
of such a class "object": With the variation above, one has to make a lot
of 0 pointer checking.

If there is no way for C++ to help simplify such practical programming
problems, there probably there is no point for C++ to support
implementations of hardware 0 pointer checking.

Such a class may eventually show up in the standard library -- the problem
is only that there are several variations of it. For example, one may put
in a class "handle" so that the objects in the hierarchy can self-mutate.

But if one has such a class "object", then one would expect it to be high
level -- throwing exceptions if refrences is addressed wrongly.

Then C++ already has been layered, even though it has been achieved by a
combination of (generally low level) language features and library
building. -- I think most expect that the C++ language proper will be only
augmented with certain hooks to so that high level programming features
can be built on top of that.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Sun, 3 Jun 2001 23:58:35 GMT
Raw View
Balog Pal wrote:
> "Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message news:KvPn34AGd8$6EwLL@ntlworld.com...
>
> > >> You mean you wanted a way to collect completely unrelated objects?
> > >
> > >Yes!
>
> What could be a good reason for that?
>
The same good reason as having void*. Turning things
around would you wish to remove void*? As with other areas of
C++ there are idioms that having a polymorphic void* would make
possible. I am not precient enough to enumerate them but I don't
rule them out either. Are they useful? I don't know. I do know
that I have wanted this functionality in the past (as part of
removing dependencies) and have had to work around it's absence.

> > >Currently you have to provide your own as with useful RTTI.
> > >These things are basic and should be standard IMO.
>
> Polymorphism != anarchy. The polymorph behavior is always backed up with some
> basic interface. And that is still better obtained by having a common base
> class wits a small set of virtual funcions. RTTI among them. Is it 3 lines
> of code to implement, or 4?
>
I'd like to see RTTI implemented in 4 lines of code ;-). I agree that
there are other solutions either based on defining a common base class
or a template envelope letter idiom with a virtual function.

> > I do not think that such collections are all that common.
>
> IMHO completely unrelated collections (that are usable for anything)
> are closer to nonexistent, and for real polymorphs I think one never
> get beyond 3 distinct ierarchies in any project. [I think I used an
> overall count of three in my 2 decades of programming, Borland's Object,
> MFC CObject and recently created my own to hold all kinds of database records. ]
>
A good example here. What if you wanted to implement non-intrusive persistence
and wanted to be able to say commit() and rollback()? Note I don't mean the
normal recursive tree traversal of MFC OWL etc.

cheers
Nick nick.thurn@db.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                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Sat, 2 Jun 2001 12:54:35 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message news:KvPn34AGd8$6EwLL@ntlworld.com...

> >> You mean you wanted a way to collect completely unrelated objects?
> >
> >Yes!

What could be a good reason for that?

> >Currently you have to provide your own as with useful RTTI.
> >These things are basic and should be standard IMO.

Polymorphism != anarchy. The polymorph behavior is always backed up with some basic interface. And that is still better obtained by having a common base class wits a small set of virtual funcions. RTTI among them. Is it 3 lines of code to implement, or 4?

Having templates you can go the other way around, say like the templated containers in MFC work, using template functions SerializeElements, CompareElements, etc, you have to explicitely specialize for all your classes. I found that extremely error prone.
And it is nothing like a polymorphism: you can't iterate your collection and call the appropriate function of each element that way, it only allows the templated class to work, using some uniform features of the argument actual type.

> I do not think that such collections are all that common.

IMHO completely unrelated collections (that are usable for anything) are closer to nonexistent, and for real polymorphs I think one never get beyond 3 distinct ierarchies in any project. [I think I used an overall count of three in my 2 decades of programming, Borland's Object, MFC CObject and recently created my own to hold all kinds of database records. ]

> The main
> motive for such things as monolithic inheritance from CObject was to
> provide containers in the days before templates were being supported. If
> you really need containers of objects of unrelated types it is easy
> enough (I think) to write a suitable smart pointer,

Having a collection of diverse pointers is really a no-brainer, but what will you do with them later? Suppose you have a pointer to vector<int> and another to a vector<double>, stored in some smart thing that collects vector<TYPE> pointers, and even provides you with RTTI.
 How you write a simple routine that sums the element count for all the contained vectors?

> but the need is rare
> enough, IMO,  to suggest that it is not something to spend precious
> Standards resources on doing.

That is definitely not a standard thing to do. Everyone knowing the concept of polymorphism can create his own base class best fitting the purpose without problems. C++ has every tool to that. Okey, one missing for a common problem, ctor order for cross-unit globals, but that is another story.

Paul

>
>
> Francis Glassborow      ACCU
> 64 Southfield Rd
> Oxford OX4 1PA          +44(0)1865 246490
> All opinions are mine and do not represent those of any organisation
>
> ---
> [ 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                ]
>

---
[ 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: Matthew Austern <austern@research.att.com>
Date: Thu, 24 May 2001 19:04:12 GMT
Raw View
bs@research.att.com (Bjarne Stroustrup) writes:

> Having seen this discussion, I thought I'd better post a brief summary of my
> thoughts. Please remember that these are my suggestions, not committee policy.

And I should follow up too.  This is mostly going to be about
committee policy, so, I'm afraid, some of it is going to be pretty
bureaucratic.  Sorry.  Some of it is interesting anyway.

The committee has just taken the first steps in thinking about a new
revision of the C++ standard: it voted to ask its parent organization,
SC22, for permission to write a "type 2 technical report" on
extensions to the standard library.

"Type 2" is bureaucratese.  It means that the material in the
technical report not be normative (people who write C++
implementations will not be required to include any of it), but that
it will be considered for inclusion in a future standard.

Why are we going through the route of a technical report, instead of
working on a new standard in the first place?  A few reasons.  I can't
guarantee that everyone on the committee voted on this for the same
reasons, but here are some of the reasons that I personally think it's
a good idea:
 - It's a faster process.  A new revision of the standard is a
   big deal, and will take longer than a simple technical report.
 - As Bjarne suggested, it's desirable to focus on library changes
   rather than core language changes, and that's particularly true
   at this moment.  There's always a delicate balance between
   stagnation and instability, and the balance point seems to be
   different for the core language and for the library.  It doesn't
   seem appropriate to be changing the core language just yet, when
   we don't yet have experience with a fully conforming compiler.
 - A technical report provides more scope for experimentation.  It
   will let us build existing practice, which can be standardized
   (perhaps in a modified form) later.

The committee hasn't started work on the technical report yet: we
haven't officially gotten a "work item" from our parent organization,
and we haven't yet established procedures and criteria.

I've written up a few notes about procedures and criteria:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1314.htm.  To
echo Bjarne's disclaimer: these are my thoughts, not committee policy.
In some cases they are suggestions or outlines of what committee
policy might be.  They are the starting point of a discussion.

Some specific points:
 - The committee will probably want to focus on specific areas.
   I've suggested a few possible areas; I'm sure that the exact
   list will change.
 - I believe that the committee should make this process as
   open as possible.  Most of the work will come from outside,
   if only because the committee does not have the time and
   expertise to do all of the development work itself.  Exactly
   what that means, we don't yet know.  Maybe there will be
   some arrangement with the moderators of this newsgroup (as
   the committee does with defect reports), or maybe there will
   be an arrangement with BOOST and/or other groups.
 - I believe that the committee should in general prefer
   proposals that give a detailed design (as opposed to a
   general suggestion) and that include a reference implementation.
   It's too easy to make conceptual mistakes if you don't work
   through the details; I know, anyway, that I'm not smart enough
   to see the full implications of a suggestion before I do that
   kind of work.

The committee will announce more details here when it knows them.  In
the mean time, it's time for everyone to start thinking about library
extensions that you'll like to see.

---
[ 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: comeau@panix.com (Greg Comeau)
Date: Thu, 24 May 2001 19:43:25 GMT
Raw View
In article <3B047711.AC54817F@wizard.net>,
James Kuyper Jr. <kuyper@wizard.net> wrote:
>I suspect that you're not really talking about a different syntax for
>function prototypes, that's been relatively unchanged since prototypes
>were first introduced by the C89 standard. What did change when C was
>first standardized was that function declarations used to have only a
>non-prototype syntax, and but the standard introduced function
>prototypes as an alternative way of doing function declarations.
>However, the old non-prototype syntax was never abandoned by C (though
>it has been abandoned by C++). If that's the change you're talking
>about, it was forced only by your need to change languages; within C
>itself, backwards compatibility has been maintained in this matter.
>That's not quite true - C99 has killed implicit int. However, there
>aren't any C99 implementations yet, so I doubt that you're referring to
>that change.

Comeau supports a slew of C99'isms, including banning implicit int.

>This actually illustrates my point; it's the failure to keep changes
>backward compatible that cost you all that porting work. You can blame
>predecessors with the same attitude you have for that work.
>
>I don't believe that backward compatibility should be treated as an
>absolute requirement that must always be honored; I'm just saying that
>the time scale for breaking backwards compatibility should be a lot
>longer than the 5-10 years you were suggesting.

I agree there should be some leeway, and so vendors should be
pretty flexible in their transition models and options possible
for user controlof this.  If they do that, the actual timeframe
is less important.
--
Greg Comeau                 Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==>         http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo!       NEW: Try out our C99 mode!
comeau@comeaucomputing.com  http://www.comeaucomputing.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                ]





Author: Boris Fomitchev <boris.NO-SPAM@stlport.com>
Date: Thu, 24 May 2001 18:19:26 CST
Raw View
Actually, buffer, as simple as it may seem to be, is an interesting and
nontrivial exercise:

Andrei Alexandrescu wrote:

> "Tim Sharrock" <tim@sharrock.org.uk> wrote in message
> news:2pejftc9mp58apol1ggd7f2idfblnc82kg@4ax.com...
>
>> I would like to be able to use standard containers optimised for space.
>>
>> std::vector::reserve, for example is specified in such a way that there
>> you can provide a minimum value for the capacity, but not a maximum.
>
>
> For optimization lovers, I think there is a container that's needed:
> buffer<T>. I know people who can't use vector because their performance
> needs are too demanding. An std::buffer<T>:
>
> * would provide a subset of vector's functions
>
> * would hold only the pointer and the size

How we are going to tell how many initialized entries are there ? Do we
assume all entries are initialized on buffer creation instead? May not
be good for non-POD types. What about types with no default constructor ?

The abstraction

>
> * would provide methods such as resize_nocopy, resize_noinit, and
> resize_nocopy_noinit, that allow precise control of allocatiio

>
> * would shrink when resized to a smaller size

That implicitly involve reallocation and copying cost. No single
platform provide a system primitive to lessen the size of allocation, so
the only way to implement this is to reallocate and copy (or move()).
This is very non-intuitive for resize() function IMHO. Name of function
should be resize_and_reallocate or shrink() then ... Shrinking is one
functionality people do miss in vector sometimes; however, it should
have a clear semantic so that people do not misuse it.


>
> Basically an std::buffer<T> is a dynamic buffer that allow the user fine
> control over what's going on. In particular, std::vector<T> would use a
> buffer as implementation. In addition, the vector would hold the effective
> size.

The idea of having a primitive simpler that vector which may be used as
a building block is definitely attractive. The idea of using such as
deque block is not also that crazy IMO. Another such a primitive would
be generic move() algorithm which is notoriously hard to get right,
especially when exceptions come to stage ...

-Boris.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 23 May 2001 15:06:50 GMT
Raw View
Eugene Karpachov wrote:
>=20
> Mon, 21 May 2001 18:49:30 GMT James Kuyper Jr. =CE=C1=D0=C9=D3=C1=CC:
> >Eugene Karpachov wrote:
> >>
> >> Wed, 16 May 2001 13:39:55 GMT James Kuyper Jr. wrote:
> >> >Elimination of undefined behavior would require that a C++
> >> >implementation emulate memory protection on platforms where it isn'=
t
> >> >provided by the hardware or operating system already. That can be a=
 very
> >> >significant cost.
> >>
> >> Is there at least one modern platform where hardware cannot determin=
e illegal
> >> memory access? If yes, is there at least one conforming implementati=
on of c++
> >> for this platform anyway?
> >
> >Hardware detection of illegal memory access is not the answer - it
> >typically causes uncontrolled termination of your program. That's
>=20
> Yes, why not to terminate it? Termination is exactly defined behaviour,=
 but
> "undefined behaviour" could be formatting of hard drive or something li=
ke.

Because what happens (or what can be made to happen) on termination
caused by hardware-detected illegal memory access is very different on
different platforms. On some platforms, the consequences can't be
controlled at all, except by adding extra instructions to every memory
access. On others, termination is built in at the hardware or OS level,
with no ability for the implementor to influence the form of the
termination it can be equivalent to abort(), or worse. On other
platforms, there's a way to trap the event, and treat it as a signal or
an exception - which raises problems if it gets triggered as a
consequence of excecuting the signal or exception handler. If the
standard defines what happens, then on some platforms it won't be
possible to match that definition. It doesn't really matter what that
definition is. Only by saying that it could be anything, does the
standard adequately cover the possibilities that can reasonably and
efficiently implemented on each platform.

> >should be? Also, explain why it's useful for that behavior to be
> >defined.
>=20
> Because it is safer to terminate improperly behaving program than to le=
t it
> proceed into unknown direction. In practice, termination is what does r=
eally
> happen; why not to standardize this *defined* and the safest behaviour?=
 May be
> something like "implementation-defined termination".

Because the kind of termination that is possible in this case on many
systems does not allow proper cleanup. That being the case, guaranteeing
that it happens would be no safer than saying "undefined behavior" -
failing to do the cleanup can often have arbitrarily bad consequences
anyway.

---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Wed, 23 May 2001 15:37:49 GMT
Raw View
Sat, 19 May 2001 18:47:21 GMT, Michael Lee Finney <michael.finney@acm.org=
> pisze:

>    2. Assume, for the moment that the extra overhead=20
> for the storage allocator is 8 bytes (and, here I am=20
> assuming 4 byte points and integers as "natural", but=20
> 64-bit machines would scale everything by 2). Require=20
> the compiler to place in that 8 bytes a) the number of=20
> allocated objects and b) a pointer to the _class=20
> object for the allocated object.

With these rules you can't find the _class object having a pointer
into the middle of an array, and thus you can't call virtual functions
on an object taken from an array.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 23 May 2001 17:59:00 GMT
Raw View
In article <3B0BA84E.5AE2D59@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:
>>>Elimination of undefined behavior [in case of illegal memory access]
would >>>require that a C++
>>>implementation emulate memory protection on platforms where it isn't
>>>provided by the hardware or operating system already.
...
>> ...why not to terminate it? Termination is exactly defined behaviour,=
>> but "undefined behaviour" could be formatting of hard drive or something li=
>ke.
>
>Because what happens (or what can be made to happen) on termination
>caused by hardware-detected illegal memory access is very different on
>different platforms. On some platforms, the consequences can't be
>controlled at all, except by adding extra instructions to every memory
>access. On others, termination is built in at the hardware or OS level,
>with no ability for the implementor to influence the form of the
>termination it can be equivalent to abort(), or worse. On other
>platforms, there's a way to trap the event, and treat it as a signal or
>an exception - which raises problems if it gets triggered as a
>consequence of excecuting the signal or exception handler.

I think there is no point making additions just in order to remove the
"undefined" from the C++ standard:

There must be an advantage in programmability for the user of the C++ compiler.

However, when this is possible, this need not happen on every platform. I
think that if a feature is available on more advanced platforms, and one
expects it to trickle down to less advanced computers in the future, then
it is prudent to add it conditionally: Some macro or variable will tell if
the feature is present.

Now to the illegal memory access feature:

There I think that if it is possible to on some platforms produce a C++
version that throws a C++ exception and make proper cleanup and/or
retrieve the program, then one should add this feature conditionally to
C++.

I have encountered an example where this might be useful: I made a
compiler plugin to an IDE (integrated development environment), in fact
Bison that naturally terminates by a C exit() call. Then the funny thing
happens that when this Bison plugin terminates, the whole IDE is picked
down as a program, because exit() refers to the whole program, not just
the plugin.

By contrast, if Bison instead would throw an exception "std::exit", then
it would be possible for the IDE to catch that exception and retrieve.

A similar situation happens with illegal memory access, even though the
problem is more serious here: Unless one knows in what ways the memory
space has been corrupted, it is not prudent to do anything but to
terminate the whole program and its memory allocation.

But let's concentrate on the general principle: If there are ways to make
a prudent termination with proper cleanup or perhaps even be able to
retrieve on some platforms, then one might add that as a feature to C++
conditionally.

Further, is now the new C++ version should support systems programming,
one might need to add some such features.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: jk@steel.orel.ru (Eugene Karpachov)
Date: Tue, 22 May 2001 20:28:19 GMT
Raw View
Mon, 21 May 2001 18:49:53 GMT James Kuyper Jr. wrote:
>Eugene Karpachov wrote:
>...
>> I'd say that any modern CPU with hardware memory management unit can catch
>> NULL pointer dereferencing (as to "current computer technology"). The ancient
>> hardware, like real-mode i86's, would suffer of course, - but why penalize
>> whole majority of current hardware in favor of obsolete CPU's? It is doubtless
>> that no conforming implementation for PC 8086 exists anyway.
>
>Well, there are no conforming implementations yet, period, so there's
>certainly not one for a "PC" (?) 8086.

I mean Intel 8086 based personal computers (PC), like IBM XT etc, those from
early 1980-s. These PC indeed cannot detect invalid memory access. Is there
any need to rely on them in C++0x?

--
jk

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Tue, 22 May 2001 20:31:10 GMT
Raw View
Nicola Musatti wrote:
>
> Christopher Eltschka wrote:
> [...]
> > Another idea: What, if - instead of a typeof operator - it
> > would be allowed to use an expression as template argument
> > where a type argument is expected, and it would be taken as
> > the type of the expression to be inserted here. Then typeof
> > could be implemented in terms of this. Advantage: no keyword.
> >
> > Example: typeof implementation
> >
> > template<class T>
> >  struct type_traits
> > {
> >   typedef T type;
> > };
> >
> > #define typeof(expr) type_traits<(expr)>::type
>
> Combining this idea with templated typedefs we get rid of the macro:
>
> template <typename T> typedef type_traits<T>::type typeof;

Great! So double advantage: No keyword _and_ no macro.
Only names which can be put to namespace std, therefore zero
impact to currently conforming programs.

Of course programs using current typeof extensions (like in g++)
would have to be rewritten (or to themselves define the macro
as a quick fix - they then can encode the behaviour of _their_
implementation into that macro, and therefore get portable
this way!)

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 23 May 2001 01:01:39 GMT
Raw View
Eugene Karpachov wrote:
>
> Mon, 21 May 2001 18:49:53 GMT James Kuyper Jr. wrote:
> >Eugene Karpachov wrote:
> >...
> >> I'd say that any modern CPU with hardware memory management unit can catch
> >> NULL pointer dereferencing (as to "current computer technology"). The ancient
> >> hardware, like real-mode i86's, would suffer of course, - but why penalize
> >> whole majority of current hardware in favor of obsolete CPU's? It is doubtless
> >> that no conforming implementation for PC 8086 exists anyway.
> >
> >Well, there are no conforming implementations yet, period, so there's
> >certainly not one for a "PC" (?) 8086.
>
> I mean Intel 8086 based personal computers (PC), like IBM XT etc, those from
> early 1980-s. These PC indeed cannot detect invalid memory access. Is there
> any need to rely on them in C++0x?

No, but there's no need to rule them out, either. One of C++'s
strengths, which it inherits from its C ancestry, is a standard that's
deliberately vague enough to allow implementation on almost any
platform. "undefined behavior" is one of the key tools for achieving
that goal. Any definition that the C++ standard chose for this behavior
will make it unimplementable, or only inefficiently implementable, on
many platforms. If that doesn't bother you, then Java is the language
you should be looking at, not C++. The Java standard isn't afraid of
forcing an implementation to support features it can only emulate
inefficiently.
There's room for both kinds of languages, and little point in trying to
make them too similar.

---
[ 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: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Wed, 23 May 2001 08:21:33 GMT
Raw View
In article <MPG.156f44f33894fa4f98973f@news.lynchburg.net>, Michael Lee Finney
says...
>
>In article <aoaN6.7579$6j3.630114@www.newsranger.com>,
>Michiel.Salters@cmg.nl says...
>> In article <9e31tk$oq6$1@news5.svr.pol.co.uk>, Steve Burt says...
>> >
>> >I don't know whether anyone else has mentioned this, but is it really
>> >necessary to have both delete *and* delete [] operators? My experience
>> >has been that this can be a source of bugs and occasional complication.
>> >Wouldn't just a plain delete suffice? (i.e. make delete and delete[] the
>> >same - no existing code would be broken).
>> >I'd guess this would require an extra byte (or perhaps just a  bit) to be
>> >allocated by new to tell it whether the thing is an array or not

>> Keeping that information also means keeping some information for new'ed
>> integers etc. When the compiler sees delete, it knows that it doesn't
>> need to to look any further. It can just set a one-bit flag in a bit
>> array. I.e. keep a pool of 33*N integers, with N integers for 32 flags
>> indicating which one is free. Whenever a simple delete is done on
>> 4 bytes of memory this flag is reset. new[] and delete[] typically are
>> more complex, keeping element counts etc. The compiler know to look for
>> that information when it sees delete[].
>>
>> In your proposal, you'd have to implement new/delete as one-element arrays.
>> This would cause (in my example) a 3200% increase in overhead for simple
>> objects. An improvement in memory use is possible, but this will in return
>> cause additional run-time overhead.

>Of course storage allocators have to provide a result
>with worst case alignment -- almost always more than 4
>bytes, usually 8 bytes. Thus there is available 8
>bytes before the new object (even if it is an int). So
>you could always store <repetition, size> before a new
>object with no additional cost. Then delete and delete
>[] would always work correctly.

Incorrect. There is no requirement for the overhead to be
allocated near the the new'ed object.

Imagine this implementation:

class __4BytePool {
const int itemsize=4;
unsigned char [31*itemsize] data;
unsigned long in_use;
public:
void *GetItem() {
for(int i=0; i<32; i++)
if ( ! ( in_use & (1<<i) ) )
return data+itemsize*i;
return 0;
}
void ReturnItem(void*ptr) {
in_use^= ( 1<<((ptr-data)/itemsize) );
}
};

It is a bit simplistic (no error handling), but it will
sub-allocate memory for 4-byte items. Memory is aligned,
and the overhead is 100/31 %. I make an assumption that
only one item is allocated at a time. With a merged
delete/delete[] such techniques fail.

Regards,
Michiel Salters

--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl

---
[ 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: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Wed, 23 May 2001 08:41:08 GMT
Raw View
In article <9e3fs4$dv$1@news6.svr.pol.co.uk>, Steve Burt says...
>
>
>"Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
>news:aoaN6.7579$6j3.630114@www.newsranger.com...
>> In article <9e31tk$oq6$1@news5.svr.pol.co.uk>, Steve Burt says...
>> >
>> >On the subject of possible language changes...
>> >
>> >I don't know whether anyone else has mentioned this, but is it really
>> >necessary to have both delete *and* delete [] operators? My experience
>> >has been that this can be a source of bugs and occasional complication.

>> The main reason is that new[] is not considered something to use
>> casually. std::vector<> is a better default choice, and it doesn't need
>> a delete[].
>>
>> >Wouldn't just a plain delete suffice? (i.e. make delete and delete[] the
>> >same - no existing code would be broken).
>> >I'd guess this would require an extra byte (or perhaps just a  bit) to be
>> >allocated by new to tell it whether the thing is an array or not. new
>> >already records the size. I'm sure the top bit of a 32-bit size could
>> >safely
>> >be used.
>>
>> Keeping that information also means keeping some information for new'ed
>> integers etc. When the compiler sees delete, it knows that it doesn't
>> need to to look any further. It can just set a one-bit flag in a bit
>> array. I.e. keep a pool of 33*N integers, with N integers for 32 flags
>> indicating which one is free. Whenever a simple delete is done on
>> 4 bytes of memory this flag is reset. new[] and delete[] typically are
>> more complex, keeping element counts etc. The compiler know to look for
>> that information when it sees delete[].
>>
>
>You've lost me. Why does it need to keep anything?
>If the size of the object is 4 bytes or less, it uses the method you
>describe. If it is bigger, it stores it on the heap somewhere with a size.
>Whether the object is a primitive type, or a small array (a char[3], for
>instance) makes no difference at all, does it? Allocating a 3 byte array can
>use the fast pool method, just like allocating an int. All the compiler
>needs to know is that the pool contains object of 'x' bytesor les, then
>set/clear single bit flags.

Unfortunately, that won't work. Consider

typedef char *char_ptr
char_ptr p[4];
p[0]=new char;
p[1]=new char[3];
p[2]=new char[7];
p[3]=new char[300];
delete p[0];
delete p[1];  // ???
delete p[2];  // ???
delete p[3];  // ???
With your proposal, delete would have to now how many elements to delete.
The size information it needs for case 3 must also be available in case 0
and 1. With the current scheme the overhead for case 1 might be a single
bit. The compiler can determine which pool it came from from the pointer
type. You don't know to which pool (4byte, 8 byte, ...) delete[] must
return its memory.

>I don't think so - the compiler uses the pool method for small things, heap
>for larger ones

And how does it distinguish between them?

>> The final, killer argument is that if you don't want to remember what
>> to use, you can replace all plain new's by new[1], and delete[]
>> everything. In that view the "normal" new is an optimization you can
>> take if you want, and you accept the consequences.

>Well, if memory management were implemented as I suggested above, this would
>make no difference at all.

It will. By using new instead of new[1], you take on the responsibility
of remembering that size yourself, and calling delete instead of delete[].
If you don't do so, the compiler must keep this information - and it
doesn't understand your program as well as you do. That takes memory at
run-time. When you design a program to use plain new, the only memory used
is yours :-)

Regards,
Michiel Salters

--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl

---
[ 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: Michael Rubenstein <mike@mrubenstein.com>
Date: Wed, 23 May 2001 09:18:32 GMT
Raw View
On Mon, 21 May 2001 07:47:21 CST, jk@steel.orel.ru (Eugene
Karpachov) wrote:

>Sun, 13 May 2001 11:47:30 GMT Hans Aberg wrote:
>>So then one may decide to say that the dereferencing of a zero pointer
>>should throw an exception or something in order to get rid of the
>>"undefined" -- but that may cause unacceptable runtime overheads, given
>>the current computer technology.
>
>I'd say that any modern CPU with hardware memory management unit can catch
>NULL pointer dereferencing (as to "current computer technology"). The ancient
>hardware, like real-mode i86's, would suffer of course, - but why penalize
>whole majority of current hardware in favor of obsolete CPU's? It is doubtless
>that no conforming implementation for PC 8086 exists anyway.
>
>>In the future, it may be feasible to throw an exception in such cases. But
>
>Not necessarily exception; may be 'program termination' is enough. Or may be
>exception - it is debatable.

However, even if the implementation can produce an interrupt for
null pointer dereferencing, it might take extra code.  Consider

 struct A
 {
   int a;
   int f() { return 0; }
   static int g() { return 0; }
 } *pa = 0;

 int i = 0 * pa->a;
 int j = pa->f();
 int k = pa->g();

In each of these cases the compiler can optimize away the
dereference if pa points to an object.  Would you require the
compiler to actually do the dereference so it can throw an
exception?

Silly examples?  They look strange in this code, but if one
considers what can happen when template functions and const int
are used I don't think they look so silly.
--
Michael M Rubenstein

---
[ 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: jk@steel.orel.ru (Eugene Karpachov)
Date: Wed, 23 May 2001 09:19:05 GMT
Raw View
Mon, 21 May 2001 18:49:30 GMT James Kuyper Jr. =CE=C1=D0=C9=D3=C1=CC:
>Eugene Karpachov wrote:
>>=20
>> Wed, 16 May 2001 13:39:55 GMT James Kuyper Jr. wrote:
>> >Elimination of undefined behavior would require that a C++
>> >implementation emulate memory protection on platforms where it isn't
>> >provided by the hardware or operating system already. That can be a v=
ery
>> >significant cost.
>>=20
>> Is there at least one modern platform where hardware cannot determine =
illegal
>> memory access? If yes, is there at least one conforming implementation=
 of c++
>> for this platform anyway?
>
>Hardware detection of illegal memory access is not the answer - it
>typically causes uncontrolled termination of your program. That's

Yes, why not to terminate it? Termination is exactly defined behaviour, b=
ut
"undefined behaviour" could be formatting of hard drive or something like.

>should be? Also, explain why it's useful for that behavior to be
>defined.

Because it is safer to terminate improperly behaving program than to let =
it
proceed into unknown direction. In practice, termination is what does rea=
lly
happen; why not to standardize this *defined* and the safest behaviour? M=
ay be
something like "implementation-defined termination".

Disclaimer: it is not deeply thought; just brain-storming.

--=20
jk

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 23 May 2001 09:19:46 GMT
Raw View
"James Kuyper Jr." <kuyper@wizard.net> wrote in message
news:3B091C39.57D9ADCF@wizard.net...
> Eugene Karpachov wrote:
> ...
> > I'd say that any modern CPU with hardware memory management unit can
catch
> > NULL pointer dereferencing (as to "current computer technology"). The
ancient
> > hardware, like real-mode i86's, would suffer of course, - but why
penalize
> > whole majority of current hardware in favor of obsolete CPU's? It is
doubtless
> > that no conforming implementation for PC 8086 exists anyway.
>
> Well, there are no conforming implementations yet, period, so there's
> certainly not one for a "PC" (?) 8086.
>
> Secondly, who's penalized? Undefined behavior includes the possibility
> of throwing an exception. On platforms where it can be caught, that's a
> perfectly legal way of handling it.
>
> ...
> > Not necessarily exception; may be 'program termination' is enough. Or
may be
> > exception - it is debatable.
>
> Which is precisely why undefined behavior is the best choice; it allows
> either of those, and other possibilities as well.


Maybe "implementation defined" is better than "undefined" - at least you can
then rely on a particular result for your chosen platform, rather than
hoping it works as it did last time. Maybe permit implementations to define
it as undefined behaviour ;)

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 23 May 2001 09:25:04 GMT
Raw View
Al Grant wrote:
>
> "Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
> news:hH9tdQAx8kA7EwR9@ntlworld.com...
> > These days, keywords such as 'auto', 'register' and increasingly
> > 'inline' are also superfluous to requirements.
>
> A very useful meaning of 'register', which fits with an
> intuitive physical reality, though not compatible with
> the current language, would be to mean that the address
> of the variable is never leaked.  I.e.
>
>   void g(int &);
>   int h();
>
>   int f()
>   {
>     register int x; int y;
>     ...
>     g(x);      // x spilled
>     ...
>     y = h();   // No need to spill x here
>   }
>
> Without 'register', the compiler is forced to spill x at
> function calls on paths leading from the original
> address-taking, in case g and h turn out to be
>
>   int *global_ptr;
>   void g(int &p) { global_ptr = &p; }
>   int h() { return *global_ptr; }

But the variable declaration is the wrong place to say this.
It doesn't allow the compiler to check it (because only while
compiling the function g(int&), the compiler knows if the
variable is really leaked), and it allows the programmer to
accidentally introduce obscure bugs (f.ex. he could _later_
change g(int&) to leak - maybe the programmer of g doesn't
even know that anyone relies the non-leaking feature).

Moreover, the optimization would be quite limited:

void non_leaking(int&);
void leaking(int&);
void h();

void foo()
{
  int x; // will be passed to leaking later,
         // so cannot be declared non-leaked
  non_leaking(x); // x spilled
  ...
  h();            // no need to spill, but the compiler doesn't know
  ...
  leaking(x);     // x spilled
  ...
  h();            // x must be spilled
}

To allow the compiler optimizing that, one would need to tell
at the _argument_, say:

void non_leaking(int transient&);
void leaking(int&)
void h();

void foo()
{
  int x; // no need to declare x transient!
  non_leaking(x); // x spilled; the compiler knows the address isn't
leaked
  ...
  h();            // x not spilled
  ...
  leaking(x);     // x spilled, may leak
  ...
  h();            // x spilled
}

Also, now the compiler knows _in the function_ that the argument
is not allowed to leak, and can check it (by not allowing to
take the address, and only allowing to bind to transient
references). For example, the following would be flagged as error:

void non_leaking(int transient& i)
{
  leaking(i);
     // error: transient object bound to non-transient reference
}

To make the protection complete, transient references would not
be allowed as class members.

Instead of disallowing taking the address of transient references,
one could also define pointers to transient (int transient*), and
add the rule that pointers to transient may only be assigned to
other such pointers which are defined in the same scope, or in a
sub-scope of that scope, or be used to initialize a new pointer
to transient (so the destination pointer vanishes before the
source pointer does). Of course, pointers to transient would be
disallowed from being class members, too, also it would not be
allowed to allocate them with new.

---
[ 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: "Steve Burt" <steve.burt@cursor-system.com>
Date: Wed, 23 May 2001 13:45:01 GMT
Raw View
"Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
news:r6KO6.4548$r4.273189@www.newsranger.com...
> In article <9e3fs4$dv$1@news6.svr.pol.co.uk>, Steve Burt says...
> >
> >
> >"Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
> >news:aoaN6.7579$6j3.630114@www.newsranger.com...
> >> In article <9e31tk$oq6$1@news5.svr.pol.co.uk>, Steve Burt says...
> >> >
> >> >On the subject of possible language changes...
> >> >
> >> >I don't know whether anyone else has mentioned this, but is it really
> >> >necessary to have both delete *and* delete [] operators? My experience
> >> >has been that this can be a source of bugs and occasional
complication.
>
> >> The main reason is that new[] is not considered something to use
> >> casually. std::vector<> is a better default choice, and it doesn't need
> >> a delete[].
> >>
> >> >Wouldn't just a plain delete suffice? (i.e. make delete and delete[]
the
> >> >same - no existing code would be broken).
> >> >I'd guess this would require an extra byte (or perhaps just a  bit) to
be
> >> >allocated by new to tell it whether the thing is an array or not. new
> >> >already records the size. I'm sure the top bit of a 32-bit size could
> >> >safely
> >> >be used.
> >>
> >> Keeping that information also means keeping some information for new'ed
> >> integers etc. When the compiler sees delete, it knows that it doesn't
> >> need to to look any further. It can just set a one-bit flag in a bit
> >> array. I.e. keep a pool of 33*N integers, with N integers for 32 flags
> >> indicating which one is free. Whenever a simple delete is done on
> >> 4 bytes of memory this flag is reset. new[] and delete[] typically are
> >> more complex, keeping element counts etc. The compiler know to look for
> >> that information when it sees delete[].
> >>
> >
> >You've lost me. Why does it need to keep anything?
> >If the size of the object is 4 bytes or less, it uses the method you
> >describe. If it is bigger, it stores it on the heap somewhere with a
size.
> >Whether the object is a primitive type, or a small array (a char[3], for
> >instance) makes no difference at all, does it? Allocating a 3 byte array
can
> >use the fast pool method, just like allocating an int. All the compiler
> >needs to know is that the pool contains object of 'x' bytesor les, then
> >set/clear single bit flags.
>
> Unfortunately, that won't work. Consider
>
> typedef char *char_ptr
> char_ptr p[4];
> p[0]=new char;
> p[1]=new char[3];
> p[2]=new char[7];
> p[3]=new char[300];
> delete p[0];
> delete p[1];  // ???
> delete p[2];  // ???
> delete p[3];  // ???
> With your proposal, delete would have to now how many elements to delete.
> The size information it needs for case 3 must also be available in case 0
> and 1. With the current scheme the overhead for case 1 might be a single
> bit. The compiler can determine which pool it came from from the pointer
> type. You don't know to which pool (4byte, 8 byte, ...) delete[] must
> return its memory.

Oh, yes I do, and without storing size information, either.
Assuming that the pool resides in a block of contiguous memory, I can simply
check the pointer address to see whether it is part of the pool. Assuming
the pool is done as an object of some sort, I say:
if (pool.isInPool (pointer))
    pool.delete(pointer);
else
    free (pointer);

Since it's hard to imagine a pool system which doesn't use blocks of
contiguous memory, this seems perfectly OK.
>
> >I don't think so - the compiler uses the pool method for small things,
heap
> >for larger ones
>
> And how does it distinguish between them?

By the value of the pointer....



---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 23 May 2001 13:45:36 GMT
Raw View
In article <3B0AFA47.90671AF1@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:
>> I'd say that any modern CPU with hardware memory management unit can catch
>> NULL pointer dereferencing (as to "current computer technology"). The ancient
>> hardware, like real-mode i86's, would suffer of course, - but why penalize
>> whole majority of current hardware in favor of obsolete CPU's? It is
>> doubtless that no conforming implementation for PC 8086 exists anyway.
...
>> I mean Intel 8086 based personal computers (PC), like IBM XT etc, those from
>> early 1980-s. These PC indeed cannot detect invalid memory access. Is there
>> any need to rely on them in C++0x?
>
>No, but there's no need to rule them out, either. One of C++'s
>strengths, which it inherits from its C ancestry, is a standard that's
>deliberately vague enough to allow implementation on almost any
>platform. "undefined behavior" is one of the key tools for achieving
>that goal. Any definition that the C++ standard chose for this behavior
>will make it unimplementable, or only inefficiently implementable, on
>many platforms.

There is the alternative to conditionally include this or any such
feature: There is a macro or a variable that one check for the
availability of the feature and how it is implemented.

The C++ standard already contains such portions, for example, the
availability of quiet and signaling NaN's in the <limits> header.

So if other CPU low level features start to become available, one can make
it possible to detect in C++ when those features are available.

In addition, I think there should be good way to use them from C++.

> If that doesn't bother you, then Java is the language
>you should be looking at, not C++. The Java standard isn't afraid of
>forcing an implementation to support features it can only emulate
>inefficiently.
>There's room for both kinds of languages, and little point in trying to
>make them too similar.

Perhaps C++ should add the parts necessary to make a extern "Java"
directive be portable whenever available.

It is possible to use Java and C++ together, but it fragile and depends
heavily on the C++ compiler. See "Integrating C++ and Java",
  http://www.jovial.com/~billf/javaAndCpp/java_and_cpp.html

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Sat, 19 May 2001 18:46:39 GMT
Raw View
In article <aoaN6.7579$6j3.630114@www.newsranger.com>,
Michiel.Salters@cmg.nl says...
> In article <9e31tk$oq6$1@news5.svr.pol.co.uk>, Steve Burt says...
> >
> >On the subject of possible language changes...
> >
> >I don't know whether anyone else has mentioned this, but is it really
> >necessary to have both delete *and* delete [] operators? My experience
> >has been that this can be a source of bugs and occasional complication.
>
> Well, it has been recently discussed. The summary then was: " After
> discussing this subject 17E34 times, we still don't like it." So the
> summary now probably will be "After disucssing this 17E34 +1 times,
> we still don't like it."
>
> The main reason is that new[] is not considered something to use
> casually. std::vector<> is a better default choice, and it doesn't need
> a delete[].
>
> >Wouldn't just a plain delete suffice? (i.e. make delete and delete[] the
> >same - no existing code would be broken).
> >I'd guess this would require an extra byte (or perhaps just a  bit) to be
> >allocated by new to tell it whether the thing is an array or not. new
> >already records the size. I'm sure the top bit of a 32-bit size could safely
> >be used.
>
> Keeping that information also means keeping some information for new'ed
> integers etc. When the compiler sees delete, it knows that it doesn't
> need to to look any further. It can just set a one-bit flag in a bit
> array. I.e. keep a pool of 33*N integers, with N integers for 32 flags
> indicating which one is free. Whenever a simple delete is done on
> 4 bytes of memory this flag is reset. new[] and delete[] typically are
> more complex, keeping element counts etc. The compiler know to look for
> that information when it sees delete[].
>
> In your proposal, you'd have to implement new/delete as one-element arrays.
> This would cause (in my example) a 3200% increase in overhead for simple
> objects. An improvement in memory use is possible, but this will in return
> cause additional run-time overhead.
>
> The final, killer argument is that if you don't want to remember what
> to use, you can replace all plain new's by new[1], and delete[]
> everything. In that view the "normal" new is an optimization you can
> take if you want, and you accept the consequences.

Of course storage allocators have to provide a result
with worst case alignment -- almost always more than 4
bytes, usually 8 bytes. Thus there is available 8
bytes before the new object (even if it is an int). So
you could always store <repetition, size> before a new
object with no additional cost. Then delete and delete
[] would always work correctly.

Further, the argument that std::vector<> is nonsense
because many classes have to implement that sort of
thing and there are many cases where std::vector<> is
not the best solution. And beyond that, the C++
standard should not attempt to force one style of C++
coding over another.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Sat, 19 May 2001 18:47:21 GMT
Raw View
Here are some suggestions which I believe would be
beneficial to the C++ langauge without any cost that I
can see.

Consider that instances of C++ virtual classes require
some way to dispatching virtual function calls. This
is always implemented (so far as I know) as a vptr
table with only a few actual variants.

Also consider that the storage allocator
malloc/new/new[] must return allocated storage aligned
on a boundary suitable for any data element, and at
the same time must be able to free/delete/delete[] the
allocated storage without the user informing the run
time system of either the length of the allocated
objects or their number (in the case of new[]/delete
[]). In order to accomplish this, the allocator
generally allocates a block of length N+k, where k is
header used by the allocator. But, because of the
alignment constraints, k is usually at least 8 (it is
16 for the IBM VisualAge C++ 4.0 compiler). Allocators
are possible which don't use this scheme, but
generally they aren't used. And the overhead exists
somewhere unless extremely complex algorithms are
used.

Finally consider that most true OO languages (and yes
I know C++ isn't "just" an OO) language) always
allocate a "header" before a freshly allocated object.

I propose that the standard be a bit more explicit in
this matter as follows...

   1. Every object, including primitive data types,
will have a _class structure which contains at least
a) The length of the object, including the vptr or
equivalent and padding and b) the normal vptr array.
Naturally, a _class object itself has a _class object
which in turn points to itself.

   2. Assume, for the moment that the extra overhead
for the storage allocator is 8 bytes (and, here I am
assuming 4 byte points and integers as "natural", but
64-bit machines would scale everything by 2). Require
the compiler to place in that 8 bytes a) the number of
allocated objects and b) a pointer to the _class
object for the allocated object.

   3. Let the storage allocator use the stored
repetition count and the pointer to obtain the total
length of allocated storage.

This means that the distinction between delete and
delete[] is obsolete.

   4. Let use of the _class pointer replace the use of
the current vptr.

This reduces the size of allocated objects by 4 bytes
each. Note that a _class object, but not the
repetition could would be required for any embedded
object (such as on the stack, a base class or an
object contained in another class).

Also assume that the pointer to the allocated object
points immediately past the _class pointer is -4 from
the pointer and the repetition count is -8 from the
pointer (architectures which don't allow negative
indexing from a pointer already have to offset the
pointer by the length of the storage header or do
extra arithmetic on it -- so using negative offsets
doesn't seem to be a problem to me).

Finally, provide a mechanism for the user to obtain
the dynamic length of an object from the _class
object, either by publicly defining it, or by
providing a non-virtual function _size() which is not
available for non-virtual objects (except the first or
only one allocated by new/new[]).

This allows an extremely low overhead of array bound
checking (implemented by a user or library class such
as Array) which can provide safe array accessing.

The definitions

   #define alloc(N) ((void *)(new char[N]);
   #define free(p) delete(p)

which would provide the existing semantics for
alloc/free. A bit more is needed for realloc, but not
much...

   void * realloc(p, N)
      {
      if (N <= _count(p)}
            return p;
         else
            {
            void * q = new[N * _size(p)]
            memcpy(q, p, _size(p));
            return q;
            }
      }

Allocation on the stack isn't affected.

As far as I can see, the only cost here is negative --
the average size of allocated objects has been reduced
by 4 (or one pointer). The benefits are that the user
can dynamically determine the size of any virtual
object and can dynamically determine the count and
size for any allocation. This makes very low cost safe
arrays possible -- it even makes low cost
multidimensional arrays possible if they are built
with templates for the dimensions so that they can be
allocated and passed around with their dimensions
intact. It also improves reflection in the language,
the _class object could be the same object returned
via RTTI, but is clearly described. A final benefit is
the _class object can contain descriptions of all
pointers in the class, so that if the vendor (or user)
is implementing garbage collection then the basic
tools for following the graph of allocated objects are
built into the language. Finally, a simple virtual
object which contains only one vptr -- especially when
only single inheritance has been used -- has a pointer
past the _class object and so the object can be passed
out of C++ to the operating system or other libraries.
This can be especially beneficial when using C++ to
encapsulate older libraries.

Depending on the implement or's goals, splitting the
_class object into several objects which are identical
except for some flags might provide some
implementation benefit, but I don't necessarily
suggest or recommend that.

However, I don't see any downside to doing this in the
standard. It does constrain implement ors a bit, but
it doesn't really affect much in practice except to
pin down a bit of the OO overhead and reduce the
dynamic storage overhead. And, so far as I know, a
compiler constructed this way would adhere to the
current standard so it wouldn't break any code.

---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Sat, 19 May 2001 18:48:18 GMT
Raw View
"Andrew R. Thomas-Cramer" <artc@prism-cs.com> wrote in message
news:3af9a386$0$18890$272ea4a1@news.execpc.com...
> * finally blocks
>     I spent several hours yesterday, in a particular block of code, trying
> either to find a way to use resource-acquisition-is-initialization for an
> ad-hoc cleanup in a way that would not result in obfuscated code, or a way
> to avoid RAII. The finally block would have been clear and simple, a
single
> line of code. In the end, for simplicity, I wrote redundant code -- which
I
> despise -- one line in a catch(...), and a mirror of it below the
try/catch.
>   I don't need ad hoc cleanup very often, but when I do, defining ad hoc
> classes inside a function is messy and less readable than a simple finally
> block.

I agree, but finally is equally awkward. The form I believe would be most
helpful is:

void Fun()
{
    statements
    on_block_exit
    {
        statements
    }
    statements
}

The on_block_exit keyword allows you to define at arbitrary points inside a
block, statements that will be executed when that block is exited. For
example:

void Fun()
{
    FILE* f = fopen(...);
    if (!f) throw_error();
    on_block_exit fclose(f);
    ... use f ...
}

The point is that you can arrange the on_block_exit statements so that they
group naturally with the operations they counterpart.

The other useful keyword would be on_exception. Code in an on_exception
block shall execute only if the block is exited via an exception.

Using these blocks, it's very easy to write exception-safe programs without
having to resort to try/catch blocks or lots of little RAII classes.

> * switch on any type supporting operator=
>   Perhaps this is merely syntatic sugar, but I'd find it more convenient,
> particularly when switching on strings. I don't do this very often, but
when
> I do, I'd appreciate not being forced into redundancy.

I didn't understand this one, could you please detail?


Andrei


---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Sat, 19 May 2001 18:50:39 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.156f4f3e2ef95242989741@news.lynchburg.net...
[snip]
> Bottom line, the preprocessor really does play a role
> in C++ programming.

I agree.

> Other (simpler) examples are...
[snip]

Frankly, I didn't like any of your examples. They are really minor syntactic
fixes, at a price in understandability, header dependency, and
comprehensibility of error messages.

The problem is not that the concept of macros is bad. Macros are wonderful
because they operate on source code, which is inherently higher level, as
opposed to regular code writing which operates at runtime to solve the
problem. Macros are programs that make programs. (Templates kinda do a
similar thing.)

A very interesting article on a related subject can be found at
http://www.paulgraham.com/lib/paulgraham/pgtalk-rev2.pdf.

The problem lies with C++'s macro preprocessor. It just happens that it's a
pretty badly designed preprocessor that doesn't allow you to do anything
interesting. It's not even Turing complete. Its grammar is different from,
and incompatible with, C++'s grammar, a major source of annoyance for all
tool writers. I recall I gathered my courage like four times to write a tool
for C++ code manipulation, and each time I got discouraged because of the
stinkin' preprocessor.

It's clear that the preprocessor is here to stay because it does things C++
can't do. In my dreams I hope C++ would develop parallel facilities within
the language that would have the preprocessor fall into obsolescence.


Andrei


---
[ 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: Tim Sharrock <tim@sharrock.org.uk>
Date: Sun, 20 May 2001 22:27:49 GMT
Raw View
On Wed, 16 May 2001 20:15:39 GMT, "Andrei Alexandrescu"
<andrewalex@hotmail.com> wrote:

>"Tim Sharrock" <tim@sharrock.org.uk> wrote in message
>news:2pejftc9mp58apol1ggd7f2idfblnc82kg@4ax.com...
>> I would like to be able to use standard containers optimised for space.
>>
>> std::vector::reserve, for example is specified in such a way that there
>> you can provide a minimum value for the capacity, but not a maximum.
>
>For optimization lovers, I think there is a container that's needed:
>buffer<T>. I know people who can't use vector because their performance
>needs are too demanding. An std::buffer<T>:
>
>* would provide a subset of vector's functions
>
>* would hold only the pointer and the size
>
>* would provide methods such as resize_nocopy, resize_noinit, and
>resize_nocopy_noinit, that allow precise control of allocation
>
>* would shrink when resized to a smaller size
>
>Basically an std::buffer<T> is a dynamic buffer that allow the user fine
>control over what's going on. In particular, std::vector<T> would use a
>buffer as implementation. In addition, the vector would hold the effective
>size.

Yes, that would suit me fine - particularly if you can get access
to the underlying std::buffer<T> on those occasions when you want to.
(I can imagine some issues with that though - what if you resized
the std::buffer<T> to smaller than the std::vector<T>::size() - how
could the vector know without extra run-time costs? Exposing
std::buffer<T>s used as pages in a std::deque<T> offer even more
possibilities for inconsistency...)

Tim

--
Tim Sharrock   (tim@sharrock.org.uk)

---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Mon, 21 May 2001 00:30:29 GMT
Raw View
"Tim Sharrock" <tim@sharrock.org.uk> wrote in message
news:oagggtoh9hoh5mlkp117flac6uci7l60hd@4ax.com...
> On Wed, 16 May 2001 20:15:39 GMT, "Andrei Alexandrescu"
> <andrewalex@hotmail.com> wrote:
[about buffer]
> Yes, that would suit me fine - particularly if you can get access
> to the underlying std::buffer<T> on those occasions when you want to.
> (I can imagine some issues with that though - what if you resized
> the std::buffer<T> to smaller than the std::vector<T>::size() - how
> could the vector know without extra run-time costs? Exposing
> std::buffer<T>s used as pages in a std::deque<T> offer even more
> possibilities for inconsistency...)

I didn't think of exposing the buffer from vector or deque. You either use
buffer or the higher-level abstractions.

By the way, I started implementing buffer. It's very interesting how the
interface turns out when you struggle to maintain maximum efficiency while
being exception-safe and generic. What's most interesting is that there are
not many degrees of liberty you have; there is only one good way of doing
each thing (resizing etc.) Which is cool because you can clearly justify
every decision. I hate when I have to choose between two equally attractive
options :o).

Andrei


---
[ 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: comeau@panix.com (Greg Comeau)
Date: Sun, 20 May 2001 23:46:59 CST
Raw View
In article <slrn.pl.9fs99h.hsq.qrczak@qrnik.zagroda>,
Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl> wrote:
>Sun, 13 May 2001 05:26:22 GMT, Michael Lee Finney <michael.finney@acm.org=
>> pisze:
>> I suggest that alternatives for all available signatures be available
>> with a return type of void. It is very annoying to have to always
>> return something from main when normally I never return anything
>> from main.
>
>You cal declare main as returning int and omit the return statement
>at the end. There is a special exception for main which allows to do
>that, defaulting to 'return 0;'.

I think his point is that the whole main() thing is messy,
and that he would like some closure by allowing something else.
I agree it's a mess, and something probably should be done
(probably at the expense of making it more complex, but on the
other hand possible allowing ease of use).  In fact, many things
could and probably should be done in general re the ease of use and
teachability of C++.
--
Greg Comeau                 Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==>         http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo!       NEW: Try out our C99 mode!
comeau@comeaucomputing.com  http://www.comeaucomputing.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                ]





Author: comeau@panix.com (Greg Comeau)
Date: Sun, 20 May 2001 23:47:18 CST
Raw View
In article <s8qejVASwv$6Ewfp@ntlworld.com>,
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>There are technical reasons why a return of anything
>other than int [from main()] results in portability problems.

The problem is that their are arguments that there are technical
reasons why a return of int results in portability problems. :)
--
Greg Comeau                 Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==>         http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo!       NEW: Try out our C99 mode!
comeau@comeaucomputing.com  http://www.comeaucomputing.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                ]





Author: jk@steel.orel.ru (Eugene Karpachov)
Date: Mon, 21 May 2001 07:47:21 CST
Raw View
Sun, 13 May 2001 11:47:30 GMT Hans Aberg wrote:
>So then one may decide to say that the dereferencing of a zero pointer
>should throw an exception or something in order to get rid of the
>"undefined" -- but that may cause unacceptable runtime overheads, given
>the current computer technology.

I'd say that any modern CPU with hardware memory management unit can catch
NULL pointer dereferencing (as to "current computer technology"). The ancient
hardware, like real-mode i86's, would suffer of course, - but why penalize
whole majority of current hardware in favor of obsolete CPU's? It is doubtless
that no conforming implementation for PC 8086 exists anyway.

>In the future, it may be feasible to throw an exception in such cases. But

Not necessarily exception; may be 'program termination' is enough. Or may be
exception - it is debatable.

--
jk

---
[ 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: jk@steel.orel.ru (Eugene Karpachov)
Date: Mon, 21 May 2001 07:47:30 CST
Raw View
Wed, 16 May 2001 13:39:55 GMT James Kuyper Jr. wrote:
>Elimination of undefined behavior would require that a C++
>implementation emulate memory protection on platforms where it isn't
>provided by the hardware or operating system already. That can be a very
>significant cost.

Is there at least one modern platform where hardware cannot determine illegal
memory access? If yes, is there at least one conforming implementation of c++
for this platform anyway?

--
jk

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 21 May 2001 18:41:37 GMT
Raw View
In article <slrn9ghqqo.pk.jk@localhost.localdomain>, jk@steel.orel.ru
(Eugene Karpachov) wrote:
>>So then one may decide to say that the dereferencing of a zero pointer
>>should throw an exception or something in order to get rid of the
>>"undefined" -- but that may cause unacceptable runtime overheads, given
>>the current computer technology.
>
>I'd say that any modern CPU with hardware memory management unit can catch
>NULL pointer dereferencing (as to "current computer technology"). The ancient
>hardware, like real-mode i86's, would suffer of course, - but why penalize
>whole majority of current hardware in favor of obsolete CPU's?

This is interesting: If it is possible with many today's CPU's to catch
null pointer dereferencing, then it is possible for you or someone well
acquainted with the feature to write a proposal that allows one to make
use of it when avaiable.

>>In the future, it may be feasible to throw an exception in such cases. But
>
>Not necessarily exception; may be 'program termination' is enough. Or may be
>exception - it is debatable.

I think that one should be able to choose: One may write say a debugger or
a program that loads a DLL. Then it should be possible to avoid program
termination.

Otherwise, I realized that the problem with detecting dereferencing 0
pointers will go away when switching to programming with a polymorphic
variable: One way to implement this is to have a class "object" with a
polymorphic pointer to objects of classes derived from a class
"object_root". Further, put a reference count in so that the class
"object" maintains references to objects.

Then one can initialize the class object to the 0 pointer:
    class object {
      object_root* data_;
    public:
      object() : data_(0) { }
      bool null() const { return data_ == 0; }
    };
When developing this class, one will have to everywhere put in checks for
the 0 pointer, and decide what to do. For example
    Y object::this_or_that(X x) {
      if (null())  // Error.
      return data_->this_or_that(x);
    }

Now, if the CPU can support checks for 0 pointers, one would be able to
simplify the code above, if possible, so that the overhead decreases in
the case there is not a 0 pointer.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 21 May 2001 18:49:30 GMT
Raw View
Eugene Karpachov wrote:
>
> Wed, 16 May 2001 13:39:55 GMT James Kuyper Jr. wrote:
> >Elimination of undefined behavior would require that a C++
> >implementation emulate memory protection on platforms where it isn't
> >provided by the hardware or operating system already. That can be a very
> >significant cost.
>
> Is there at least one modern platform where hardware cannot determine illegal
> memory access? If yes, is there at least one conforming implementation of c++
> for this platform anyway?

Hardware detection of illegal memory access is not the answer - it
typically causes uncontrolled termination of your program. That's
perfectly acceptable with the current C standard, which allows undefined
behavior in this case. If the standard is changed to define the behavior
in this case, whatever that definition is, on some platforms it's going
to be different from what the hardware memory protection allows.
Incidentally, would someone care to suggest what that defined behavior
should be? Also, explain why it's useful for that behavior to be
defined.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 21 May 2001 18:49:53 GMT
Raw View
Eugene Karpachov wrote:
...
> I'd say that any modern CPU with hardware memory management unit can catch
> NULL pointer dereferencing (as to "current computer technology"). The ancient
> hardware, like real-mode i86's, would suffer of course, - but why penalize
> whole majority of current hardware in favor of obsolete CPU's? It is doubtless
> that no conforming implementation for PC 8086 exists anyway.

Well, there are no conforming implementations yet, period, so there's
certainly not one for a "PC" (?) 8086.

Secondly, who's penalized? Undefined behavior includes the possibility
of throwing an exception. On platforms where it can be caught, that's a
perfectly legal way of handling it.

...
> Not necessarily exception; may be 'program termination' is enough. Or may be
> exception - it is debatable.

Which is precisely why undefined behavior is the best choice; it allows
either of those, and other possibilities as well.

---
[ 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: comeau@panix.com (Greg Comeau)
Date: Mon, 21 May 2001 18:50:26 GMT
Raw View
In article <remove.haberg-1505012142580001@du131-226.ppp.su-anst.tninet.se>,
Hans Aberg <remove.haberg@matematik.su.se> wrote:
>In article <VB1AcWASJSA7EwXJ@ntlworld.com>, Francis Glassborow
><francisG@robinton.demon.co.uk> wrote:
>>>I think the reason that people want to get rid of the preprocessor is that
>>>in the past it has been used in order to get around limitations in the
>>>C/C++ languages.
>>
>>Not at all, the fundamental reason is that it knows nothing about scope,
>>and it is actually difficult to make it otherwise.
>
>I don't see why one would want to introduce scope in to the preprocessor,
>because that is something that belongs to the actual C++ language, nor do
>I see why one would want to get rid of the preprocessor for that reason.

One doesn't need to introduce scope into the preprocessor,
because it already has a scope.  But that's the problem,
it completes with the other scopes.  I'd much rather something
that wasn't a second distinct language atop my program, and instead
something which integrated and understood the rest of the syntax.
--
Greg Comeau                 Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==>         http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo!       NEW: Try out our C99 mode!
comeau@comeaucomputing.com  http://www.comeaucomputing.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                ]





Author: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Mon, 21 May 2001 19:58:43 GMT
Raw View
Francis Glassborow wrote:
>
> In article <MPG.15675c92644d20e4989728@news.lynchburg.net>, Michael Lee
> Finney <michael.finney@acm.org> writes
> >I think that's a good idea. And if changes to the
> >signature of main are considered, I suggest that
> >alternatives for all available signatures be available
> >with a return type of void. It is very annoying to
> >have to always return something from main when
> >normally I never return anything from main. The only
> >real use for returning something from main is writing
> >batch programs where the return code is used to direct
> >a script. I almost never write such programs and I
> >suspect that most programs don't fall into that
> >category.
>
> But the language (though not one major implementor in their current
> release) allows you to omit a return from main, the result will be the
> same as return 0; There are technical reasons why a return of anything
> other than int results in portability problems.

But if the only allowed return type other than int would be
void, the compiler could silently replace "void main" with
"int main" during compilation, and everything would be OK.

Things would be different if you would allow f.ex. return of
std::string.

---
[ 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: "Paul Mensonides" <pmenso57@home.com>
Date: Fri, 18 May 2001 07:43:10 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.156bba557914ef6f989732@news.lynchburg.net...
| I want to bring up, and discuss, a point that has been
| mentioned in the past when changes to C++ have been
| proposed. It has not been mentioned this time around,
| but almost certainly will be sooner or later.
|
| I see far too often the statement that some change or
| another is "merely" syntactic sugar. In spite of the
| fact that is perhaps the best reason to make a change!

You are right on target Michael.

I think the biggest deterrent to an enhanced and better C++ is the view that the
language will die or fragment (which it already has) if the language has too
many features.  This may have been the case at the beginning, but not any more.
C++ won't die no matter what they add to it.  The better course is to
*continually* add features over time.  Not all at once, of course; that is just
a new language and compiler vendors will start ignoring the standards body.
But, as long as there is room for improvement, then the language should be
improved--and there will always be room for improvement.  It is not a matter of
whether C++ is "good enough"; it is a matter of whether C++ could be better.
Likewise, how easy it is to teach C++ is not nearly as big an issue as it is
made out to be.  I thought that C++ wasn't supposed to be competing with other
languages?  If that is the case, then, it doesn't matter how *many* people use
it, as long as there are enough to justify its continued existence.  If people
want an *easy* (i.e. non-powerful, less-terse) programming language, they can
program in some other language (like VB).  I guarantee that if I care enough
about whatever they might add that I can learn it, and I think that is true for
most people.  If you can't understand the concepts you shouldn't be programming
in C++ anyway; that just makes it harder on the people that do understand it to
maintain your poorly written code.  After all, people have learned APL, for
goodness sake.  CLOS can be *way* more unreadable than C++ to the "learner" (it
also has *way* more primitives, etc.), yet some people (and not just the
geniuses) have learned it.  (Just look at the size of the ANSI Common Lisp .pdf
compared to the C++ one! 64.15 MB -> 2.05 MB)  Also, C++ tends to "borrow" most
of it's features from other languages.  Obviously, new paradigms are going to
develop a lot slower if no languages support them except backwater research
languages, and most of the time these languages (and paradigms) don't make it
anywhere because they are specialized for that specific programming paradigm
rather than general-purpose, multi-paradigm.  C++ doesn't tend to "create" any
new paradigms it just popularizes them after borrowing them because it is the
predominant systems programming language.  People seem to be saying, "C++ is
nearly finished, unless some other paradigm becomes prevalent, then we will
borrow it and add it to the language."  Yet how does a paradigm become
prevalent?  Originally, in the case of C++, only by distribution of
"non-standard" extensions to C (a popular language)(It is easy to dislike
"proprietary" languages unless you yourself are the creater of it!).  The
standard library is trivial compared to the core language of C++.  The library
can be made given the core language, not the other way around.  Also, many other
libraries are *almost* standard on certain platforms and they aren't part of
*the* standard.  Also, reinventing the wheel is frowned on, but it often a
necessity given the 'restrictions' on certain parts of the standard library.
C++ should give you the tools to do what you want to do, not discourage things
'physically' by not providing core language support (Oral discouragement is
enough.).  One of the best examples of all is Andrei Alexandrescu's Loki library
which I would classify as hackery (though it IS interesting) of the template
mechanism.  Support for this kind of thing should be directly supported by the
core language so this kind of convoluted psuedo-code can be avoided (after all,
what are templates but a glorified Cpp).  Don't get me wrong, Andrei's book is
one the best C++ books that I've purchased, and it was somewhat of an eye-opener
for me.  But this kind of gross manipulation shouldn't be necessary.  It is a
typical case of C++'s lack of core support generating far harder to learn, far
more complicated than necessary, and far less elegant paradigms.  It is a
glorified form of #define private public (and the like).  Too often I hear the
argument, "You can already do this, we don't need the extension."  Of course, we
don't *need* anything.  The people that promote these arguments tend to forget
to say, "You can already do this with this grotesque, inelegant, error-prone
hack, we don't need the extension."  If that is true, then we don't *need* C++
at all.  Michael is right, C++ can already do almost anything (the hard way) via
asm().  Which is better, a language that encourages a bunch of stupid hacks or
one that is clean and elegant?  Consider the
multiple-inheritance-same-virtual-function-name issue:  if the language doesn't
support an elegant form of renaming than you 'fake' it in a less coherent way
anyway.  What happened to discouraging Cpp usage?

the clean way to rename...

class A1 {
 public:
  virtual void f();
};

class A2 {
 public:
  virtual void f();
};

class B : public A1, public A2 {
 public:
    void A1_f() = A1::f;
    void A2_f() = A2::f;
};

the dirty way to rename...

class A1 {
 public:
  virtual void f();
};

class A2 {
 public:
  virtual void f();
};

class A1_ex : public A1 {
    public:
        void f() {
            A1_f();
        }
        virtual void A1_f() = 0;
};

class A2_ex : public A2 {
    public:
        void f() {
            A2_f();
        }
        virtual void A2_f() = 0;
};

class B : public A1_ex, public A2_ex {
    public:
        void A1_f() { ... }
        void A2_f() { ... }
};

Either way, you obtain the pseudo-same result:  renaming (never mind the
inefficiency issue).  So what is the point of preventing name aliasing?  How
about a similar example:

void SomeIdiotsReallyReallyReallyLongLibraryFunctionName(int);

inline void Idiot(int x) {
SomeIdiotsReallyReallyReallyLongLibraryFunctionName(x); }

Why is that any different than a general aliasing strategy?  It is actually far
more irritating.
This is only one example among many.  C++ should evolve directly into C++++, not
be replaced by it.

I agree with Stroustrup on many issues.  However, if C++ doesn't become C++++ by
itself (because it refuses to) it is going to become as asinine as some of the
'new' features of C99 (like _Complex) because it refuses to improve
significantly.  Then you get a crippled C++++ because it tries too hard to
maintain C/C++ compatibility, etc., etc.  Ultimately, you get a brand new
language that completely breaks for the past (i.e. C/C++) that fails completely
simply because it is NOT compatible with C++.  Therefore, C++ *MUST* become this
language or we are all in for a "dark age" of programming:  status quo only.

Paul Mensonides

---
[ 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: "Steve Burt" <steve.burt@cursor-system.com>
Date: Fri, 18 May 2001 11:56:39 GMT
Raw View
On the subject of possible language changes...

I don't know whether anyone else has mentioned this, but is it really
necessary to have both
delete *and* delete [] operators?
My experience has been that this can be a source of bugs and occasional
complication.

Wouldn't just a plain delete suffice? (i.e. make delete and delete[] the
same - no existing code would be broken).
I'd guess this would require an extra byte (or perhaps just a  bit) to be
allocated by new to tell it whether the thing is an array or not. new
already records the size. I'm sure the top bit of a 32-bit size could safely
be used.

---
[ 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: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Fri, 18 May 2001 15:02:44 GMT
Raw View
In article <9e31tk$oq6$1@news5.svr.pol.co.uk>, Steve Burt says...
>
>On the subject of possible language changes...
>
>I don't know whether anyone else has mentioned this, but is it really
>necessary to have both delete *and* delete [] operators? My experience
>has been that this can be a source of bugs and occasional complication.

Well, it has been recently discussed. The summary then was: " After
discussing this subject 17E34 times, we still don't like it." So the
summary now probably will be "After disucssing this 17E34 +1 times,
we still don't like it."

The main reason is that new[] is not considered something to use
casually. std::vector<> is a better default choice, and it doesn't need
a delete[].

>Wouldn't just a plain delete suffice? (i.e. make delete and delete[] the
>same - no existing code would be broken).
>I'd guess this would require an extra byte (or perhaps just a  bit) to be
>allocated by new to tell it whether the thing is an array or not. new
>already records the size. I'm sure the top bit of a 32-bit size could safely
>be used.

Keeping that information also means keeping some information for new'ed
integers etc. When the compiler sees delete, it knows that it doesn't
need to to look any further. It can just set a one-bit flag in a bit
array. I.e. keep a pool of 33*N integers, with N integers for 32 flags
indicating which one is free. Whenever a simple delete is done on
4 bytes of memory this flag is reset. new[] and delete[] typically are
more complex, keeping element counts etc. The compiler know to look for
that information when it sees delete[].

In your proposal, you'd have to implement new/delete as one-element arrays.
This would cause (in my example) a 3200% increase in overhead for simple
objects. An improvement in memory use is possible, but this will in return
cause additional run-time overhead.

The final, killer argument is that if you don't want to remember what
to use, you can replace all plain new's by new[1], and delete[]
everything. In that view the "normal" new is an optimization you can
take if you want, and you accept the consequences.

Regards,


--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl

---
[ 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: "Andrew R. Thomas-Cramer" <artc@prism-cs.com>
Date: Sat, 19 May 2001 09:02:52 GMT
Raw View
"Bjarne Stroustrup" <bs@research.att.com> wrote in message
news:GD6KyB.L9q@research.att.com...
> ...
>     remove "embarrasements" and frequent novice complaints
>...
> introduce notation for "override function".

Does this refer to replacing the arcane "=0" syntax?

If not, may I suggest we consider this syntax to be in this category? I
would have found it easier to teach the use of a keyword such as "abstract"
or "pure" than "=0".



---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Sat, 19 May 2001 09:02:13 GMT
Raw View
I have shown a number of macros here recently that
illustrates functionality that cannot be achieved
without the use of the preprocessor.

I know that many would like to eliminate the
preprocessor, but until there is a better way to
accomplish what macros do, that is not a viable
suggestion.

In the case of the macros I demonstrated, the
preprocessor was absolutely essential and used to pass
class names and variable names around and to construct
unique names where needed. The C++ preprocessor (as
opposed to others) is very weak in some of these
features. Things like providing a #set so that each
invocation of a macro can generate a different name
would be very useful. It would be very useful to
provide stronger scanning and replacement facilities
to make the resulting syntax nicer.

People have said (I don't remember who said it first)
that the preprocessor is only useful when you want to
change the language. Their given assumption is that
you should never want to change the language. But, my
response is *exactly*! Change includes enhance. No
language provides every possible facility. The
Property macro I gave is implemented by the compiler
for Forte's TOOL language. The get/set macros are
available in Eiffel under the concept of "uniform
access" (depending on how they are defined). But those
features are not in C++.

Bottom line, the preprocessor really does play a role
in C++ programming. The examples I gave are far from
the only examples. In most cases, the language is
being enhanced. In some cases, it is fixed.

Other (simpler) examples are...

   #define for if(0);else for

which fixes the for scope bug in many compilers
(Microsoft's Visual C++ 6.0 among them).

   #define loop while(1)

or

   #define loop for(;;)

Sometimes you want an infinite loop, but occasionally
one or the other of these constructs generates better
code on a particular platform. Just using "loop" as a
keyword is cleaner.

   #define until(x) while(!(x))

This allows the use of a negative "while" or
"do...while" loop. It is frequently cleaner to hide
the negation.

   #define when(x) if(!(x));else
   #define unless(x) if(x);else

These provide one-way conditionals which cannot suffer
from the dangling else problem. Knuth showed that 80%
of all conditionals are one-way. Probably 40% positive
and 40% negative. It can be cleaner, more
understandable -- and even reduce the likely hood of
bugs, to use these macros.

   #define elif else if

A bit of quick syntactic sugar to replace the missing
elif in the C++ (and C) language, but which is present
in the compiler.

   #define also :case

This allows a bit of syntactic sugar in switch
statements which have multiple alternatives. Then you
can say

   case a also b also c:

instead of the uglier

   case a:
   case b:
   case c:

The latter expresses a switch more in terms of jumps
and labels (which it is) instead of in terms of a
multi-way select (which is what it is conditionally).

   #define true (1||0)
   #define false (0&&1)

These defines allow the true/false keywords to be used
in the preprocessor without losing their type when
used in normal C++ expressions.

   #define nil

This is extremely useful in reducing bugs when an
empty statement is needed. So you can write...

   for(...)
      nil;

instead of

   for(...);

or

   for(...)
      ;

or

   for(...) {}

All of which tend to be error prone. Having a keyword
that doesn't do anything is sometimes very useful.

All of these fix or enhance C++. But the macro
preprocessor is also a convenient way to get those
enhancements into the language long before they make
it (if ever) into the standard or a particular
vendor's implementation.

Sometimes people say that you shouldn't change the
language because new readers can't understand the code
because it is no longer C++. However, I don't view the
use of macros like this any different than imposing
coding style requirements on a project, or conventions
as to ownership passage. All of those must be
explained external to the code or both understanding
and correctness will suffer.

And, of course, I can hope that eventually the C++
standard will pick some of them up. Certainly, C++ has
inherited from C nowhere near enough control
structures. Just because if/while is Turing complete
doesn't mean that I want to be limited to if/while. I
want a control structure for each of the reasonably
used patterns. That reduces errors and increases
readability. It can even help code efficiency by
giving the compiler another hint. Control structures
are one area when C++ is currently semantically
impoverished, instead of having semantic richness.

---
[ 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: "Steve Burt" <steve.burt@cursor-system.com>
Date: Sat, 19 May 2001 18:44:32 GMT
Raw View
"Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
news:aoaN6.7579$6j3.630114@www.newsranger.com...
> In article <9e31tk$oq6$1@news5.svr.pol.co.uk>, Steve Burt says...
> >
> >On the subject of possible language changes...
> >
> >I don't know whether anyone else has mentioned this, but is it really
> >necessary to have both delete *and* delete [] operators? My experience
> >has been that this can be a source of bugs and occasional complication.
>
> Well, it has been recently discussed. The summary then was: " After
> discussing this subject 17E34 times, we still don't like it." So the
> summary now probably will be "After disucssing this 17E34 +1 times,
> we still don't like it."
>
> The main reason is that new[] is not considered something to use
> casually. std::vector<> is a better default choice, and it doesn't need
> a delete[].
>
> >Wouldn't just a plain delete suffice? (i.e. make delete and delete[] the
> >same - no existing code would be broken).
> >I'd guess this would require an extra byte (or perhaps just a  bit) to be
> >allocated by new to tell it whether the thing is an array or not. new
> >already records the size. I'm sure the top bit of a 32-bit size could
safely
> >be used.
>
> Keeping that information also means keeping some information for new'ed
> integers etc. When the compiler sees delete, it knows that it doesn't
> need to to look any further. It can just set a one-bit flag in a bit
> array. I.e. keep a pool of 33*N integers, with N integers for 32 flags
> indicating which one is free. Whenever a simple delete is done on
> 4 bytes of memory this flag is reset. new[] and delete[] typically are
> more complex, keeping element counts etc. The compiler know to look for
> that information when it sees delete[].
>

You've lost me. Why does it need to keep anything?
If the size of the object is 4 bytes or less, it uses the method you
describe.
If it is bigger, it stores it on the heap somewhere with a size.
Whether the object is a primitive type, or a small array (a char[3], for
instance) makes no difference at all, does it? Allocating a 3 byte array can
use the fast pool method, just like allocating an int. All the compiler
needs to know is that the pool contains object of 'x' bytesor les, then
set/clear single bit flags.

delete[] and delete would still be identical (as indeed would new and new[])


> In your proposal, you'd have to implement new/delete as one-element
arrays.
> This would cause (in my example) a 3200% increase in overhead for simple
> objects. An improvement in memory use is possible, but this will in return
> cause additional run-time overhead.

I don't think so - the compiler uses the pool method for small things, heap
for larger ones
>
> The final, killer argument is that if you don't want to remember what
> to use, you can replace all plain new's by new[1], and delete[]
> everything. In that view the "normal" new is an optimization you can
> take if you want, and you accept the consequences.
>
Well, if memory management were implemented as I suggested above, this would
make no difference at all.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Thu, 17 May 2001 11:26:33 GMT
Raw View
> > Are there ANY modern machines which are not 2's
> > complement based? I don't know of any. I do know of
> > some interface hardware which sends its data in odd
> > formats, but not the primary processor. Are there even
> > any older machines for which new compilers are being
> > written which are not 2's complement?
>
> Define modern?  If you mean computers that are running
> C++ today, yes there are such machines.  You don't
> achieve portability by denying that certain machines
> ought not to exist.

I don't deny that certain machines don't exist, I am
not aware of any non 2's complement machines which
have active C++ compiler development. That does not
mean that they exist -- on the other hand, are there
enough of them to worry about? No language can be
suitable for every possible machine and there is no
reason that C++ should try to fit that mold.

You say there are such machines. What are they? How
many are they?

> > Another possibility is to assuming that integers are
> > available as power of two. Here, there would be some
> > diminishing of market because there are apparently
> > some DSPs which have 40 bit integers (according to
> > recent posts). However, are full blown C++ compilers
> > being implemented for DSPs? Do we really care if a
> > fully conforming C++ can't be implemented on the
> > occassional DSP? Like 2's complement, this is
> > something that always seems to be the case for modern
> > processors.
>
> There exist machines running C++ today that have 20, 24,
> 36 bit integers.  Do you want to extend this restriction
> to all datatypes.  The Pentium has 80 bit floating point.
> This is now perhaps the most popular C++ platform in the
> world.

I am interested in going with the hardware designers'
consensus, as far as it actually exists. I don't know
of any recent machines which have floating point which
do not support IEEE floating point. Which gives the 32
and 64 bit formats as standard. It also gives a short
extended format between 32 and 64 bits (nobody bothers
with that one) and a long extended format between 64
and 128 bits. For the latter I have seen 64, 80, 96
and 128 bits -- probably 112 is out there somewhere.
So, no, I don't necessarily advocate that all data
types be a power of two.

These machines running 20, 24 and 36 bit integers and
C++ may be out there. But again, if so, what are they?
How many are they? How long before they fall apart
from rust? Do we really care about them?

After all, they could always implement a non-conformat
version of C++ which differs in that aspect. Possibly
there could be a more relaxed version of the standard
for such machines. But is there any reason the rest of
us need to be stuck with the consequences? Also, is it
entirely unreasonable to require the compilers for
those machines to generate the needed code to handle
"standard" data types? There might be a very small
performance penalty on such machines, but that doesn't
mean that they are left out in the cold either. Where
is the most benefit for the most people?

> > Its past time to drop support for archaic hardware.
> > Hardware designers have tended to arrive at a
> > consensus, so why shouldn't language designers take
> > advantage of that consensus.
>
> I disagree with your determination that "everything that
> I'm not using is archaic."  In actuality the issues here
> are trivial.

That I never said. Just because I'm not using it, does
not mean that it is archaic. There is a *lot* that I
am not using which is not archaic. On the other hand,
just because someone is using some particular hardware
does not mean that it is not archaic.

If it hasn't been designed and built in the last 10
years, it is archaic. Or perhaps the last 5. And
perhaps we should only consider machines in active
production (machines which are not being produced
clearly are either archaic or are going to quickly
become archaic). This industry moves fast, and
hardware more than 5 years old is generally so limited
that it gets tossed onto the curb for garbage pickup.
I have done so several times myself.

I think we should draw a line and set a reasonable
policy as to what machines should be considered. I
think the policy "if it has ever existed or might
possibly exist then the C++ standard should support
it" is not the right policy. There are probably people
keeping an IBM STRETCH computer alive somewhere. But I
don't think that the C++ standard needs to consider
it. If you can't go out and buy one then probably new
versions of the standard don't need to consider it. I
personally know of someone that has a PDP-11 in their
living room. But I see no reason to support C++ for it
either.

If it wasn't for the IBM mainframe world, I would
argue that we don't need to consider any character set
other than Unicode. I would argue that we should
distinguish between source, internal and target
character sets. And that the internal character set
should be explicitly and only Unicode. The source and
target character sets can be converted into and from
Unicode as necessary, so the standard could be more
explicit (and generous -- especially for potential
overloadable operators) about the supported character
set. Of course, that doesn't mean any run-time
overhead, any conversions are compile time only.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 17 May 2001 11:27:37 GMT
Raw View
In article <MPG.156cb1b91a391cb8989735@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>Consider Java. It has made quite a few of these
>assumptions. While it may have gone further than we
>would like in that direction, nevertheless, I don't
>see a lot of complaining that Java can't be
>implemented on this or that platform because of the
>assumptions.

Java runs on exactly one platform (with minor variations:)

>
>Its past time to drop support for archaic hardware.
>Hardware designers have tended to arrive at a
>consensus, so why shouldn't language designers take
>advantage of that consensus.
>
>
>> > As far as dereferencing null pointers is concerned,
>> > there is no reason that when "0" is converted to a
>> > pointer that it cannot actually point to some read
>> > only area of memory which contains a virtual object,
>> > all of whose vptrs go to code that throws an
>> > exception. That should should have a zero cost.
>>
>> On many platforms, the most natural implementation of integer-pointer
>> conversion is equivalent to keeping the bit pattern unchanged.
>> Unfortunately, the bit pattern corresponding to an integer with a value
>> of 0 isn't necessarily the bit pattern of a legal address. Even if it is
>> a legal address, it might be one that's reserved to the operating system
>> for some special purpose, thereby preventing a C++ implementation from
>> filling it in the fashion described. On such platforms, your suggestion
>> would require adding a null-pointer test to every pointer dereference.
>>
>> Elimination of undefined behavior would require that a C++
>> implementation emulate memory protection on platforms where it isn't
>> provided by the hardware or operating system already. That can be a very
>> significant cost.
>
>The conversion of integer to pointer could withstand
>the cost of a zero check and replacement with some
>other value (and vice-versa for the opposite
>conversion). That conversion is very rare in code. The
>most important conversion is that of the constant 0 to
>a pointer which the compiler can detect.
>
>I do not suggest the overhead of checking each pointer
>dereference (although that could be part of a
>debugging compile). You can substantially reduce the
>number of undetected null pointer dereferences without
>going that far. It doesn't have to be all or nothing.

Well few of us are against attempts to reduce undefined behaviour, and
even remove certain sets of undefined behaviour entirely. But what you
are writing about here is a quality of implementation issue. Good
implementations might detect null-pointer dereferencing, but from the
standard perspective either it has to be prohibited or classified as
undefined behaviour, standards cannot just say 'avoid it if you can.'

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 17 May 2001 11:28:40 GMT
Raw View
Michael Lee Finney wrote:
...
> The "One Definition Rule" says that the same name
> can't have two different definitions -- even in
> different translation units. Most compilers don't

No, it says that functions, objects, types, static class member, or
templates can't have different definitions in different translation
units. It doesn't even mention names that denote none of those things,
such as macros. Per 3.5p9,

"two names that are the same (clause 3) and that are declared in
different scopes shall denote the same object, reference, function,
type, enumerator, template or namespace if

-- both names have external linkage or else both names have internal
linkage and are declared in the same translation unit; and

-- both names refer to members of the same namespace or to members, not
by inheritance, of the same class; and

-- when both names denote functions, the function types are identical
for purposes of overloading; and

-- when both names denote function templates, the signatures (14.5.5.1)
are the same"

Therefore, the same name occurring in different translation units can
indicate different things whenever that rule doesn't apply. In
particular, they can have different definitions if both names have
internal linkage, or no linkage.

I know nothing about IBM's compiler, but the descriptions of it given in
this thread suggest that it might treat some of those names as if they
were in the same translation unit, and that it would therefore find
their definitions to be in conflict.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 17 May 2001 11:31:03 GMT
Raw View
Michael Lee Finney wrote:
...
> I do not suggest the overhead of checking each pointer
> dereference (although that could be part of a
> debugging compile). You can substantially reduce the
> number of undetected null pointer dereferences without
> going that far. It doesn't have to be all or nothing.

Implementations currently have permission to produce undefined behavior
whenever you dereference null pointers. If the idea is to remove that
permission entirely, then a partial fix is insufficient.

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Thu, 17 May 2001 17:36:18 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.156cb4e78dfba807989736@news.lynchburg.net...
> In article <9dtcnt$jr2g3$1@ID-49767.news.dfncis.de>,
> anthwil@nortelnetworks.com says...
> > "Michael Lee Finney" <michael.finney@acm.org> wrote in message
> > news:MPG.156b43fd86ad209698972d@news.lynchburg.net...
>
> > Why does this require that we lose separate compilation? It seems to me
that
> > all the information about a single translation unit (which headers it
> > includes (and which parts of those headers it depends on), which
template
> > instantiations it needs, etc) could be included in an object file
generated
> > from that translation unit as a single entity. When linking the files
> > together into the final executable (or shared library or DLL or
whatever),
> > then the compiler would be able to automatically detect whether an
object
> > file was out of date wrt another, and either recompile automatically (if
the
> > source was available) or flag an error (if it wasn't). Also, when
> > recompiling a single translation unit, it could be checked against the
> > information in the pre-existing object file for changes.
>
> Everything you say is true. But, if you don't give up
> separate compilation then code optimization needs to
> be moved out of the compiler and into the linker.

For those optimisation algorithms that require global knowledge, yes.

> There are many optimization algorithms which only work
> with complete code analysis. While they can be adapted
> to handle a set of explicit inports and exports (which
> is similar to what happens due to separate translation
> units) they have to know things such as all declared
> classes. Many of the optimization gains made by these
> algorithms can be significant, but they aren't
> available with separate translation units.

Unless you provide the required info to the now-optimising linker.

> > I don't like the thought of messing with order of declaration. As for
> > optimisation, when generating object code, the compiler could store not
only
> > the general no-assumptions-about-usage object code for a function, but
also
> > enough additional information to enable it to further optimise the
function
> > at final link time based on usage. e.g. if a function is passed two
> > references, then in general it can assume nothing about whether or not
they
> > refer to the same object. If in practice, they always refer to the same
> > object, then the compiler can eliminate one of them at final link time.
If
> > the required additional information about a function is not present
(e.g. it
> > was written by a third party), or the required usage information is not
> > present (it is used by a third-party library without additional info),
then
> > the pre-generated no-assumptions object code can be used.
>
> How is eliminating order dependency really "messing
> with order of declaration"? Everything currently valid
> is still valid. And things that should be valid become
> valid. And I stop driving myself crazy trying to make
> the compiler happy via the empirical discovery of an
> order of declaration for inline functions (and
> sometimes classes). Let the blasted compiler read the
> source file twice. Once to discover all of the
> definitions (storing them for later) and once to
> actually compile. Not really a big deal -- especially
> as the second pass is usually on the stored,
> preprocessed text.

The problem with ignoring the order of declaration is the same problem as
having "using directives" in headers - which declarations are visible
depends on the context. I write my (template or inline) code in a header
that uses a specific operator or function, which must be declared before
use. If you permit the functions written in the source file which #includes
this header to be included in the name lookup, then you can change which
function is selected, or create an ambiguity where there was none before.

> > > IBM's compiler let you specify header files to be used
> > > in the project, but they are global across the
> > > project. You can, however, still specify header files
> > > the "standard" way for those header files which must
> > > be seen only in one source file.
> >
> > Project-wide includes seem dangerous to me - each file depends on things
not
> > explicitly identified within it. Thus if you want to reuse the code
> > elsewhere, it is not clear what it depends on.
>
> The "One Definition Rule" says that the same name
> can't have two different definitions -- even in
> different translation units. Most compilers don't
> enforce that (IBM's VisualAge C++ compiler does), but
> its consequence is that any header file used in any
> translation unit can be included in any other
> translation unit without having any effect other than
> possibly reducing compilation speed.

Again, its not the violations of ODR that I'm concerned about, its the
silent changes to name resolution, due to the extra (non-obvious)
declarations present in the project-wide headers.

> The only exception is macro expansion which may or may
> not be global. That is handled by the IBM compiler by
> still allowing the normal #include which is processed
> in the normal manner. But all of the other headers can
> be given to the compiler and processed just once.
>
> I don't see how potential reuse of the code changes
> this.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 17 May 2001 17:36:36 GMT
Raw View

Christopher Eltschka wrote:
[...]
> Another idea: What, if - instead of a typeof operator - it
> would be allowed to use an expression as template argument
> where a type argument is expected, and it would be taken as
> the type of the expression to be inserted here. Then typeof
> could be implemented in terms of this. Advantage: no keyword.
>
> Example: typeof implementation
>
> template<class T>
>  struct type_traits
> {
>   typedef T type;
> };
>
> #define typeof(expr) type_traits<(expr)>::type

Combining this idea with templated typedefs we get rid of the macro:

template <typename T> typedef type_traits<T>::type typeof;

Best regards,
Nicola Musatti

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Thu, 17 May 2001 17:37:18 GMT
Raw View
In article <GDGIrF.Bqw@research.att.com>,
bs@research.att.com says...

> I think that "syntactic sugar" most often refers to facilities - such as
> C++ macros - that make the text seen by the programmer different (and
> supposedly more pleasing to humans) than what the compiler eventually sees.
> That is, the term is most often reserved to source transformation
> tools/facilities. I suggest we try to stick to that definition in this
> discussion.

Would you include operator overloading in that
category? I think it is one of the most important
categories of syntactic sugar, but the compiler does
see the operators.

> I have never seen "auto" used to good effect. I remember when "register"
> became redundant and sometimes counterproductive. However, I have yet to
> see examples where "inline" is redundant, and it will be years before
> "inline" is redundant in portable code.
>
> PS One reason C++ has "inline" was that a long time ago I was assured that
> next year my compiler would do automatic inlining that was better that a
> human could do - after 25 years I'm still waiting for that compiler.

My only problem with "inline" is that I can't force
the compiler to inline code. I frequently write code
which I know will only perform efficiency if it is
inlined, but the compiler will decide not to inline
once some threshold has been reached. Sometimes it is
because I know that dead code removal will result in
very small code after inlining, but the compiler can't
tell that beforehand.

I have seen a difference of a factor of two in
performance between two different compilers because of
this effect, where otherwise they generally produce
code which is pretty much neck and neck.

I know that every function can't be inlined, but even
recursive functions can be inlined one or two levels.
And sometimes I want to force inline because of code
locality or some other reason. Its o.k. to hint to the
compiler, but sometimes I want to demand!

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 17 May 2001 17:37:54 GMT
Raw View
Michael Lee Finney wrote:
...
> If it hasn't been designed and built in the last 10
> years, it is archaic. Or perhaps the last 5. And

Your time scale is myopic. The time between revisions to the standard is
only about 10 years. Code and platforms survive for decades. There's
still Fortran code in active use that was written in the 60's, and I'm
sure that doesn't define the upper limit on useful code life. One of the
key purposes of standardization is time binding; by giving due
consideration to issues of backward compatibility, it allows old code to
be re-used with minimal re-writes.

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Thu, 17 May 2001 17:38:28 GMT
Raw View
Bjarne Stroustrup wrote:
>
> Francis Glassborow <francis.glassborow@ntlworld.com> writes
>
> > Michael Lee Finney <michael.finney@acm.org> writes
> > >The basis of syntactic sugar is that you can write
> > >something that is both more concise AND more readable,
> > >and usually more writable as well.
> >
> > Well it all depends on what you understand by syntactic sugar. Keywords
> > like 'try' are the most refined examples, they do absolutely nothing
> > other than make humans feel comfortable, the compiler could completely
> > ignore them and just note blocks that are followed by one or more
> > catches.
>
> I think that "syntactic sugar" most often refers to facilities - such as
> C++ macros - that make the text seen by the programmer different (and
> supposedly more pleasing to humans) than what the compiler eventually sees.
> That is, the term is most often reserved to source transformation
> tools/facilities. I suggest we try to stick to that definition in this
> discussion.

So, by that definition is 'try' syntactic sugar?
How about '+=' ?

In a language like C on a machine where this:
  x + y
is always the same as this:
  x - -y
Is + syntactic sugar?
Or maybe it is the 2 operand '-' that is syntactic sugar?

Or maybe these +, -, *, / are all just syntactic sugar, and
the 'real operations' are +=, -=, *=, and /=.

Who is to say which part of the compiler is that part that
you call "source transformation" above, and which part of
the compiler is the part that you call "compiler" above?

In short, I think you have a much different idea in mind
for what '"syntactic sugar" most often refers to' than
I have ever heard of before.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 17 May 2001 19:55:53 GMT
Raw View
In article <MPG.156cdf12bff12a2f989737@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>If it wasn't for the IBM mainframe world, I would
>argue that we don't need to consider any character set
>other than Unicode. I would argue that we should
>distinguish between source, internal and target
>character sets. And that the internal character set
>should be explicitly and only Unicode. The source and
>target character sets can be converted into and from
>Unicode as necessary, so the standard could be more
>explicit (and generous -- especially for potential
>overloadable operators) about the supported character
>set. Of course, that doesn't mean any run-time
>overhead, any conversions are compile time only.

Oh, boy! Join the C Standards reflector and see just how big a mess
supporting Unicode can be. And it keeps changing. Once 16-bits was
enough, now it isn't. If you are writing code for the most exte4nsively
used CPU types in the world (like the several dozen that manage your new
car) you certainly would not want anything to do with Unicode. Of course
you may think these do not need any internal codings for characters but
I think you would be mistaken.

I know that it is normal to think that one's own experience is typical
but one thing that working in the standards world has taught me is that
different problem domains have very different views of what is normal
and there is nothing special to my view.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Thu, 17 May 2001 21:11:52 GMT
Raw View
In article <9e03h7$ahpp$1@ID-49767.news.dfncis.de>,
anthwil@nortelnetworks.com says...
> Again, its not the violations of ODR that I'm concerned about, its the
> silent changes to name resolution, due to the extra (non-obvious)
> declarations present in the project-wide headers.

I agree that this is a serious concern, much more so
that macros which can be handled. I am not sure of the
impact or how the IBM compiler handles it. IBM claims
the compiler is compliant with the standard, but there
are bound to be areas which aren't quite up to snuff.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Thu, 17 May 2001 21:12:09 GMT
Raw View
In article <3B03D86B.8D36B885@wizard.net>,
kuyper@wizard.net says...
> Michael Lee Finney wrote:
> ...
> > If it hasn't been designed and built in the last 10
> > years, it is archaic. Or perhaps the last 5. And
>
> Your time scale is myopic. The time between revisions to the standard is
> only about 10 years. Code and platforms survive for decades. There's
> still Fortran code in active use that was written in the 60's, and I'm
> sure that doesn't define the upper limit on useful code life. One of the
> key purposes of standardization is time binding; by giving due
> consideration to issues of backward compatibility, it allows old code to
> be re-used with minimal re-writes.

My point is not old code, but old hardware. The old
code is (almost always) running on newer hardware.
Which means that it must be recompiled. And ported to
the standard supported by the compiler. I have a lot
of old C code which was written when function
prototypes had a different syntax. It has to be ported
whenever I recompile it for a newer platform.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 18 May 2001 01:09:47 GMT
Raw View
Michael Lee Finney wrote:
>
> In article <3B03D86B.8D36B885@wizard.net>,
> kuyper@wizard.net says...
> > Michael Lee Finney wrote:
> > ...
> > > If it hasn't been designed and built in the last 10
> > > years, it is archaic. Or perhaps the last 5. And
> >
> > Your time scale is myopic. The time between revisions to the standard is
> > only about 10 years. Code and platforms survive for decades. There's
> > still Fortran code in active use that was written in the 60's, and I'm
> > sure that doesn't define the upper limit on useful code life. One of the
> > key purposes of standardization is time binding; by giving due
> > consideration to issues of backward compatibility, it allows old code to
> > be re-used with minimal re-writes.
>
> My point is not old code, but old hardware. The old
> code is (almost always) running on newer hardware.
> Which means that it must be recompiled. And ported to
> the standard supported by the compiler. I have a lot
> of old C code which was written when function
> prototypes had a different syntax. It has to be ported
> whenever I recompile it for a newer platform.

I suspect that you're not really talking about a different syntax for
function prototypes, that's been relatively unchanged since prototypes
were first introduced by the C89 standard. What did change when C was
first standardized was that function declarations used to have only a
non-prototype syntax, and but the standard introduced function
prototypes as an alternative way of doing function declarations.
However, the old non-prototype syntax was never abandoned by C (though
it has been abandoned by C++). If that's the change you're talking
about, it was forced only by your need to change languages; within C
itself, backwards compatibility has been maintained in this matter.
That's not quite true - C99 has killed implicit int. However, there
aren't any C99 implementations yet, so I doubt that you're referring to
that change.

This actually illustrates my point; it's the failure to keep changes
backward compatible that cost you all that porting work. You can blame
predecessors with the same attitude you have for that work.

I don't believe that backward compatibility should be treated as an
absolute requirement that must always be honored; I'm just saying that
the time scale for breaking backwards compatibility should be a lot
longer than the 5-10 years you were suggesting.

---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 16 May 2001 13:37:49 GMT
Raw View

Alexei Zakharov wrote:
>
> > So, what do we want?
>
> Delegates.
>
> This can be a very useful feature and this idea is around for many years.
>
> That's how Bjarne Stroustrup describes it in "The design and evolution of
> C++":
>     class B { int b; void f(); };
>     class C : *p { B* p; int c; };
>     void f( C* q )
>     {
>         q->f();  //  meaning q->p->f();
>     }

I'm not sure I follow the implications of this proposal, but I thought
I'd jump on the chance of suggesting my alternate syntax; given your B
class:

struct B1 { int g(); int h(); };
class D {
  public:
    using b;
    using *b1;
    int h();    // hides b1->h();
  private:
    B b;
    B1 * b1;
};

Best regards,
Nicola Musatti

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 16 May 2001 13:37:29 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.156b43fd86ad209698972d@news.lynchburg.net...
> In article <9dqp1n$je3m0$1@ID-49767.news.dfncis.de>,
> anthwil@nortelnetworks.com says...
> > "Michael Lee Finney" <michael.finney@acm.org> wrote in message
> > news:MPG.156a6b7532c00bc98972b@news.lynchburg.net...
> > > In article <bbajqVAuHIA7Ew2Y@ntlworld.com>,
> > > francis.glassborow@ntlworld.com says...
> > > > No, much of current undefined behaviour is because anything else
places
> > > > an unreasonable requirement on compilers in a context of separately
> > > > compiled translation units.
> > >
> > > Perhaps its time to drop the notion of separately
> > > compiled translation units. This notion does not bring
> > > much benefit to the table and yet causes tremendous
> > > problems.  And the only compiler that compiles
> > > everything together (the IBM VisualAge C++ 4.0 or
> > > above) is also the only compiler that truly enforces
> > > the single declaration rule.
> > >
> > > In practice (and I maintain programs across multiple
> > > platforms) I find that every target I build has to
> > > have its own makefile and the object files cannot, in
> > > general, be shared between projects because the
> > > compiler options tend to be different (RTTI - yes/no,
> > > multithreaded support - yes/no, char as
> > > signed/unsigned - yes/no, etc.)
> > >
> > > And the benefits of eliminating that restriction are
> > > tremendous -- starting with optimization.
> >
> > Are you saying that if you change one source file, every other file in
your
> > project has to be recompiled?
>
> Not at all. The IBM VisualAge C++ 4.0 compiler builds
> a database as it compiles. That includes template
> instantiations. Nothing is ever compiled twice. As I
> understand it, even functions within a translation
> unit are not recompiled when something else changes.
> IBM has shown that you can do a tremendous job in that
> way, substantially reducing both original compile time
> (no recompiling template instantiations) and recompile
> time (no recompiling anything which didn't change). In
> the latter case, it does have to at least compare the
> source code to inside of a changed translation unit to
> find the areas which have changed. But that can be as
> fast as grep.

Why does this require that we lose separate compilation? It seems to me that
all the information about a single translation unit (which headers it
includes (and which parts of those headers it depends on), which template
instantiations it needs, etc) could be included in an object file generated
from that translation unit as a single entity. When linking the files
together into the final executable (or shared library or DLL or whatever),
then the compiler would be able to automatically detect whether an object
file was out of date wrt another, and either recompile automatically (if the
source was available) or flag an error (if it wasn't). Also, when
recompiling a single translation unit, it could be checked against the
information in the pre-existing object file for changes.

> > That is the benefit of separate compilation - each translation unit
(within
> > a project) can be compiled separately, and only recompiled if its direct
> > dependencies change. If we lose that ability, compile times for large
> > projects will become unrealistically long, as (say) 10000 source files
will
> > have to be recompiled every time someone makes a one character change in
any
> > file, even if nothing else really depends on it.
>
> With IBM's approach, changes to things such as
> comments do not force a recompilation. Is that true of
> your current compiler?

MSVC does do something like that, but I am not sure under what circumstances
it works (occasionally it outputs "no significant changes", or something,
and doesn't regen the object file) It still has to check every translation
unit that references the changed file, though.

> > Certainly there are benefits to eliminating separate compilation, with
> > regard to the final compiled program - fewer bugs due to more checking,
> > better optimisation etc. However, the cost for this benefit is very
large.
>
> I think the cost is much smaller than most people
> realize. Keeping separate source files is fine for
> code organization, but the compiler should be told all
> of the necessary source files, any additional object
> files or libraries, its options and what it is to
> produce. Let the compiler handle things like
> determining what has actually changed, let it do
> optimization across the entire program, even let it
> process header files only one time (when possible).
> Let the compiler worry about order of declaration --
> which is one REALLY nice benefit of IBM's compiler. I
> hate trying to order inline functions to make sure
> that a one pass compiler can handle things right. I
> should NEVER have to worry about what order I wrote
> things in my source code. Let the blasted compiler
> read the source code twice!

I don't like the thought of messing with order of declaration. As for
optimisation, when generating object code, the compiler could store not only
the general no-assumptions-about-usage object code for a function, but also
enough additional information to enable it to further optimise the function
at final link time based on usage. e.g. if a function is passed two
references, then in general it can assume nothing about whether or not they
refer to the same object. If in practice, they always refer to the same
object, then the compiler can eliminate one of them at final link time. If
the required additional information about a function is not present (e.g. it
was written by a third party), or the required usage information is not
present (it is used by a third-party library without additional info), then
the pre-generated no-assumptions object code can be used.

> IBM's compiler let you specify header files to be used
> in the project, but they are global across the
> project. You can, however, still specify header files
> the "standard" way for those header files which must
> be seen only in one source file.

Project-wide includes seem dangerous to me - each file depends on things not
explicitly identified within it. Thus if you want to reuse the code
elsewhere, it is not clear what it depends on.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 16 May 2001 13:38:14 GMT
Raw View

"James Kuyper Jr." wrote:
>
> Dave Harris wrote:
> >
> > kuyper@wizard.net (James Kuyper Jr.) wrote (abridged):
> ...
> > > If you've explicitly initialized a variable with an incorrect value,
> > > and forget to give it a correct value before first use, the behavior is
> > > perfectly well defined, but incorrect. That's what makes it bad
> > > practice.
> >
> > Giving variables the wrong value is indeed a bug, but using a random
> > value instead of 0 will not make the bug go away.
>
> No; making them random instead of 0 makes the bug worse; that's the
> whole point - ideally it makes the bug so bad that it gets noticed
> during the early stages of testing, rather than long after final
> delivery.

I would like to add a couple of comments to this discussion. There are
situations where there is no reasonable initial value for a variable and
defaulting to one is just misleading. In such cases, defaulting to zero
may prove a bad choice because is often a reasonable value and may
actually make bugs more evident.

An alternative that just came to my mind is to make "unitialization"
explicit by using a conventional value; for integral types a choice
could be something like:

const int uninitialized = 0xBAD;
int i = uninitialized;

which might be easy to spot with a debugger and much more unlikely to be
a valid value than zero.

Best regards,
Nicola Musatti

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 16 May 2001 13:38:52 GMT
Raw View
In article <Aug1HXAEcdA7EwH6@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>In article <remove.haberg-1505012142540001@du131-226.ppp.su-
>anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>>But this is resolved when introducing a conservative GC.
>
>I have seen many claims for conservative GC but never this one. How it
>solve problems such as the optimiser assuming that the two variables are
>distinct, when the call passes the same one to both reference
>parameters.

Well, in a conservative GC, the runtime system keeps track of bindings, so
it does not make any difference if they are the same or distinct. It is
easy to see if you replace the references in your examples by a C++ class
with a ref count (but a ref count can't resolve circular structures).

>Do you understand the problems that lead to undefined behaviour?

What I do not understand is what you have in your mind, and I do not seem
to get any help from you. The example you gave did not tell exactly what
you have in your mind, so I am left guessing.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Andrew Cannon <ajc@gmx.net>
Date: Wed, 16 May 2001 13:39:15 GMT
Raw View
My 0.2 Pf worth:

I would like to have some way of "turning off" a virtual base class. In
other words, a way of declaring it to be no longer virtual for
more-derived classes.

Example:

class A { ... };
class B : virtual A { ... };
class C : virtual A { ... };
class D : B, C, final virtual A { ... };

[I've used an imaginary keyword "final" here which has already been
suggested in the context of making a class non-derivable, but this is
obviously only one possibility.]

Now the effect of this is that the virtual base A inherited from B and C
becomes a non-virtual base of D. In terms of storage layout it has a
fixed place in every D object.

If A has no default constructor then D::D() must call A's constructor as
usual, but the "bubbling-up" stops there, so subclasses of D do not see
A as a virtual base and don't have to call A's constructor.

This effectively "encapsulates" the virtual base, which is highly
desirable if you are writing a library class. It also makes virtual
bases without default constructors a practical proposition!

Andrew

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 16 May 2001 13:39:55 GMT
Raw View
Michael Lee Finney wrote:
>
> In article <BJyFujAOQaA7Ew1v@ntlworld.com>,
> francis.glassborow@ntlworld.com says...
> > In article <MPG.156b45757716f6bc98972e@news.lynchburg.net>, Michael Lee
> > Finney <michael.finney@acm.org> writes
...
> > I think you are entirely missing the root causes of undefined behaviour.
> > Unless the compiler sees the actual source code for the whole program at
> > one time (and object code is not good enough) it cannot diagnose a
> > considerable amount of undefined behaviour.
...
> I fear either we aren't communicating at all, or you
> have answered a different post. While I am concerned
> about undefined behaviour, that has no relationship to
> my desire to eliminate independent compilation of
> translation units.

You and Francis are talking about two different kinds of undefined
behavior. As Francis rightly points out, a lot of behavior is undefined
simply because making it defined would require implementations to
consider an entire program as a whole before fully translating any of
it, because it can only be detected by examining the source code on a
whole-program basis.

> The primary place where undefined behaviour annoys me
> is signed right shift which I have long felt should be
> strictly defined as an arithmetic shift -- at least
> when compiled on a 2's complement machine (and are
> there any other sorts in significant numbers today?).

That, on the other hand, is example undefined behavior that is there in
order to make it feasible to implement C++ on a wide variety of
platforms. If Mark Blewitt's suggestion that undefined behavior be
eliminated were actually carried out, I think you'd find that there
would be a drastic reduction in the number of platforms on which
conforming C++ implementations were possible. The number would probably
drop to either 0 or 1, depending upon how certain issues were resolved.

> As far as dereferencing null pointers is concerned,
> there is no reason that when "0" is converted to a
> pointer that it cannot actually point to some read
> only area of memory which contains a virtual object,
> all of whose vptrs go to code that throws an
> exception. That should should have a zero cost.

On many platforms, the most natural implementation of integer-pointer
conversion is equivalent to keeping the bit pattern unchanged.
Unfortunately, the bit pattern corresponding to an integer with a value
of 0 isn't necessarily the bit pattern of a legal address. Even if it is
a legal address, it might be one that's reserved to the operating system
for some special purpose, thereby preventing a C++ implementation from
filling it in the fashion described. On such platforms, your suggestion
would require adding a null-pointer test to every pointer dereference.

Elimination of undefined behavior would require that a C++
implementation emulate memory protection on platforms where it isn't
provided by the hardware or operating system already. That can be a very
significant cost.

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Wed, 16 May 2001 13:40:17 GMT
Raw View
michael.finney@acm.org (Michael Lee Finney) wrote (abridged):
> As far as dereferencing null pointers is concerned,
> there is no reason that when "0" is converted to a
> pointer that it cannot actually point to some read
> only area of memory which contains a virtual object,
> all of whose vptrs go to code that throws an
> exception. That should should have a zero cost.

It's harder to detect "one past the end" dereferences. Eg:

    void demo() {
        int data[10];
        int *p = data;
        p += 10;
        assert( p != 0 );
        ++*p;
    }

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Heinz Huber <hhuber@racon-linz.at>
Date: Wed, 16 May 2001 15:13:26 GMT
Raw View

Francis Glassborow wrote:
>
> In article <3B00DB8A.8A389E2D@racon-linz.at>, Heinz Huber <hhuber@racon-
> linz.at> writes
> >I didn't mean to propose a general implicit (I think you meant implicit above)
>
> I did:(
>
> >conversion from int to enum. What I want is the compiler to use an implicit
> >conversion only in the following (and equivalent) case:
> >enum Test { t1, t2 };
> >Test v1 = t1 + t2;      // OK since operator on two values of Test
>
> IOWs you want exactly what I do a built-in default operator+ for each
> enum type (but which operators should be provided as defaults?

As to which operators should be provided, I like Christopher Eltschka's
suggestion of introducing enum directives:

__ordinal enum ...
__set enum ... (I'd prefer __bitmask here)
__set enum ... (this time a real set; equivalent to enum without a qualifier)
__circular enum ...

[snipped other examples of what should not work]

Heinz

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 16 May 2001 15:13:54 GMT
Raw View
In article <MPG.156bba557914ef6f989732@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>The basis of syntactic sugar is that you can write
>something that is both more concise AND more readable,
>and usually more writable as well.

Well it all depends on what you understand by syntactic sugar. Keywords
like 'try' are the most refined examples, they do absolutely nothing
other than make humans feel comfortable, the compiler could completely
ignore them and just note blocks that are followed by one or more
catches.


These days, keywords such as 'auto', 'register' and increasingly
'inline' are also superfluous to requirements.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 15:13:46 GMT
Raw View
I would like to suggest a new modifier for pointers
which would only have an effect when the compiler
vendor is providing garbage collection.

Basically, it is very desirable to declare a pointer
(or reference) as "weak". If the only pointer to an
object is weak, then that object is still collected.
This capability is present in quite a few garbage
collected languages, but not in C++. It would use the
obvious syntax, for example:

 UserClass * weak anObject;

Perhaps the "restricted" qualifier is also needed from
the latest C standard, but that is a separate issue.

The weak qualifier is very useful when you want to
build collections of things which are to be collected
whenever all other pointers are removed.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 16 May 2001 15:14:10 GMT
Raw View
Michael Lee Finney wrote:
...
> So, please, don't reject a change just because it is
> "merely" syntactic sugar. Instead, look for more
> sugar!

The fact that something is "merely" syntactic suger raises the bar: it
has to be substantially more useful to justify adding it to the language
than would be the case if it were the only way to achieve a desireable
end. We most definitely should not look for "syntactic suger" as
valuable in its own right - there's literally no limit to the amount
that could be added. Syntactic suger makes one special case easier to
handle, at the cost of making the language as a whole a little more
complicated. Add enough syntactic suger to the language, and almost
everything would be a special case.

Let's consider an ancient piece of syntatic suger as an example: "+=". I
love it! It significantly simplifies a very commonplace construct,
particularly when the LHS is a very complicated expression. However, it
adds a token that both humans and compilers must learn to parse. It
makes legal syntax that otherwise would not be, with a corresponding
reduction in the compiler's ability to detect errors. It requires that
an extra paragraph or two be added to the standard, with a corresponding
reduction in the ease of reading the standard, and a corresponding
increase in the ease with which inconsistencies and misunderstandings
can creep in. These are all very minor disadvantages compared to the
advantages of "+=", but it would be a bad idea to assume that the
advantages of syntactic suger always outweigh the disadvantages.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 16 May 2001 15:15:40 GMT
Raw View
Francis Glassborow wrote:

One more idea:

Make a failed assert undefined behaviour in NDEBUG mode
(but keep the fact that the expression isn't evaluated at runtime
in this case).

Rationale:

A failed assertion usually means something went wrong. That is,
the result of the program is most probably undefined anyway (not
necessarily in the sense of the standard, but in the sense of the
expected/intended program logic).

Making failed assertions undefined allows the compiler to optimize
on assertions.

Example:

void foo()
{
  int x = foo();
  if (x < 0)
    x += bar();
  assert(x >= 0);
  bar(x/2);
}

If the compiler knows that x >= 0, then it can replace x/2 by
x >> 1 if that is faster. OTOH, in NDEBUG mode the last line
may be reached even if x<0. In that case, x/2 and x >> 1 are
possibly different, and therefore the compiler cannot make the
optimization.

Now, if x<0, the program is buggy (otherwise the assert wouldn't
be there), and it's not unlikely that bar(x/2) would fail or
behave unpredictable anyway. Therefore the compiler should be
allowed to optimize x/2 to x >> 1 even with NDEBUG defined,
because it only changes the behaviour if the program is already
broken anyway.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 16 May 2001 18:46:25 GMT
Raw View
In article <3B0271C0.216DD526@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:

>You and Francis are talking about two different kinds of undefined
>behavior. As Francis rightly points out, a lot of behavior is undefined
>simply because making it defined would require implementations to
>consider an entire program as a whole before fully translating any of
>it, because it can only be detected by examining the source code on a
>whole-program basis.

I suspect that you assume that, in the name of efficiency, there has to be
a static (compile time) analysis, which in its turn has to do with the
primitive hardware architecture of todays computers.

Those issues (of which I have not yet been shown any examples of) I figure
can be resolved with a dynamic (runtime) analysis, but with a penalty in
runtime performance.

So one is left with a tradeoff -- lots of undefined behavior but with the
benefits of a static analysis providing quick runtime code versus safe
programing using dynamical analysis but with the disadvantage of slow(er)
runtime code.

In the future, as computers become faster, the dynamical analysis picture
will become more feasible as it decreases the costly programming time. As
this happens, one may perhaps see hardware architectures supporting this
development.

As for C++, it is not possible to remove the features that enables it to
produce fast code, so one will by that be forced to keep the static
analysis and the resulting undefined behavior it is causing. In fact, C++
needs even more low level programming, in order to help up embedded,
systems and, paradoxically, some types of dynamic programming.

But on the other hand, C++ will need to support safer programming as well,
making use of the dynamic analysis.

So, therefore I think that one may attempt to layer the language: In the
upper layers, one perhaps does not permit the "undefined" clause. But as
needed for performance, one should be able to make use of the lower layers
with its static analysis.

This is not so difficult to achieve in practise: For example, one can
build a class with a safe interface but relying on fast but unsafe
implementation details. The implementation of such a class could start
with high level, but slow constructs, and then one is moving on to lower
levels, when optimizations are needed.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Wed, 16 May 2001 19:58:53 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:hH9tdQAx8kA7EwR9@ntlworld.com...
> These days, keywords such as 'auto', 'register' and increasingly
> 'inline' are also superfluous to requirements.

A very useful meaning of 'register', which fits with an
intuitive physical reality, though not compatible with
the current language, would be to mean that the address
of the variable is never leaked.  I.e.

  void g(int &);
  int h();

  int f()
  {
    register int x; int y;
    ...
    g(x);      // x spilled
    ...
    y = h();   // No need to spill x here
  }

Without 'register', the compiler is forced to spill x at
function calls on paths leading from the original
address-taking, in case g and h turn out to be

  int *global_ptr;
  void g(int &p) { global_ptr = &p; }
  int h() { return *global_ptr; }



---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Wed, 16 May 2001 20:15:39 GMT
Raw View
"Tim Sharrock" <tim@sharrock.org.uk> wrote in message
news:2pejftc9mp58apol1ggd7f2idfblnc82kg@4ax.com...
> I would like to be able to use standard containers optimised for space.
>
> std::vector::reserve, for example is specified in such a way that there
> you can provide a minimum value for the capacity, but not a maximum.

For optimization lovers, I think there is a container that's needed:
buffer<T>. I know people who can't use vector because their performance
needs are too demanding. An std::buffer<T>:

* would provide a subset of vector's functions

* would hold only the pointer and the size

* would provide methods such as resize_nocopy, resize_noinit, and
resize_nocopy_noinit, that allow precise control of allocation

* would shrink when resized to a smaller size

Basically an std::buffer<T> is a dynamic buffer that allow the user fine
control over what's going on. In particular, std::vector<T> would use a
buffer as implementation. In addition, the vector would hold the effective
size.


Andrei


---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 20:46:40 GMT
Raw View
In article <3B026BEF.428F26CB@wizard.net>,
kuyper@wizard.net says...
> Michael Lee Finney wrote:
> ...
> > So, please, don't reject a change just because it is
> > "merely" syntactic sugar. Instead, look for more
> > sugar!
>
> The fact that something is "merely" syntactic suger raises the bar: it
> has to be substantially more useful to justify adding it to the language
> than would be the case if it were the only way to achieve a desireable
> end. We most definitely should not look for "syntactic suger" as
> valuable in its own right - there's literally no limit to the amount
> that could be added. Syntactic suger makes one special case easier to
> handle, at the cost of making the language as a whole a little more
> complicated. Add enough syntactic suger to the language, and almost
> everything would be a special case.

Here, I have to disagree. My opinion is that when
something is "merely" syntactic sugar it does (or at
least should not) raise the bar. Just because
something can be accomplished does not mean that it is
very usable. You can do OO programming in C, so why
have all of the syntactic sugar present in C++ to
support that?

I do support the idea that, as far as possible,
syntactic sugar should not be a special case. It
should apply in some general fashion.

> Let's consider an ancient piece of syntatic suger as an example: "+=". I
> love it! It significantly simplifies a very commonplace construct,
> particularly when the LHS is a very complicated expression. However, it
> adds a token that both humans and compilers must learn to parse. It
> makes legal syntax that otherwise would not be, with a corresponding
> reduction in the compiler's ability to detect errors. It requires that
> an extra paragraph or two be added to the standard, with a corresponding
> reduction in the ease of reading the standard, and a corresponding
> increase in the ease with which inconsistencies and misunderstandings
> can creep in. These are all very minor disadvantages compared to the
> advantages of "+=", but it would be a bad idea to assume that the
> advantages of syntactic suger always outweigh the disadvantages.

Here is an excellent example. You have not only +=,
but also -=, *=, /= and a whole set of additional
operators. Actually, almost all of the operators,
assignment or not, fall into the category of syntactic
sugar. And quite a bit of the standard is devoted to
that.

Instead, suppose we extend the preprocessor as
follows...

First, add a #token preprocessor directive

   #token string

for example:

   #token "*="
   #token "/="
   #token "%="
   #token "+="
   #token "-="
   #token "<<="
   #token ">>="
   #token "&="
   #token "^="
   #token "|="

where the intent is that when the preprocessor
encounters a #token, it adds a token to the lexical
scanner which is easy or hard, depending on how the
lexical scanner is written. Scanners generated via
tools can't do this very easily, but hand written
scanners can represent tokens in a dynamically
updatable trie (or alternate structure) which can be
updated on the fly. Yes, I have written such a lexical
scanner (in C++) and as far as I can tell it is as
fast as a hand written, custom built scanner and
faster than generated scanners.

Next, add the preprocessor directives

   #operator prefix(n)  <token>
   #operator infix(n)   <token>
   #operator infix(n)   <left token> <right token>
   #operator postfix(n) <token>
   #operator matchfix   <left token> <right token>
   #operator brackets   <left token> <right token>
   #operator function   <left token> <right token>

where n is the precedence level. A larger value binds
more tightly. Thus

   #operator prefix(10) >+

would define the >+ list concatenation operator. Any
operator defined in this manner may be overloaded by

   operator <token>()
   operator <left token> <right token> ()

if it is unambiguous or

   prefix operator <token> ()
   infix operator <token> ()
   postfix operator <token> ()
   matchfix operator <left token> <right token> ()
   function operator <left token> <right token> ()

where prefix operators have one parameter (or zero as
class members) and postfix operators have two
parameters (or one as class members) where the second
parameter is always of type int and may not have a
name. If the "postfix operator" form is used, then
only one parameter may be used. This allows the
compiler to avoid passing a useless parameter. Infix
operators have two parameters (or one as a class
member). Care must be used when the same operator is
used as both prefix (or postfix) and infix. This
normally occurs for the - operator. E.g. "a - b" or "-
b", but there are no instances (in C++) of postfix
operators also being used as infix operators.

Note: If the same operator is available as a matchfix
      operator and as a function operator, function
      operators are recognized immediately following a
      name (possibly separated by white space). In all
      other cases the matchfix operator will be
      recognized. Thus

         #operator function ( )
         #operator matchfix ( )

Now, it is possible to remove everything in the
compiler with respect to almost all of the operators
and instead replace it with a general mechanism to
accept a dynamic definition of operators.

Now, assuming that there is a <standard> header as I
have suggested before which is automatically included
by the compiler just before reading a translation
unit, all of the conventional operators can be defined
there.

That means that all of those operators can be taken
out of the C++ grammar, making C++ a much smaller
language, and the definition of those operators can be
moved to a separate section which would be sort of in
between the compiler and library.

So, by generalizing the solution to getting syntactic
sugar for += we instead provide syntactic sugar for
all user defined operators -- which is something that
I want very much. At the same time, the grammar for
C++ can be reduced in size. The increase in effort
required to handle the dynamic operator definitions is
offset by the reduction in effort required to
implement the existing operators as special cases.

If you do enough in this direction then the "core" C++
language is reduced substantially so that it primarily
is concerned about the "essence" of C++ while leaving
the exact details of many things to be defined to the
compiler in the <standard> header, which of course,
would be a separate part of the standard.

One of the advantages of syntactic sugar is that it
can frequently reduce complexity. But, even where the
complexity is increased for the compiler, if it is
decreased for the programmer then it is substantial
gain. Too many people on the standards committee are
overly concerned with how hard it is to implement
whereas most of us are more concerned with how hard it
is to use.

P.S. One caveat here, one consideration here is that
some operators such as && cannot be correctly
implemented in C++ without additional extensions
(which I have previously suggested).

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 20:52:47 GMT
Raw View
In article <3B0271C0.216DD526@wizard.net>,
kuyper@wizard.net says...

> That, on the other hand, is example undefined behavior that is there in
> order to make it feasible to implement C++ on a wide variety of
> platforms. If Mark Blewitt's suggestion that undefined behavior be
> eliminated were actually carried out, I think you'd find that there
> would be a drastic reduction in the number of platforms on which
> conforming C++ implementations were possible. The number would probably
> drop to either 0 or 1, depending upon how certain issues were resolved.

While that is a very good point, perhaps there are
some compromises possible. While I suspect that you
can eliminate all undefined behaviour and still leave
C++ viable for most machines, nevertheless, you could
make some reasonable assumptions.

For example, there are a number of undefined
behaviours which could be eliminated by making the
assumption that the compiler is generating code for a
2's complement machine. While, historically, there
have been other machines, I think that IS the
essential word here -- "historically".

Are there ANY modern machines which are not 2's
complement based? I don't know of any. I do know of
some interface hardware which sends its data in odd
formats, but not the primary processor. Are there even
any older machines for which new compilers are being
written which are not 2's complement?

I think this assumption would have essentially zero
impact on the number of possible conforming C++
implementations.

Another possibility is to assuming that integers are
available as power of two. Here, there would be some
diminishing of market because there are apparently
some DSPs which have 40 bit integers (according to
recent posts). However, are full blown C++ compilers
being implemented for DSPs? Do we really care if a
fully conforming C++ can't be implemented on the
occassional DSP? Like 2's complement, this is
something that always seems to be the case for modern
processors.

Even for those DSPs, apparently 1, 2 and 4 byte
integers are available, it is only the 5 byte integer
which is outside of bounds. There is nothing to say
that given 1, 2 and 4 sizes that the "extra" size
couldn't be made available in a full conforming
compiler.

It might not be possible to eliminate some of the
assumptions about pointers. There might still be some
word addressed machines around or some Harvard
architecture machines around.

I think that a more comprehensive survey of hardware
which is being used as the target of new C++ compilers
would allow more assumptions to be made which in turn
would substantially reduce the amount of undefined
behaviour in the standard.

Consider Java. It has made quite a few of these
assumptions. While it may have gone further than we
would like in that direction, nevertheless, I don't
see a lot of complaining that Java can't be
implemented on this or that platform because of the
assumptions.

Its past time to drop support for archaic hardware.
Hardware designers have tended to arrive at a
consensus, so why shouldn't language designers take
advantage of that consensus.


> > As far as dereferencing null pointers is concerned,
> > there is no reason that when "0" is converted to a
> > pointer that it cannot actually point to some read
> > only area of memory which contains a virtual object,
> > all of whose vptrs go to code that throws an
> > exception. That should should have a zero cost.
>
> On many platforms, the most natural implementation of integer-pointer
> conversion is equivalent to keeping the bit pattern unchanged.
> Unfortunately, the bit pattern corresponding to an integer with a value
> of 0 isn't necessarily the bit pattern of a legal address. Even if it is
> a legal address, it might be one that's reserved to the operating system
> for some special purpose, thereby preventing a C++ implementation from
> filling it in the fashion described. On such platforms, your suggestion
> would require adding a null-pointer test to every pointer dereference.
>
> Elimination of undefined behavior would require that a C++
> implementation emulate memory protection on platforms where it isn't
> provided by the hardware or operating system already. That can be a very
> significant cost.

The conversion of integer to pointer could withstand
the cost of a zero check and replacement with some
other value (and vice-versa for the opposite
conversion). That conversion is very rare in code. The
most important conversion is that of the constant 0 to
a pointer which the compiler can detect.

I do not suggest the overhead of checking each pointer
dereference (although that could be part of a
debugging compile). You can substantially reduce the
number of undetected null pointer dereferences without
going that far. It doesn't have to be all or nothing.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 21:08:26 GMT
Raw View
In article <9dtcnt$jr2g3$1@ID-49767.news.dfncis.de>,
anthwil@nortelnetworks.com says...
> "Michael Lee Finney" <michael.finney@acm.org> wrote in message
> news:MPG.156b43fd86ad209698972d@news.lynchburg.net...

> Why does this require that we lose separate compilation? It seems to me that
> all the information about a single translation unit (which headers it
> includes (and which parts of those headers it depends on), which template
> instantiations it needs, etc) could be included in an object file generated
> from that translation unit as a single entity. When linking the files
> together into the final executable (or shared library or DLL or whatever),
> then the compiler would be able to automatically detect whether an object
> file was out of date wrt another, and either recompile automatically (if the
> source was available) or flag an error (if it wasn't). Also, when
> recompiling a single translation unit, it could be checked against the
> information in the pre-existing object file for changes.

Everything you say is true. But, if you don't give up
separate compilation then code optimization needs to
be moved out of the compiler and into the linker.
There are many optimization algorithms which only work
with complete code analysis. While they can be adapted
to handle a set of explicit inports and exports (which
is similar to what happens due to separate translation
units) they have to know things such as all declared
classes. Many of the optimization gains made by these
algorithms can be significant, but they aren't
available with separate translation units.

> I don't like the thought of messing with order of declaration. As for
> optimisation, when generating object code, the compiler could store not only
> the general no-assumptions-about-usage object code for a function, but also
> enough additional information to enable it to further optimise the function
> at final link time based on usage. e.g. if a function is passed two
> references, then in general it can assume nothing about whether or not they
> refer to the same object. If in practice, they always refer to the same
> object, then the compiler can eliminate one of them at final link time. If
> the required additional information about a function is not present (e.g. it
> was written by a third party), or the required usage information is not
> present (it is used by a third-party library without additional info), then
> the pre-generated no-assumptions object code can be used.

How is eliminating order dependency really "messing
with order of declaration"? Everything currently valid
is still valid. And things that should be valid become
valid. And I stop driving myself crazy trying to make
the compiler happy via the empirical discovery of an
order of declaration for inline functions (and
sometimes classes). Let the blasted compiler read the
source file twice. Once to discover all of the
definitions (storing them for later) and once to
actually compile. Not really a big deal -- especially
as the second pass is usually on the stored,
preprocessed text.

> > IBM's compiler let you specify header files to be used
> > in the project, but they are global across the
> > project. You can, however, still specify header files
> > the "standard" way for those header files which must
> > be seen only in one source file.
>
> Project-wide includes seem dangerous to me - each file depends on things not
> explicitly identified within it. Thus if you want to reuse the code
> elsewhere, it is not clear what it depends on.

The "One Definition Rule" says that the same name
can't have two different definitions -- even in
different translation units. Most compilers don't
enforce that (IBM's VisualAge C++ compiler does), but
its consequence is that any header file used in any
translation unit can be included in any other
translation unit without having any effect other than
possibly reducing compilation speed.

The only exception is macro expansion which may or may
not be global. That is handled by the IBM compiler by
still allowing the normal #include which is processed
in the normal manner. But all of the other headers can
be given to the compiler and processed just once.

I don't see how potential reuse of the code changes
this.

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Wed, 16 May 2001 21:18:57 GMT
Raw View

Michael Lee Finney wrote:

> Are there ANY modern machines which are not 2's
> complement based? I don't know of any. I do know of
> some interface hardware which sends its data in odd
> formats, but not the primary processor. Are there even
> any older machines for which new compilers are being
> written which are not 2's complement?

Define modern?  If you mean computers that are running
C++ today, yes there are such machines.  You don't
achieve portability by denying that certain machines
ought not to exist.

>
> Another possibility is to assuming that integers are
> available as power of two. Here, there would be some
> diminishing of market because there are apparently
> some DSPs which have 40 bit integers (according to
> recent posts). However, are full blown C++ compilers
> being implemented for DSPs? Do we really care if a
> fully conforming C++ can't be implemented on the
> occassional DSP? Like 2's complement, this is
> something that always seems to be the case for modern
> processors.

There exist machines running C++ today that have 20, 24,
36 bit integers.  Do you want to extend this restriction
to all datatypes.  The Pentium has 80 bit floating point.
This is now perhaps the most popular C++ platform in the
world.

I can't see what your complaint is with this (I can
understand the right shift issue).

> Its past time to drop support for archaic hardware.
> Hardware designers have tended to arrive at a
> consensus, so why shouldn't language designers take
> advantage of that consensus.

I disagree with your determination that "everything that
I'm not using is archaic."  In actuality the issues here
are trivial.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 16 May 2001 21:57:23 GMT
Raw View
Nicola Musatti wrote:
>
> While we're at it...
>
> Joseph Gottman wrote:
> [...]
> > template <class X, class Y>
> > polynomial<typeof(X() + Y())> operator+(
>
> ... it should be legal to write the above as:
>
> polynomial < typeof ( X + Y ) > operator+ (
>
> And possibly also:
>
> template <class X, class Y> typedef typeof(X+Y) polynomial;
> template <class A, class B> polynomial<A,B> operator+(...

Another idea: What, if - instead of a typeof operator - it
would be allowed to use an expression as template argument
where a type argument is expected, and it would be taken as
the type of the expression to be inserted here. Then typeof
could be implemented in terms of this. Advantage: no keyword.

Example: typeof implementation

template<class T>
 struct type_traits
{
  typedef T type;
};

#define typeof(expr) type_traits<(expr)>::type

Of course, the type_traits would probably be more elaborate,
it could f.ex. give const and non-const versions of the type,
etc, which would be useful even with normal type arguments.

Another use of the feature would be s.th. like

template<class T1, class T2>
 math::vector<T1()+T2()> operator+(math::vector<T1> v1,
                                   math::vector<T2> v2);

which is even more concise than the version with typeof.

Also a declare macro would be easy to write:

#define declare(var, expr) type_traits<(expr)>::type var(expr)

Then you could write f.ex.

std::vector<int> v;
declare (a, v.begin());
declare (b, v.end());

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 17 May 2001 03:06:00 GMT
Raw View
Nicola Musatti wrote:
...
> defaulting to one is just misleading. In such cases, defaulting to zero
> may prove a bad choice because is often a reasonable value and may
> actually make bugs more evident.

Was that a typo? "less" seems to fit the context better than "more".

---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 17 May 2001 11:24:07 GMT
Raw View

"James Kuyper Jr." wrote:
>
> Nicola Musatti wrote:
> ...
> > defaulting to one is just misleading. In such cases, defaulting to zero
> > may prove a bad choice because is often a reasonable value and may
> > actually make bugs more evident.
>
> Was that a typo? "less" seems to fit the context better than "more".

Oops, you're right!

Thanks,
Nicola Musatti

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Tue, 15 May 2001 17:27:56 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.156a6b7532c00bc98972b@news.lynchburg.net...
> In article <bbajqVAuHIA7Ew2Y@ntlworld.com>,
> francis.glassborow@ntlworld.com says...
> > No, much of current undefined behaviour is because anything else places
> > an unreasonable requirement on compilers in a context of separately
> > compiled translation units.
>
> Perhaps its time to drop the notion of separately
> compiled translation units. This notion does not bring
> much benefit to the table and yet causes tremendous
> problems.  And the only compiler that compiles
> everything together (the IBM VisualAge C++ 4.0 or
> above) is also the only compiler that truly enforces
> the single declaration rule.
>
> In practice (and I maintain programs across multiple
> platforms) I find that every target I build has to
> have its own makefile and the object files cannot, in
> general, be shared between projects because the
> compiler options tend to be different (RTTI - yes/no,
> multithreaded support - yes/no, char as
> signed/unsigned - yes/no, etc.)
>
> And the benefits of eliminating that restriction are
> tremendous -- starting with optimization.

Are you saying that if you change one source file, every other file in your
project has to be recompiled?

That is the benefit of separate compilation - each translation unit (within
a project) can be compiled separately, and only recompiled if its direct
dependencies change. If we lose that ability, compile times for large
projects will become unrealistically long, as (say) 10000 source files will
have to be recompiled every time someone makes a one character change in any
file, even if nothing else really depends on it.

Certainly there are benefits to eliminating separate compilation, with
regard to the final compiled program - fewer bugs due to more checking,
better optimisation etc. However, the cost for this benefit is very large.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 17:28:15 GMT
Raw View
In article <MPG.156a6b7532c00bc98972b@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>Perhaps its time to drop the notion of separately
>compiled translation units. This notion does not bring
>much benefit to the table and yet causes tremendous
>problems.  And the only compiler that compiles
>everything together (the IBM VisualAge C++ 4.0 or
>above) is also the only compiler that truly enforces
>the single declaration rule.

There is no such rule, I think you meant 'The One Definition Rule'.
Throwing away separate compilation would be going much further than
VisualAge C++, it would throw out the entire concept of libraries and so
would be unacceptable to any and all library vendors. It would also
seriously affect development as it would no longer be possible to just
compile against, as yet, unimplemented headers.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Alexei Zakharov" <zakharov_alexei@hotmail.com>
Date: Tue, 15 May 2001 17:28:27 GMT
Raw View
> So, what do we want?

Delegates.

This can be a very useful feature and this idea is around for many years.

That's how Bjarne Stroustrup describes it in "The design and evolution of
C++":
    class B { int b; void f(); };
    class C : *p { B* p; int c; };
    void f( C* q )
    {
        q->f();  //  meaning q->p->f();
    }
Then follow problems with such design:
    [1] Functions in the delegating class do not override functions of the
class delegated to.
    [2] The function delegated to cannot use functions from the delegating
class or in other ways "get         back" to the delegating object.

[1] requires changing the virtual table of the delegated object.  But the
compiler has no chance to know when *p is initialized to do that.  Another
problem here is that *p can be accessed, so it can be changed and we lose
our new virtual table.

By changing the syntax to something like:

class C : public *B
{
public: C( B * b ) : B( b ) {}
};

the complexity of the problem can be reduced to some extent.  Now we know
exactly where the pointer of the delegated class is initialized and there's
no way to change it.

As for [2], perhaps, there's no need to do it, similar to how base class
can't access derived one.

Does anyone know the current state of progress of this idea, and is there
any chance to get it in some future C++ standard?

Alexei Zakharov.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 17:29:05 GMT
Raw View
In article <remove.haberg-1505010950140001@du135-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>
>I think the reason that people want to get rid of the preprocessor is that
>in the past it has been used in order to get around limitations in the
>C/C++ languages.

Not at all, the fundamental reason is that it knows nothing about scope,
and it is actually difficult to make it otherwise.

>
>However, a proper preprocessor can also be used in order to produce proper
>C++ output after the preprocessing, which is good especially for automated
>situations. Making it a separate program (disregarding the fact that the
>preprocessor already is a separate program) does not integrate the process
>in the same way.

Sorry, but I do not follow that.

>
>And you are as likely to get rid of the preprocessor from C/C++ as the
>word "undefined" from the C++ standard, for the same reasons, namely
>efficiency.

There are very few uses that I have for the preprocessor, and if only
certain implementors would stop using it my code would be much more
portable.

>
>For example, I haven't seen any suggestions on how to get rid of the
>header macros that one has to put in order to make sure it isn't read
>twice by the translation unit.

Where have you been for the last ten years? That is actually easy and
might even be dealt with in the next release of the standard, at the
same time we need to reconsider the way header files are 'included'. Now
support conditional compilation and feature checks some other way and
the pre-processor is just about dead.

>If you want to get rid of the preprocessor,
>such and all other current preprocessor uses must somehow be covered up.
>
>So one can just as well think of prudent ways to enhance the preprocessor.

No, design and write a full featured pre-processor from scratch and
ensure that it is not required by users who do not want to have it.

>
>Possibly you have a scare there: People are afraid of that a better
>preporcessor will make folks using that instead of the proper C++ feature.
>That might have been the case before they got used to the current features
>(tempalets etc).

Not scared, just having a clear understanding as to what belongs in the
language as such and what should be additional tools. I think that the
pre-processor should be just as much an added tool as a programmers
editor or a version of lint.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 17:29:24 GMT
Raw View
In article <remove.haberg-1505010950240001@du135-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>>No, much of current undefined behaviour is because anything else places
>>an unreasonable requirement on compilers in a context of separately
>>compiled translation units.
>
>So what do you have in your mind here? -- Please give an example.

void foo(int &, int &);
int main(){
  int i=0, j=0;
  foo(i, j); // no reason to worry
  foo(i, i); // no way to know if there is a problem
}

Please note that aliasing problems can be very obscure and require deep
analysis of code to identify.






Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 17:29:20 GMT
Raw View
In article <3B00DB8A.8A389E2D@racon-linz.at>, Heinz Huber <hhuber@racon-
linz.at> writes
>I didn't mean to propose a general implicit (I think you meant implicit above)

I did:(

>conversion from int to enum. What I want is the compiler to use an implicit
>conversion only in the following (and equivalent) case:
>enum Test { t1, t2 };
>Test v1 = t1 + t2;      // OK since operator on two values of Test

IOWs you want exactly what I do a built-in default operator+ for each
enum type (but which operators should be provided as defaults?

>Test v2 = t1 + 1;       // to be defined whether OK since operator on one value
>of Test

Not logical to allow that one as it implies a conversion of the second
argument.

>Test v3 = 1 + 2;        // definitly not OK!!!

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: LR <lruss@superlink.net>
Date: Tue, 15 May 2001 17:30:00 GMT
Raw View
Francis Glassborow wrote:
> I do not
> think tinkering with pre-processors will meet with much favour, the
> trend would be to get rid of it rather than replace it.

I know that pre-processors can be badly abused, but I think that they
still have a few legitamate uses.

Besides which, getting rid of it would break plenty of code.

I guess that I'd be opposed to the trend.

LR.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Tue, 15 May 2001 18:49:08 GMT
Raw View
In article <9dqp1n$je3m0$1@ID-49767.news.dfncis.de>,
anthwil@nortelnetworks.com says...
> "Michael Lee Finney" <michael.finney@acm.org> wrote in message
> news:MPG.156a6b7532c00bc98972b@news.lynchburg.net...
> > In article <bbajqVAuHIA7Ew2Y@ntlworld.com>,
> > francis.glassborow@ntlworld.com says...
> > > No, much of current undefined behaviour is because anything else places
> > > an unreasonable requirement on compilers in a context of separately
> > > compiled translation units.
> >
> > Perhaps its time to drop the notion of separately
> > compiled translation units. This notion does not bring
> > much benefit to the table and yet causes tremendous
> > problems.  And the only compiler that compiles
> > everything together (the IBM VisualAge C++ 4.0 or
> > above) is also the only compiler that truly enforces
> > the single declaration rule.
> >
> > In practice (and I maintain programs across multiple
> > platforms) I find that every target I build has to
> > have its own makefile and the object files cannot, in
> > general, be shared between projects because the
> > compiler options tend to be different (RTTI - yes/no,
> > multithreaded support - yes/no, char as
> > signed/unsigned - yes/no, etc.)
> >
> > And the benefits of eliminating that restriction are
> > tremendous -- starting with optimization.
>
> Are you saying that if you change one source file, every other file in your
> project has to be recompiled?

Not at all. The IBM VisualAge C++ 4.0 compiler builds
a database as it compiles. That includes template
instantiations. Nothing is ever compiled twice. As I
understand it, even functions within a translation
unit are not recompiled when something else changes.
IBM has shown that you can do a tremendous job in that
way, substantially reducing both original compile time
(no recompiling template instantiations) and recompile
time (no recompiling anything which didn't change). In
the latter case, it does have to at least compare the
source code to inside of a changed translation unit to
find the areas which have changed. But that can be as
fast as grep.

> That is the benefit of separate compilation - each translation unit (within
> a project) can be compiled separately, and only recompiled if its direct
> dependencies change. If we lose that ability, compile times for large
> projects will become unrealistically long, as (say) 10000 source files will
> have to be recompiled every time someone makes a one character change in any
> file, even if nothing else really depends on it.

With IBM's approach, changes to things such as
comments do not force a recompilation. Is that true of
your current compiler?

> Certainly there are benefits to eliminating separate compilation, with
> regard to the final compiled program - fewer bugs due to more checking,
> better optimisation etc. However, the cost for this benefit is very large.

I think the cost is much smaller than most people
realize. Keeping separate source files is fine for
code organization, but the compiler should be told all
of the necessary source files, any additional object
files or libraries, its options and what it is to
produce. Let the compiler handle things like
determining what has actually changed, let it do
optimization across the entire program, even let it
process header files only one time (when possible).
Let the compiler worry about order of declaration --
which is one REALLY nice benefit of IBM's compiler. I
hate trying to order inline functions to make sure
that a one pass compiler can handle things right. I
should NEVER have to worry about what order I wrote
things in my source code. Let the blasted compiler
read the source code twice!

IBM's compiler let you specify header files to be used
in the project, but they are global across the
project. You can, however, still specify header files
the "standard" way for those header files which must
be seen only in one source file.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Tue, 15 May 2001 18:58:48 GMT
Raw View
In article <s8peTxAg5PA7EwDg@ntlworld.com>,
francis.glassborow@ntlworld.com says...
> In article <MPG.156a6b7532c00bc98972b@news.lynchburg.net>, Michael Lee
> Finney <michael.finney@acm.org> writes
> >Perhaps its time to drop the notion of separately
> >compiled translation units. This notion does not bring
> >much benefit to the table and yet causes tremendous
> >problems.  And the only compiler that compiles
> >everything together (the IBM VisualAge C++ 4.0 or
> >above) is also the only compiler that truly enforces
> >the single declaration rule.
>
> There is no such rule, I think you meant 'The One Definition Rule'.
> Throwing away separate compilation would be going much further than
> VisualAge C++, it would throw out the entire concept of libraries and so
> would be unacceptable to any and all library vendors. It would also
> seriously affect development as it would no longer be possible to just
> compile against, as yet, unimplemented headers.

Yes, I meant the "One Definition Rule", but forgot its
name.

I don't think that you throw out the idea of libraries
at all. When you are compiling a library, the compiler
does the same thing it does for a program. It has a
list of "imports", I.e. undefined functions and data
and a list of "exports" - there does need to be a
mechanism to determine those. Most compilers have the
ability now, but not in a standard form.

Perhaps, something more explicit should be added to
the language "import declaration;" and "export
declaration".

Then, when a class (even a template class) is being
exported, the compiler will compile all methods which
are non-inline.

As far as unimplemented headers is concerned, that can
be treated like an import -- the worst case would be
to create a "stub" to allow program linkage, but there
is no reason that you couldn't tell the compiler to
not perform the final link since the program wouldn't
be executable anyway. However, how often do you do
that? I find it fairly rare.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 15 May 2001 19:43:20 GMT
Raw View
In article <MPG.156a6b7532c00bc98972b@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>Perhaps its time to drop the notion of separately
>compiled translation units.

In fact, it is important to go the other way around: Make it possible to
build different translation units that must be recompiled as little as
possible.

One part of this is the fragile base class problem, that is if a header is
changed, all translation units reading that header must be recompiled.

Perhaps methods to avoid that could be a topic for the next standard.

Java makes a runtime lookup of the method offsets in order to avoid that:
The offsets are then cached, in order to speed up subsequent lookups.

Having this as a general C++ feature for all classes would probably be
unacceptable because of the runtime overhead it generates, but one can
admit that. It could be added if one decides to allow classes (upon
request) to have runtime member function lookup tables (I think the Java
term might be "reflections").

Another method that comes to my mind is that one defines a lower level
"translation language" that the headers are converted to before the actual
compilation, with the property that if two translated headers are the
same, the interfaces of the object code translation units will be
identical. Then if the headers are changed but that does not change the
interface of the object code translation units according to this
translation model, no recompilation is needed.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 15 May 2001 19:44:04 GMT
Raw View
In article <VB1AcWASJSA7EwXJ@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>I think the reason that people want to get rid of the preprocessor is that
>>in the past it has been used in order to get around limitations in the
>>C/C++ languages.
>
>Not at all, the fundamental reason is that it knows nothing about scope,
>and it is actually difficult to make it otherwise.

I don't see why one would want to introduce scope in to the preprocessor,
because that is something that belongs to the actual C++ language, nor do
I see why one would want to get rid of the preprocessor for that reason.

>>However, a proper preprocessor can also be used in order to produce proper
>>C++ output after the preprocessing, which is good especially for automated
>>situations. Making it a separate program (disregarding the fact that the
>>preprocessor already is a separate program) does not integrate the process
>>in the same way.
>
>Sorry, but I do not follow that.

People are of course using all kind of macro expansion programs, but if it
is not bundled with the compiler one cannot compile the code.

>>And you are as likely to get rid of the preprocessor from C/C++ as the
>>word "undefined" from the C++ standard, for the same reasons, namely
>>efficiency.
>
>There are very few uses that I have for the preprocessor, and if only
>certain implementors would stop using it my code would be much more
>portable.

Well, this might be the case for the code that you are running. But in
code that is expected to run on several different platforms always are
very full of preprocessor directives.

And in my application, writing automated C++ output via a parser, it
proves very difficult to do that directly or to use the preprocessor
because the latter is to primitive.

>>For example, I haven't seen any suggestions on how to get rid of the
>>header macros that one has to put in order to make sure it isn't read
>>twice by the translation unit.
>
>Where have you been for the last ten years? That is actually easy and
>might even be dealt with in the next release of the standard, at the
>same time we need to reconsider the way header files are 'included'.

I don't think it has anything to do with where one is spending the time:
Even if this or that feature is easy to do, one must first cover it up.

> Now
>support conditional compilation and feature checks some other way and
>the pre-processor is just about dead.

Well, you have to do those things before you will see the preprocessor
dying. Then it will be actual usage that will determine if it is dying;
not your wishes.

>>So one can just as well think of prudent ways to enhance the preprocessor.
>
>No, design and write a full featured pre-processor from scratch and
>ensure that it is not required by users who do not want to have it.

Actually, this is the approach I am arriving at in my project: I am
actually writing a "pre-pre-processor", that could be used to eliminate
the preprocessor entirely. Instead of generating a C/C++ header/source
files with lots of unreadable macros, I can use the macro program to
correct looking header/source files without any macros (except for what is
necessary given the current C/C++).

But for upwards compatibility, I do not think you will get rid of the
preprocessor.

Also, the preprocessor is not that very different from an completely
rewritten macro program: Some differences I make use of are definitions
within definitions and explicit manipulation of string objects (giving a
higher degree of control over the output).

So it may happen that writing an entirely new macro program from scratch
in the end can be viewed as an enhanced version of the current
preprocessor.

>>Possibly you have a scare there: People are afraid of that a better
>>preporcessor will make folks using that instead of the proper C++ feature.
>>That might have been the case before they got used to the current features
>>(tempalets etc).
>
>Not scared, just having a clear understanding as to what belongs in the
>language as such and what should be additional tools. I think that the
>pre-processor should be just as much an added tool as a programmers
>editor or a version of lint.

The preprocessor is clearly a separate language that in an unfortunate way
has been described in the standard as being a part of the C++ language
itself. It would be good if the standard made that separation much clearer
than it is now.

I think that the preprocessor differs from other tools in that it often is
needed in order to compile the programs that one pick down.

If you remove the preprocessor entirely, then it must be done in a way
that it does not cause people to start using another preprocessor program,
plus making sure that programs can be compiled without other tools than
the compiler (which isn't true, because often people use another macro
program "make" that must be used).

But your suggestion does not help up the fact that writing automated C++
output is very difficult, because semantically related features must be
written down in several different contexts (for example, class member
declarations and definitions and included headers).

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 22:58:37 GMT
Raw View
In article <MPG.156b45757716f6bc98972e@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>I don't think that you throw out the idea of libraries
>at all. When you are compiling a library, the compiler
>does the same thing it does for a program. It has a
>list of "imports", I.e. undefined functions and data
>and a list of "exports" - there does need to be a
>mechanism to determine those. Most compilers have the
>ability now, but not in a standard form.

I think you are entirely missing the root causes of undefined behaviour.
Unless the compiler sees the actual source code for the whole program at
one time (and object code is not good enough) it cannot diagnose a
considerable amount of undefined behaviour.

Yes, eliminating such things as dereferencing null pointers is possible
but only at a cost that many professional programmers do not want to
pay. It is like eliminating 'divide by zero', it can be done but only in
a costly way (at least on some platforms). Large scale general purpose
language targeted at multiple platforms have problems that single
platform languages (such as Java) do not have.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: LR <lruss@superlink.net>
Date: Tue, 15 May 2001 23:37:15 GMT
Raw View
Michael Lee Finney wrote:
> Perhaps its time to drop the notion of separately
> compiled translation units.

I'm not sure that I understand this, but a quick look at the standard
seems to imply that if we dropped that "notion," then compiled libs with
headers couldn't be distributed absent complete source code.

Or did I misunderstand you, and/or the standard?

If I did understand, then I'm sure that lots of people who distribute
proprietary libs would be a little upset.

Besides which, might this have an impact on compile times?

LR.

---
[ 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: pfkeb@localhost.localdomain (Paul F. Kunz)
Date: Tue, 15 May 2001 23:38:58 GMT
Raw View
bs@research.att.com (Bjarne Stroustrup) writes:

>    Support distributed programming
>
>  simple, clean, implementation-independent model
>  extended type information (to allow message composition, etc.)
>
>    Make the standard library central to bindings to other "systems"
>
>  e.g. SQL, CORBA, ...
>
   Having gained my first experience in OOP with the Objective-C
language on a NeXTStep platform, I think adding support for the above
would be of great value for C++.  And I don't think it is that hard to
do.  If one were to extend the virtual function table to include not
only the pointers to the member functions, but also their names, as a
string, their argment types, the names, types and offset of the data
members, etc. then a set of functions in a standard library can be
used for binding to the above mentioned by Bjarne.

   Both Java and Objective-C have this kind of information available
at run time along with a well defined API to access it.  They also
both have libraries for binding to SQL, and remote message
innovacation, etc.  The Cygnus folks had an experimental version of
the GCC C++ compiler that kept this kind of information as well.

   Also in the area of GUI toolkits, it seems many of them written in
C++ have invented some ad hoc way to connect GUI objects to
application code.  Qt's `signals' and `slots' for example.  I think
that would be unneccesary if more information were available at run
time.

   One would probably only need to do this for upper C++ classes,
i.e. for classes that have virtual functions.  Lower C++ classes,
i.e. no virtual functions, would still have 0 overhead.


P.S.

   You can look at Objective-C's implementation of using this kind of
infromation because the source code is part of the GCC distribution.
It is written in C by a young Danish student.  How much easier it
would be to implement it if C++ with STL were used.

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Tue, 15 May 2001 23:43:29 GMT
Raw View

Michael Lee Finney wrote:
>
> Not at all. The IBM VisualAge C++ 4.0 compiler builds
> a database as it compiles. That includes template
> instantiations. Nothing is ever compiled twice. As I
> understand it, even functions within a translation
> unit are not recompiled when something else changes.

Of course, it's a neat idea, too bad they broke the
standard behavior in it's implementation.  The ordering
of definitions in a TU ceases to have it's mandated order
in IBM's scheme.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 15 May 2001 23:43:51 GMT
Raw View
In article <ChHF0uAYQSA7Ew2$@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>>No, much of current undefined behaviour is because anything else places
>>>an unreasonable requirement on compilers in a context of separately
>>>compiled translation units.
>>
>>So what do you have in your mind here? -- Please give an example.
>
>void foo(int &, int &);
>int main(){
>  int i=0, j=0;
>  foo(i, j); // no reason to worry
>  foo(i, i); // no way to know if there is a problem
>}
>
>Please note that aliasing problems can be very obscure and require deep
>analysis of code to identify.

But this is resolved when introducing a conservative GC.

So I still think that introducing the suitable high level concepts will
get rid of the high level "undefined"'s.

There then remains the low level "undefined"'s: In order to get rid of
those, one will need better hardware support.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 23:44:14 GMT
Raw View
In article <remove.haberg-1505012142580001@du131-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>The preprocessor is clearly a separate language that in an unfortunate way
>has been described in the standard as being a part of the C++ language
>itself. It would be good if the standard made that separation much clearer
>than it is now.

Exactly, it is an entirely different language that should have
absolutely nothing to do with C++. It is a tool for managing source code
and preparing it for a (C++) compiler. I very much doubt that we would
have anything like the current pre-processor had it not been for C.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 03:46:47 GMT
Raw View
In article <3B017B4F.850E2E0B@spamcop.net>,
ron@spamcop.net says...
>
>
> Michael Lee Finney wrote:
> >
> > Not at all. The IBM VisualAge C++ 4.0 compiler builds
> > a database as it compiles. That includes template
> > instantiations. Nothing is ever compiled twice. As I
> > understand it, even functions within a translation
> > unit are not recompiled when something else changes.
>
> Of course, it's a neat idea, too bad they broke the
> standard behavior in it's implementation.  The ordering
> of definitions in a TU ceases to have it's mandated order
> in IBM's scheme.

What you say is true.

However, what they did was to relax the order of
definitions. They made the order irrelevant. Just the
way it should be on anything except a primitive,
1950's, single pass compiler. Why in world would
anyone want to shoot themselves in foot by requiring
the programmer to sort functions by usage when
compilers are MUCH better at it?

While there are some problems with standards
compliance, the compiler shows just what can be done.
And even so, the compiler is closer to the standard
than most other compiler's. Especially when it was
released (of course, like many other things, IBM has
dropped the compiler on all platforms except AIX). How
many other compilers enforce the "One Definition
Rule" across translation units?

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 05:36:35 GMT
Raw View
I want to bring up, and discuss, a point that has been
mentioned in the past when changes to C++ have been
proposed. It has not been mentioned this time around,
but almost certainly will be sooner or later.

I see far too often the statement that some change or
another is "merely" syntactic sugar. In spite of the
fact that is perhaps the best reason to make a change!

Syntactic sugar is one of the primary enablers of
progress.

Everyday use of arithmetic simply would not have
happened without the syntactic sugar of Arabic numeric
notation. Ever tried to multiply using Roman Numerals?

Matrix theory advanced very slowly until a good
notation developed.

Einstein's development of Tensor calculus was based on
the syntactic sugar of his tenor notation (later
extended to Holor notation, but knowledge of that is
not widespread).

Assembly language developed as syntactic sugar over
machine language.

Procedural languages developed as syntactic sugar over
assembly language.

Object oriented langagues (C++ in particular) have
developed as syntactic sugar over procedural
languages. There is nothing in C++ that you can't
(eventually, with a large enough budget) do in machine
language.

In advancing C++ we should be looking very hard to
find more syntactic sugar. A little here and there and
eventually you can substantially improve the language.

The basis of syntactic sugar is that you can write
something that is both more concise AND more readable,
and usually more writable as well.

One of the places this comes up is operator
overloading. Consider appending to the head or tail of
a list. Without syntactic sugar you have to write:

   aList.addHead(anObject)
   aList.addTail(anObject)

or to concatenate a list, you have to write:

   aList.concatenate(bList)

But, if you use the conventional list operators (found
in many textbooks), you can write:

   anObject +< aList
   aList >+ anObject

and to concatenate, you could write:

   aList || bList

This particular example is trivial. But the
accumulation of things like this brings a great deal
of power to the language. While we don't want another
APL, we also don't want another COBOL (we already have
another PL/1 <g>).

So, please, don't reject a change just because it is
"merely" syntactic sugar. Instead, look for more
sugar!

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 16 May 2001 05:41:54 GMT
Raw View
In article <remove.haberg-1505012142540001@du131-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>But this is resolved when introducing a conservative GC.

I have seen many claims for conservative GC but never this one. How it
solve problems such as the optimiser assuming that the two variables are
distinct, when the call passes the same one to both reference
parameters.

Do you understand the problems that lead to undefined behaviour?


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Julian Smith" <jules@REMOVETHIS.op59.net>
Date: Wed, 16 May 2001 05:42:23 GMT
Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> wrote in message
news:9dnqms$iugj3$1@ID-14036.news.dfncis.de...

> I think the same. Needless to say :o), I'd be happy if parts of Loki would
> be considered for standardization. It would be nice to have design
artifacts
> such as object factories, visitors, singletons, multiple dispatch engines,
> right in the standard library. A large fraction of projects can benefit of
> such design artifacts.
>
> Besides, smart pointers designed in the same way as in Loki would be very
> useful. To date, all smart pointer design problems raised by Loki's users
> could be solved without changing Loki::SmartPtr's implementation, and in
an
> elegant manner.

Loki uses templates in amazing ways, and a lot of the time the end result is
genuinely useful.

However, I sometimes think I'm watching a re-make of the C preprocessor
abuses of the past. In particular, the multimethods support falls far short
of the simple syntax described in the D&E, and the requirement to
exhaustively register types and functions explicitly makes it basically
unusable in real code I think.

If support for multimethods is to be added, then let's do it properly by
changing the language to support the D&E's `virtual' function parameter
syntax.

Then add access checking based on namespaces rather than classes, and maybe
we can get rid of /all/ member functions 8) .

- Julian
--
http://www.op59.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.research.att.com/~austern/csc/faq.html                ]





Author: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 16 May 2001 05:43:09 GMT
Raw View
In article <BJyFujAOQaA7Ew1v@ntlworld.com>,
francis.glassborow@ntlworld.com says...
> In article <MPG.156b45757716f6bc98972e@news.lynchburg.net>, Michael Lee
> Finney <michael.finney@acm.org> writes
> >I don't think that you throw out the idea of libraries
> >at all. When you are compiling a library, the compiler
> >does the same thing it does for a program. It has a
> >list of "imports", I.e. undefined functions and data
> >and a list of "exports" - there does need to be a
> >mechanism to determine those. Most compilers have the
> >ability now, but not in a standard form.
>
> I think you are entirely missing the root causes of undefined behaviour.
> Unless the compiler sees the actual source code for the whole program at
> one time (and object code is not good enough) it cannot diagnose a
> considerable amount of undefined behaviour.
>
> Yes, eliminating such things as dereferencing null pointers is possible
> but only at a cost that many professional programmers do not want to
> pay. It is like eliminating 'divide by zero', it can be done but only in
> a costly way (at least on some platforms). Large scale general purpose
> language targeted at multiple platforms have problems that single
> platform languages (such as Java) do not have.
>
> Francis Glassborow      ACCU
> 64 Southfield Rd
> Oxford OX4 1PA          +44(0)1865 246490
> All opinions are mine and do not represent those of any organisation

????????????????????????

I fear either we aren't communicating at all, or you
have answered a different post. While I am concerned
about undefined behaviour, that has no relationship to
my desire to eliminate independent compilation of
translation units.

My goals are more oriented towards optimization,
convenience and being able to include language
features that require compilation of everything
together.

The primary place where undefined behaviour annoys me
is signed right shift which I have long felt should be
strictly defined as an arithmetic shift -- at least
when compiled on a 2's complement machine (and are
there any other sorts in significant numbers today?).

As far as dereferencing null pointers is concerned,
there is no reason that when "0" is converted to a
pointer that it cannot actually point to some read
only area of memory which contains a virtual object,
all of whose vptrs go to code that throws an
exception. That should should have a zero cost. Other
than that, I don't really care about null pointer
dereferencing -- not a bug that I encounter more often
than every other year or so.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Mon, 14 May 2001 15:26:12 GMT
Raw View
Wilka wrote:
>
> > > > > class A {
> > > > >   A (int i) { /* code_1 */ }
> > > > >   A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
            ^^^^^^^^^^^^^^^^^^^^                     ^^^^^^^^^^
> > > > > };
> > > > >
> > > > > code_2 is executed after full construction and the execution of
> code_1.
> > > >
> > > > If code_2 throws, should the destructor be run?
           ^^^^^^
> > >
> > > No, because A isn't constructed yet. I would treat the ctor forwarding
> > > more like a function call (like your init(), but with the option of a
> > > initializer lists).
> >
> > But then if the A(int) constructor allocates ressources,
> > the A(B const&) constructor will have to release them manually
> > in case of exceptions, which is quite error prone.
>
> The A(int) constructor will have the same problems when called normally,
> i.e. the need to correctly tidy up if an exception is throw. So if there is
> an exception when called via the initialiser list, it'll tidy up as normal
> and the body of A(B const&) won't be executed.

You missed my point. If A(int) throws, there is no question
what should happen.
I've been speaking about A(B const&) throwing (see ^^^ marked lines
above).

>
> >
> > Also, if A(int) is called directly, then the object is considered
> > completely constructed after it's return, i.e. in an usable state.
> > If A(int) returns due to a "chained call", the object is already
> > in the same state, but this time, it is not considered completely
> > constructed. This is IMHO a bad inconsistency.
>
> This could also cause problems with multiple calls to a base class ctor,
> e.g.
>
> struct A : B
> {
>     A::A(int n) : B(n) { /* code */}
>     A::A(int n, float f) : B(n), A(n) { /* code */}
> };

This could easily be prevented by a rule that _either_ base/member
constructors _or_ a base class constructor can be called from the
member initializer list. Indeed, this rule would be a must, because
base/member initializers are added silently by the compiler if
omitted.

But then, I can foresee the questions on comp.lang.c++{,.moderated}:

"Why doesn't the following work?

class A
{
public:
  A(int i): member1(i) {}
  A(int i, int j): A(i), member2(j) {}
private:
  int member1, member2;
};

My compiler keeps telling me

  foo.cc:5: Tried to initialize member2 twice.

But where did I initialize it twice? HELP!"

All in all, I think this feature adds much complexity for little
benefit. What is worse, the complexity isn't obvious until you
get it wrong.
Especially for the exception thing, if both possible solutions
are unintuitive in some way, then it IMHO shows clearly that there
is something wrong with the feature itself.
Conceptionally, it would be a deviation of the general rule
"A constructor constructs an object". Depending on the view,
the object would either be fully constructed before constructor
return (of the chaining constructor), or not be constructed
after constructor return (of the chained-to constructor, but
even then only if the constructor is called by chaining).
The exception problem is caused exactly by this problem, which
can be summarized by the question:
"When is the object fully constructed?"

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 14 May 2001 18:47:53 GMT
Raw View
marcodg@home.com (Marco Dalla Gasperina) wrote (abridged):
> I'll throw in my support for Mr. Harris' idea as I've tried to
> do something similar.  There are additional advantages in that
> this supports what I would call virtual sequences: things that
> are sequences but don't occupy the memory of sequences...
>
> An example is the sequence of integers from 0 to 1,302,325.
> (This brings up the ability to apply a functor to a sequence
> as well... the result being another sequence).

Yes - it seems easier to implement funky sequences as sequences than as
pure iterators. It can be done with iterators - istream_iterator is an
example - but the sequence seems the better level of abstraction.

Incidently, the idea that code is clearer when sequences are represented
explicitly is in Stroustrup's C++PL, $18.3.1. He says the benefits for
output sequences, as opposed to input sequences, are smaller.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Mon, 14 May 2001 19:01:27 GMT
Raw View
Dave Harris wrote:
>
> Reified sequences.
>
> The STL algorithms operate on sequences. A sequence is a pair of
> iterators. However, there is no type which actually represents a sequence
> explicitly. This leads to various theoretical, practical and aesthetic
> problems. I suggest the new C++ standard make sequences explicit.
>
> At the simplest level, we could have something like:
>
>     template <typename iterator>
>     class sequence {
>     public:
>          sequence( iterator first, iterator last );
>
>          iterator begin() const;
>          iterator end() const;
>     };
>
> A sequence would be a concept rather than a class or template, so this
> template is merely an illustration. It is merely the usual half-open
> range. We would need versions of STL algorithms which accept sequences,
> eg:
>
>     template <typename sequence, typename fun>
>     fun for_each( const sequence &s, fun f ) {
>         return for_each( s.begin(), s.end(), f );
>     }
>
> I have used the names "begin" and "end" rather than the more usual
> "first" and "last" so as to make STL containers models of sequences. This
> means we can use:
>
>     vector<int> v(10);
>     for_each( v, f );
>
> directly. However, sequences are not containers. Eg we can also use:
>
>     for_each( sequence( v.begin(), v.begin()+5 ), f );
>
> A sequence is a single object rather than two, so it is easier to pass to
> other functions and (especially) to return as a result. Using them will
> reduce errors due, eg, to mixing the begin() of one sequence with the
> end() of another.
>
> Probably we will need some typedefs to make available the types of the
> iterator, value etc. We might also want to add some utility methods, eg:
>
>     template <typename iterator>
>     class sequence {
>     public:
>          //...
>          bool empty() const;
>          size_type size() const;
>          value_type front() const;
>          value_type back() const;
>     };
>
> These can be defined in terms of the begin() and end() already provided.
> It may be more convenient, readable and efficient to supply them
> directly. For example, size() could return a cached value if the iterator
> is not a random-access one.
>
> I have shown these methods as const, with the idea of passing sequences
> by reference instead of by value. Passing a single sequence by reference
> will often be more efficient than passing 2 iterators by value. It might
> be interesting to have mutable sequences, too. In fact, a sequence can
> become something almost like an iterator:
>
>     template <typename iterator>
>     class sequence {
>     public:
>          //...
>          reference front() { return *m_begin; }
>          reference operator*() { return *m_begin; }
>          sequence &operator++() { ++m_begin; return *this; }
>     private:
>         iterator m_begin;
>         iterator m_end;
>     };
>
> This allows algorithms to be implemented like:
>
>     template <typename sequence, typename fun>
>     fun for_each( sequence s, fun f ) {
>         for ( ; !s.empty(); ++s)
>             f( *s );
>         return f;
>     }
>
> This is now a significant generalisation of the notion of what a sequence
> is. It creates some new opportunities. For example, we can use
> terminating values rather then end() iterators:
>
>     class string_sequence {
>     public:
>         string_sequence( char *s );
>
>         bool empty() const { return *m_s == '\0'; }
>         char &operator*() { return *m_s };
>         string_sequence &operator++() { ++m_s; return *this; }
>
>         // ... other sequence methods.
>     private:
>         char *m_s;
>     };
>
> With a bit of work this can be generalised to cover null-terminated char
> and w_char strings, null-terminated arrays of strings (as used by the
> argv passed to main()), streams terminated by EOF, lines terminated by
> '\n', words terminated by ' ', and so forth. In such situations this kind
> of sequence is more convenient, more efficient and less clumsy than the
> pair of iterators kind.
>
> I put this forward in the spirit of brain-storming. I don't have a
> fully-worked out proposal and doing one will obviously involve a lot of
> work and careful design. However, I hope the above is enough to show how
> explicit sequences may be able to make the STL easier to use, less
> error-prone, more generic and more efficient.

Assuming sequences are introduced, the following operations would
make sense:

Constraining: Given a sequence S and a positive integer n, get
  the sequence consisting of the first n elements of S; if S is
  shorter than n, the complete sequence is returned

Value constraining (this is an extension of the "string_sequence"
  above): Given a sequence S and a value V, return the sequence
  which ends before the next occurence of the value V, or at the
  end of the sequence if V doesn't occur.

Note that value-constraining could be used for more than defining
C strings. For example, assume the function is called value_constrain,
then you could implement std::readline as (ignoring templated stream
issues):

std::string std::readline(std::istream is,
                          char end = '\n')
{
  string result;
  copy(value_constrain(istreambuf_iterator(is),
                       istreambuf_iterator(),
                       end),
       back_inserter(result));
  return result;
}

Here, the sequence of available input characters is specified
conventionally (i.e. with an iterator pair), but the function
returns a single sequence object passed to copy.

Also, together with constrain(<sequence>, <number>), one could
easily implement the often-requested length-limited readline:

std::string readline_n(std::istream is,
                       std::size_t maxsize,
                       char end = '\n')
{
  std::string result;
  copy(constrain(value_constrain(istreambuf_iterator(is),
                                 istreambuf_iterator(),
                                 end),
                 n),
       std::back_inserter(result));
  return result;
}

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Mon, 14 May 2001 19:13:10 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3AF9B200.23F606D6@dollywood.itp.tuwien.ac.at>, Christopher
> Eltschka <celtschk@dollywood.itp.tuwien.ac.at> writes
> >But IMHO allowing "enum = int" globally(!) is worse than this cast.
> >And it seems this is exactly what you had in mind, according to
> >your example.
>
> No it was not. I would like enums to be integer like types (with a full
> set of default operators) but without implicit conversions from built-in
> types. IOWs if I write:
>
> enum example (zero, one, two, three);
>
> int main(){
>   example val1=zero, val2=one;
>   example val3=val1 <op> val2; // this line should not generate an error
>   example val4=1;  // but this one should
>   val4 = val1 <op> val2 // should not
>   val1++; // should not
>   val1 += 1; // I am not sure
> // enough to give the idea, I think
> };
>
> Currently:
>
> void foo(example);
>
> void bar(example a, example b){
>   foo(a & b); // error unless I have defined operator&
> }

I prefer the current state even in that case.
I cannot imagine a single case where I would want to support
_both_ ++ _and_ &. And multiplying enums doesn't make sense
at all IMHO. If I want an int, I know where to find it.

However, one could make an extension, to direct the compiler
to pre-define a certain set of operators on certain enums, say:

__ordinal enum foo { zero, one, two, three };
  // defines:
  //   foo& operator++(foo), foo operator++(foo, int)
  //   foo& operator--(foo), foo operator--(foo, int)
  //   foo operator+(foo, int), foo operator+(int, foo)
  //   foo operator-(foo, int), int operator-(foo, foo)
  //   foo& operator+=(int), foo& operator-=(int)

(int should probably be replaced by the underlying
type of the enum)

__set enum foo { one=1, two=2, four = 4 };
  // defines:
  //   foo operator|(foo, foo), foo operator&(foo, foo)
  //   foo operator~(foo)
  //   foo operator<<(foo, int), foo operator>>(foo, int)
  //   foo& operator|=(foo), foo& operator&=(foo)
  //   foo& operator<<=(int), foo& operator>>=(int)

Maybe one could even change the default initialisation for
__set enum to generate 1<<0, 1<<1, 1<<2 etc. automatically.
The rule would then be that the first value would be 1 per
default, and the value following the previous would be
(1 << n) for the smallest n for which the result is larger
than the value of the previous enumerator.

This rule would allow to do the following:

__set enum open_mode { input, output }; // read = 1, write = 2
__set enum access_mode { none=0, execute, write, read };
                       // none=0, execute=1, write=2, read=4

__set enum event_type { keypressed,
                        keyreleased,
                        key = keypressed
                              | keyreleased,
                        mousemoved,
                        mouse1pressed,
                        mouse1released,
                        mouse1 = mouse1pressed
                                 | mouse1released,
                        mouse2pressed,
                        mouse2released,
                        mouse2 = mouse2pressed
                                 | mouse2released,
                        mouse = mousemoved
                                | mouse1
                                | mouse2
                      };
 // keypressed = 1, keyreleased = 2, key = 3,
 // mousemoved = 4,
 // mouse1pressed = 8, mouse1released = 16, mouse1 = 24
 // mouse2pressed = 32, mouse2released = 64, mouse2 = 96,
 // mouse = 124

As you can see, even in the rather complex event_type case,
there is no single explicit number - the rule to allow this
is just that masks are defined as soon as the last element
got defined (or alternatively, after _all_ elements are defined).

Also, one could add a third enum directive, __circular,
which would cause incrementing the last enum to result
in the first and decrementing the first to result in the last.

Example:

__circular direction { north, east, south, west };

Now west+1 == north and north-1 == west.

---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Mon, 14 May 2001 22:45:47 GMT
Raw View
"Bjarne Stroustrup" <bs@research.att.com> wrote in message
news:GD6KyB.L9q@research.att.com...
[snip]
> (Try to) think of the change
> caused by class hierarchies and OOP, of the change caused by templates and
> generic programming. Can a change/improvement of a similar magnitude be
> achieved? I think so, and I think the key is in the standard library (not
> in the language itself). If you find that implausible, think of the
acceptance
> and use of templates before and after the STL.

I think the same. Needless to say :o), I'd be happy if parts of Loki would
be considered for standardization. It would be nice to have design artifacts
such as object factories, visitors, singletons, multiple dispatch engines,
right in the standard library. A large fraction of projects can benefit of
such design artifacts.

Besides, smart pointers designed in the same way as in Loki would be very
useful. To date, all smart pointer design problems raised by Loki's users
could be solved without changing Loki::SmartPtr's implementation, and in an
elegant manner.


Andrei


---
[ 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: Heinz Huber <hhuber@racon-linz.at>
Date: Mon, 14 May 2001 22:46:16 GMT
Raw View

Marcin 'Qrczak' Kowalczyk wrote:
>
> Sat, 12 May 2001 15:22:23 GMT, Heinz Huber <hhuber@racon-linz.at> pisze:
>
> > I think it would be better to have the compiler treat the addition as:
> > Align operator+(Align op1, Align op2);
> > instead of using:
> > int operator+(int op1, int op2);
>
> But such addition often doesn't make sense: we can have for example
>     DayOfWeek operator+ (DayOfWeek day, int delta);
>     DayOfWeek operator- (DayOfWeek day, int delta);
>     int operator- (DayOfWeek day1, DayOfWeek day2);
> (and they should wrap), but not
>     DayOfWeek operator+ (DayOfWeek day1, DayOfWeek day2);

Perhaps we'd need a way to specify which kind of operations make sense on the
enum. Something like:
enum addEnum Enum { va11, val2 };
enum addInt Enum { val1, val2 };

Not very thought through, I know. But I think that Francis will keep up the
discussion because I see him heading into the same direction.

> > enum Enum { val1, val2 };
> > Enum e = val1 + val2;
> > The line above might (would?) trigger undefined behaviour since the result of
> > (val1 + val2) doesn't fit into Enum.
> > On the other hand, the following line would be OK:
> > int i = val1 + val2;
> > The return type of the addition is int in both cases, but may be used as Enum
> > without having to rely to a cast.
>
> I don't see how the above could be derived from consistent rules.
> What is the type of val1 + val2?

Here is the problem. In principle, the type should be Enum, but then you can
trigger undefined behaviour IIRC.
I'd prefer the type to be int, but that no explicit cast is necessary for an
assignment to Enum (or for passing as an Enum parameter).

Regards,
Heinz

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Mon, 14 May 2001 22:46:47 GMT
Raw View
"Nicola Musatti" <objectway@divalsim.it> wrote in message
news:3AFBCF96.6ABDA7F0@divalsim.it...
>
>
> Wilka wrote:
> >
> > > 2. using Base;
> > >    Example:
> > >
> > >      class Derived : private Base {
> > >        public:
> > >        using Base;  // expose the entire public interface of Base.
> > >        // ...
> > >      };
> > Or maybe:
> >
> > class Derived : using Base {
> >     // Derived now exposes the entire public interface of Base.
> > }
> You can already do this with public inheritance. The original example
> suffered from the same problem, for that matter.

Public inheritance permits implicit Derived-to-Base conversions. I presume
the point of the examples is to permit access to the full interface of Base,
but not permit these conversions.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 14 May 2001 22:55:01 GMT
Raw View
In article <MPG.15675c92644d20e4989728@news.lynchburg.net>, Michael Lee
Finney <michael.finney@acm.org> writes
>I think that's a good idea. And if changes to the
>signature of main are considered, I suggest that
>alternatives for all available signatures be available
>with a return type of void. It is very annoying to
>have to always return something from main when
>normally I never return anything from main. The only
>real use for returning something from main is writing
>batch programs where the return code is used to direct
>a script. I almost never write such programs and I
>suspect that most programs don't fall into that
>category.

But the language (though not one major implementor in their current
release) allows you to omit a return from main, the result will be the
same as return 0; There are technical reasons why a return of anything
other than int results in portability problems.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 14 May 2001 22:55:14 GMT
Raw View
In article <remove.haberg-1205011036450001@du132-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>One might also consider to add a better preprocessor to C++:

Why? As you mention in the rest of your post it is perfectly possible to
add your own (and if written in C++, it should be portable) I do not
think tinkering with pre-processors will meet with much favour, the
trend would be to get rid of it rather than replace it.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 14 May 2001 22:55:55 GMT
Raw View
In article <9dn8ka$cs7$1@kilmer.bain.oz.au>, Nick Thurn
<nickt@kipling.aus.deuba.com> writes
>> >The missing void
>> >polymorphic pointer
>>
>> You mean you wanted a way to collect completely unrelated objects?
>
>Yes! Currently you have to provide your own as with useful RTTI.
>These things are basic and should be standard IMO.

I do not think that such collections are all that common. The main
motive for such things as monolithic inheritance from CObject was to
provide containers in the days before templates were being supported. If
you really need containers of objects of unrelated types it is easy
enough (I think) to write a suitable smart pointer, but the need is rare
enough, IMO,  to suggest that it is not something to spend precious
Standards resources on doing.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 14 May 2001 22:57:45 GMT
Raw View
Francis Glassborow wrote:
>
> In article <remove.haberg-1305011216110001@du136-226.ppp.su-
> anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
> >Perhaps one should generate a list with all those "undefined" cases, for
> >easy access as a basis for discussions.
>
> Try grepping a copy of the C++ Standard for the word 'undefined'. The
> result may shock you. I think some of us will be looking at ways to
> reduce the size of that list, but there are many cases where the cost of
> removing it exceeds what many want to pay (in many cases you would have
> to abandon separate compilation)

Also, remember that such a list would only covers a tiny fraction of all
undefined behavior. Any situation for which the standard does not
explicitly define the behavior also allows undefined behavior. It's
practically impossible to provide a complete list of such undefined
behavior; the list would probably be literally infinitely long.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 14 May 2001 22:58:19 GMT
Raw View
Nick Thurn wrote:
>
> Francis Glassborow wrote:
> > In article <9dcq7k$o6e$1@kilmer.bain.oz.au>, Nick Thurn
> > <nickt@kipling.aus.deuba.com> writes
...
> > >The missing void
> > >polymorphic pointer
> >
> > You mean you wanted a way to collect completely unrelated objects?
>
> Yes! Currently you have to provide your own as with useful RTTI.
> These things are basic and should be standard IMO.

If it were standard, it would force an increase in the size of void* to
store the type information. Since a void* must be convertible to any
other type and back again without loss of information, that would mean
that the size of every pointer type must suffer a similar increase. For
pointers to polymorphic types the situation is different; each object of
a polymorphic type must contain type information anyway, so the pointers
themselves are unaffected. A typical implementation is to use a pointer
to a separate vtable for each type; addition of RTTI requires little
more than a single additional entry in each vtable, rather than
additional memory on a per-object or per-pointer basis.  That's why the
standard mandates RTTI only for polymorphic types. The general rule is
that you shouldn't have to pay for what you don't use.

Containers of unrelated types are, except in rare circumstances, a sign
of poorly thought-out design. I wouldn't consider them basic, and they
shouldn't be called for frequently enough to justify adding that cost to
every single pointer.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 14 May 2001 22:59:11 GMT
Raw View
In article <ncRcbvA81v$6Ew9t@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>Perhaps one should generate a list with all those "undefined" cases, for
>>easy access as a basis for discussions.
>
>Try grepping a copy of the C++ Standard for the word 'undefined'. The
>result may shock you. I think some of us will be looking at ways to
>reduce the size of that list, but there are many cases where the cost of
>removing it exceeds what many want to pay (in many cases you would have
>to abandon separate compilation)

Well, if there are so many cases, perhaps one can attempt layer the
language: The highest level of the language would be required to not
contain any "undefined" clauses. One should be able to program in it, and
move to lower levels for reasons of optimization.

With the example of the 0 pointer, one might introduce a high level 0
pointer which throws an exception if somebody tries to access it
dereferenced data. If one is pretty sure that the program does not need
that, one should be able to replace it with the 0 pointer that does not
throw an exception. This is way, it is possible to choose the
safety/optimization trade-off.

Much of the "undefined" seems to depend on the current hardware
architecture, so one perhaps must wait for better CPU's before one can
expect to remove them. On the other hand, no-one will develop in this
respect better CPU's before one sets forth thinking on what is needed in
order to remove those "undefined".

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 01:11:03 GMT
Raw View
In article <remove.haberg-1405011715580001@du137-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>Much of the "undefined" seems to depend on the current hardware
>architecture, so one perhaps must wait for better CPU's before one can
>expect to remove them. On the other hand, no-one will develop in this
>respect better CPU's before one sets forth thinking on what is needed in
>order to remove those "undefined".

No, much of current undefined behaviour is because anything else places
an unreasonable requirement on compilers in a context of separately
compiled translation units.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 15 May 2001 01:11:16 GMT
Raw View
In article <3AFF79C4.2D7D042C@racon-linz.at>, Heinz Huber <hhuber@racon-
linz.at> writes
>I'd prefer the type to be int, but that no explicit cast is necessary for an
>assignment to Enum (or for passing as an Enum parameter).

Unfortunately that opens up another can of worms. C++ deliberately (and
I think correctly) refused to allow explicit conversion from int to
enum. Where it gets even odder is that there is no direct explicit (note
that is explicit as in using a cast) conversion from one enum type to
another enum type.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Tue, 15 May 2001 03:59:24 GMT
Raw View
In article <bbajqVAuHIA7Ew2Y@ntlworld.com>,
francis.glassborow@ntlworld.com says...
> No, much of current undefined behaviour is because anything else places
> an unreasonable requirement on compilers in a context of separately
> compiled translation units.

Perhaps its time to drop the notion of separately
compiled translation units. This notion does not bring
much benefit to the table and yet causes tremendous
problems.  And the only compiler that compiles
everything together (the IBM VisualAge C++ 4.0 or
above) is also the only compiler that truly enforces
the single declaration rule.

In practice (and I maintain programs across multiple
platforms) I find that every target I build has to
have its own makefile and the object files cannot, in
general, be shared between projects because the
compiler options tend to be different (RTTI - yes/no,
multithreaded support - yes/no, char as
signed/unsigned - yes/no, etc.)

And the benefits of eliminating that restriction are
tremendous -- starting with optimization.

The only thing that I dislike about the IBM compiler
is that it is not possible to replace the
preprocessor. Indeed, it is not possible to even see
the preprocessor output. I am in the camp of
increasing the power of the preprocessor, I do not
view it as "evil", but merely another tool which is
sometimes appropriate. The biggest problem with the
preprocessor is that it cannot participate in scope in
any way.

---
[ 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: Heinz Huber <hhuber@racon-linz.at>
Date: Tue, 15 May 2001 11:20:24 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3AFF79C4.2D7D042C@racon-linz.at>, Heinz Huber <hhuber@racon-
> linz.at> writes
> >I'd prefer the type to be int, but that no explicit cast is necessary for an
> >assignment to Enum (or for passing as an Enum parameter).
>
> Unfortunately that opens up another can of worms. C++ deliberately (and
> I think correctly) refused to allow explicit conversion from int to
> enum. Where it gets even odder is that there is no direct explicit (note
> that is explicit as in using a cast) conversion from one enum type to
> another enum type.

I didn't mean to propose a general implicit (I think you meant implicit above)
conversion from int to enum. What I want is the compiler to use an implicit
conversion only in the following (and equivalent) case:
enum Test { t1, t2 };
Test v1 = t1 + t2;      // OK since operator on two values of Test
Test v2 = t1 + 1;       // to be defined whether OK since operator on one value
of Test
Test v3 = 1 + 2;        // definitly not OK!!!

Regards,
Heinz

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 15 May 2001 11:21:05 GMT
Raw View
In article <iMNdfgANzv$6Ew8T@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>One might also consider to add a better preprocessor to C++:
>
>Why? As you mention in the rest of your post it is perfectly possible to
>add your own (and if written in C++, it should be portable) I do not
>think tinkering with pre-processors will meet with much favour, the
>trend would be to get rid of it rather than replace it.

I think the reason that people want to get rid of the preprocessor is that
in the past it has been used in order to get around limitations in the
C/C++ languages.

However, a proper preprocessor can also be used in order to produce proper
C++ output after the preprocessing, which is good especially for automated
situations. Making it a separate program (disregarding the fact that the
preprocessor already is a separate program) does not integrate the process
in the same way.

And you are as likely to get rid of the preprocessor from C/C++ as the
word "undefined" from the C++ standard, for the same reasons, namely
efficiency.

For example, I haven't seen any suggestions on how to get rid of the
header macros that one has to put in order to make sure it isn't read
twice by the translation unit. If you want to get rid of the preprocessor,
such and all other current preprocessor uses must somehow be covered up.

So one can just as well think of prudent ways to enhance the preprocessor.

Possibly you have a scare there: People are afraid of that a better
preporcessor will make folks using that instead of the proper C++ feature.
That might have been the case before they got used to the current features
(tempalets etc).

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 15 May 2001 11:21:16 GMT
Raw View
In article <bbajqVAuHIA7Ew2Y@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>Much of the "undefined" seems to depend on the current hardware
>>architecture, so one perhaps must wait for better CPU's before one can
>>expect to remove them. On the other hand, no-one will develop in this
>>respect better CPU's before one sets forth thinking on what is needed in
>>order to remove those "undefined".
>
>No, much of current undefined behaviour is because anything else places
>an unreasonable requirement on compilers in a context of separately
>compiled translation units.

So what do you have in your mind here? -- Please give an example.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Andrew R. Thomas-Cramer" <artc@prism-cs.com>
Date: Thu, 10 May 2001 20:24:26 GMT
Raw View
"Christopher Eltschka" <celtschk@dollywood.itp.tuwien.ac.at> wrote in
message news:3AF9B8D0.55C9CE5D@dollywood.itp.tuwien.ac.at...
> What's wrong with
>
> class A
> {
> public:
>   A(int i) { init(i); }
>   A(B const& b) { init(makeInt(b)); /* code_2 */ }
> private:
>   void init(int i) { /* code_1 */ }
> };

Your init() method can't have a member initializer list. Therefore, it
eliminates redundancy in the constructor body -- but doesn't eliminate
redundancy in member initializer lists.

In Java, I've found the constructor forwarding requested by Krzikalla to be
quite useful.


---
[ 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: Ross Smith <ross.s@ihug.co.nz>
Date: Thu, 10 May 2001 21:09:56 GMT
Raw View
Ron Natalie wrote:
>
> Michiel Salters wrote:
> >
> >
> > One of the things I didn't see yet is to add another signature
> > for main, support mandatory. I propose to add
> > int main( std::vector< std::string > ), which would be valid
> > only in programs that include both <string> and <vector>. The
> > behavior is obvious, I think.
>
> Frankly, how about just std::string (forget the vector).  The entire
> world isn't a UNIX shell.  Even on Windows the command line to ARGC/ARGV
> gets a bit contrived.

But a good deal of the world _is_ a Unix shell, and your suggestion
would break argument parsing. Suppose I call a program like this:

$ ./foo "abc def" ghi

Under the (argc,argv) or vector<string> systems, the program will see
three arguments, "./foo" "abc def" "ghi". If we concatenated them all
together into one string, it would see "./foo abc def ghi" and have no
way of knowing that "abc def" was meant to be a single argument.

(No, re-quoting/escaping the arguments isn't a solution. It just forces
the program to waste time repeating the same parsing that the shell
already did.)

--
Ross Smith <ross.s@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
        "Hungarian notation is the tactical nuclear weapon of
         source code obfuscation techniques." -- Roedy Green

---
[ 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: James Dennett <jdennett@acm.org>
Date: Thu, 10 May 2001 23:41:31 GMT
Raw View
Al Grant wrote:
>
> "Mirek Fidler" <cxl@iol.cz> wrote in message
> news:9dasrk$2ad$1@news.vol.cz...
> > > Override.
> > > A new keyword, used in place of "virtual", which declares an intent to
> > > override. It is an error to declare a member function with "override" if
> > > it does not, in fact, override some base class member. Eg:
> >
> >     Yes, this was number two in my wishlist ;-) I would even suggest just
> > the same syntax.
>
> This was in my top 10 too.  But every new keyword hits
> programs that already use it as a variable name.
> Since this is essentially a source-level checking
> feature I'd suggest a pragma.

As has been pointed out elsewhere (in this group, I think),
that can be avoided if the default form is

_Overload

and there is a header

// overload
#ifndef _OVERLOAD_H
#define _OVERLOAD_H
#define overload _Overload
#endif

End-users should not be using "_Overload" in their current
code, and anyone who wishes to use a more friendly name can
#include <overload> and do so.

-- James Dennett

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Fri, 11 May 2001 00:22:59 GMT
Raw View
Martijn Lievaart wrote:
> nickt@kipling.aus.deuba.com (Nick Thurn) dared to utter in
> news:9dcl71$8ik$1@kilmer.bain.oz.au:
>
> > Martijn Lievaart wrote:
> >>
> >> Gratuitous? A life saver for anyone working with Unicode. I know many
> >>
> > The fact that the implementation of these classes is shared is a detail
> > you should not have to be concerned with.
>
> I don't think this is correct, the implementation might be a
> specialisation. They have the same interface, and that is all a user should
> be concerned with.
>
Perhaps we're at cross purposes or I'm being way to general as usual ;-).

I agree the user should not have to worry about interface differences
between string and wstring or iostream wide variants. I disagree that
templatizing these interfaces is the only way or the best way to do
this.

> >
> > I agree that wide character versions of these are absolutely necessary.
> > Templatizing the classes is not, it's just one implementation approach.
> >
>
> Yes, although imo a logical one.
>
Perhaps. My issue is templatizing has bad (tm) sideeffects in the
currently available compiler sets. If it were a doddle to implement C++
and the std library things might be different. As is we're still
waiting...

cheers
Nick

---
[ 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: Mark Blewett <mblewett@nildram.co.uk>
Date: Fri, 11 May 2001 01:39:31 GMT
Raw View
On Wed,  9 May 2001 03:07:43 GMT, nickt@kipling.aus.deuba.com (Nick
Thurn) wrote:

>Mark Blewett wrote:
>>
>> What C++ needs now is simplification, consolidation and
>> standardization (not it terms of ANSI, but in terms of the language),
>> possibily with the introduction of a mininimal set of new features.
>>
>Agree.
>
>One thing the standards process did that was wrong was
>concentrate too much on invention. In some cases this was
>gratuitous:
> - templatized streams
> - templatized string

I couldn't comment. I don't use stl strings much.

>Other areas were rendered useless for their main purpose:
> - type_info::name for persistence

Once you know the name is non-standard between compilers, it's simple
to implement around it. It's a hassle.. not a major flaw IMHO

>Other common usages were simply ignored as "bad practice"
>despite these containing the bulk of actual users:
> - c++ ala C++/Views, MFC ... basically any GUI tool kit
>
>No barrier construct for multi-threading:
> - no way to make double checked locking work portably
> - no way to ensure lock occurs before data access portably

See my previous post, its not a language feature.. it's a library
feature IMHO

>Binder dependent STL with incomplete binder support.
>
>We have ended up with a language that is tricky, hard to learn,
>really hard to compile and not yet implemented in any commercial
>compiler. Personally I believe this is bad.

I agree.

I've try to restrain from posting code so far, but here's couple of
very simple examples of things that I dislike (to varying degrees)
about c++;

What do they do?... No cheating by compiling it!

1)

#include <iostream>

const int a[2] = { 1 };

int main()
{
 std::cout << a[0] << a[1];
 return 0;
}

2)

#include <iostream>

template <unsigned int N>
class A
{
public:
 A() { std::cout << N; }
};

int main()
{
 A<-1> a;
 return 0;
}

>The simplification Mark speaks of is needed.

I would add some additional points/detail to my original post (based
on the examples above)... it's a key point I think;

C has it's own standard, does C++ have to be backward compatible in
the future? There are so many new features I can't see a reason why
c++ can't break away from c now.

For example;

The inherited rule from C (example 1) should be discarded, and
replaced with a compile time error IMHO

The conversion of -1 to max int. (example 2). We have <limits> now.
Time to remove implicit conversions like this. IMHO removing all
implicit conversions of built in types and typedefs of (a bit
radical!) and making the user specifiy the conversion via a cast<>
would be step forward... the right type for the job etc. If it isn't
let the user know at compiler time.. and do something about it.

>It should be possible
>to use the commonly needed subset of the language with efficient
>compilation and meaningful error reporting. If this requires
>a martian savant to implement the compiler then the language
>should be changed so a lowly 21st century human can actually
>do it.

>From "meaningful error reporting" I incure that you've used the STL
=o). Personally I feel this is not a language issue, but a compiler
issue. Having a 1k compiler message with as many <>'s as you can count
is daunting. If you incrementally compile or use the same compiler for
a while you start to recognise the message / problem. The major gripe
(apart from the error message length) is that in my experience the
compiler flags the definition of the template and not the instance
(which could equally be wrong).

Regards
Mark

>
>cheers
>Nick
>
>PS apologies to any martians offended by the above...
>
>---
>[ 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                ]

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Fri, 11 May 2001 09:19:10 GMT
Raw View
"Hans Aberg" <remove.haberg@matematik.su.se> wrote in message
news:remove.haberg-1005012030400001@du131-226.ppp.su-anst.tninet.se...
> In article <9dbu9s$c8s$1@cam-news1.cambridge.arm.com>, "Al Grant"
> <tnarga@arm.REVERSE-NAME.com> wrote:
> >No, because you can't buy a language feature and plug it into
> >your compiler, or mix and match language features from different
> >vendors.  You _can_ do this with libraries.
>
> There was actually the suggestion a time ago in one of these C++ groups
> that people pick down say the public sources of GCC and make their own
> version of C++ before presenting it as a suggestion for inclusion into
> C++.
> So this is what people actually do; GCC is one example.

That's hardly a sensible option for most C++ programmers.
Not everyone uses GCC.  Some people can't.

> Otherwise, I discussed the possibility of inclusion of such a GUI library,
> whereas I get the impression that you say such discussions should not take
> place.

Yes.  There are things which a standards committee should
agree (after discussion, of course) not to discuss, in
order to save time.  It's just a question of prioritisation.
If every new library proposal has to be formally considered,
where does it end?  You want a GUI library, someone else
might want a numerical algorithms library, or a networking
library, or a cryptography library.  If this has to
be discussed as part of the C++ standards process, the
people who vote on it have got to become experts in all the
relevant fields.  That's not realistic.  Far better that
these things are left to the real experts who can tell the
standards committee what _language features_ they need.
This appears to have worked well for C99 in the case of
numerical programming, which is why C99's support for
numerical programming is better than C++'s.  It does not
mean C99 has a library of numerical algorithms.  Its library
is still far smaller than C++'s.

Similarly the crypto experts might ask for a standard
built-in "rotate" function.  Or the networking people
might ask for standard "byte swap" functions and a "packed"
qualifier for structs, or a more general solution to the
endianness and alignment problems.  That is the way to
support applications - not by trying to define entire
libraries when experts in the field have failed to do so.



---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Fri, 11 May 2001 13:38:42 GMT
Raw View
Mark Blewett wrote:

[...]

> >We have ended up with a language that is tricky, hard to learn,
> >really hard to compile and not yet implemented in any commercial
> >compiler. Personally I believe this is bad.
>
> I agree.
>
> I've try to restrain from posting code so far, but here's couple of
> very simple examples of things that I dislike (to varying degrees)
> about c++;
>
> What do they do?... No cheating by compiling it!
>
> 1)
>
> #include <iostream>
>
> const int a[2] = { 1 };
>
> int main()
> {
>         std::cout << a[0] << a[1];
>         return 0;
> }

Should print "10".

>
> 2)
>
> #include <iostream>
>
> template <unsigned int N>
> class A
> {
> public:
>         A() { std::cout << N; }
> };
>
> int main()
> {
>         A<-1> a;
>         return 0;
> }

should of course print the value of UINT_MAX.

[...]

>
> For example;
>
> The inherited rule from C (example 1) should be discarded, and
> replaced with a compile time error IMHO

But then, there should be given another syntax to get this
behaviour. Also I'm not sure if it wouldn't break too much
C++ code.

>
> The conversion of -1 to max int. (example 2).

No, to max unsigned int.

> We have <limits> now.

And C had <limits.h>.

> Time to remove implicit conversions like this. IMHO removing all
> implicit conversions of built in types and typedefs of (a bit
> radical!) and making the user specifiy the conversion via a cast<>
> would be step forward...

While htere are surely a few conversions which would be
better removed (f.ex., bool->int), there are many conversions
which should be keps (after all, even Pascal has some
implicit conversions!)

The implicit conversions I'd like to remove:

bool->int
floating point -> integral

But I guess the number of broken programs would be too large.
Maybe a standard pragma

#pragma STDCPP conversions restricted

which would flag any such implicit conversion as an error
(i.e. not disabling it - since this could change program semantics
- but only refuse to compile if it would happen).

Another standard pragma

#pragma STDCPP conversions permissive

could then be used to switch off this behaviour.

The default could be made to #pragma ... restricted (no semantics would
change, but some programs would only compile with #pragma ...
permissive;
a rather small change to be made). At the same time,
#pragma ... permissive would be made deprecated, to encourage rewriting
the code.
Then, one or two standards later, #pragma ... permissive could be
removed and the conversions completely banned (this would break code
with #pragma ... permissive, but hopefully there wouldn't be much left).

[...]

---
[ 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: Olaf Krzikalla <Entwicklung@reico.de>
Date: Fri, 11 May 2001 13:38:50 GMT
Raw View
Hi,

Christopher Eltschka wrote:
> > class A {
> >   A (int i) { /* code_1 */ }
> >   A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
> > };
> >
> > code_2 is executed after full construction and the execution of code_1.
>
> If code_2 throws, should the destructor be run?

No, because A isn't constructed yet. I would treat the ctor forwarding
more like a function call (like your init(), but with the option of a
initializer lists).


Best regards
Olaf Krzikalla

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 11 May 2001 22:39:07 GMT
Raw View
In article <3AF9B200.23F606D6@dollywood.itp.tuwien.ac.at>, Christopher
Eltschka <celtschk@dollywood.itp.tuwien.ac.at> writes
>But IMHO allowing "enum = int" globally(!) is worse than this cast.
>And it seems this is exactly what you had in mind, according to
>your example.

No it was not. I would like enums to be integer like types (with a full
set of default operators) but without implicit conversions from built-in
types. IOWs if I write:

enum example (zero, one, two, three);

int main(){
  example val1=zero, val2=one;
  example val3=val1 <op> val2; // this line should not generate an error
  example val4=1;  // but this one should
  val4 = val1 <op> val2 // should not
  val1++; // should not
  val1 += 1; // I am not sure
// enough to give the idea, I think
};


Currently:

void foo(example);

void bar(example a, example b){
  foo(a & b); // error unless I have defined operator&
}



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Fri, 11 May 2001 22:39:20 GMT
Raw View
Olaf Krzikalla wrote:
>
> Hi,
>
> Christopher Eltschka wrote:
> > > class A {
> > >   A (int i) { /* code_1 */ }
> > >   A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
> > > };
> > >
> > > code_2 is executed after full construction and the execution of code_1.
> >
> > If code_2 throws, should the destructor be run?
>
> No, because A isn't constructed yet. I would treat the ctor forwarding
> more like a function call (like your init(), but with the option of a
> initializer lists).

But then if the A(int) constructor allocates ressources,
the A(B const&) constructor will have to release them manually
in case of exceptions, which is quite error prone.

Also, if A(int) is called directly, then the object is considered
completely constructed after it's return, i.e. in an usable state.
If A(int) returns due to a "chained call", the object is already
in the same state, but this time, it is not considered completely
constructed. This is IMHO a bad inconsistency.

Maybe one could invent "constructor helpers", which are _not_
constructors, but allow member initialisation, and can be called
just like base class constructors:

class A
{
public:
  A(int i): |A(i) {} // made-up syntax
  A(B const& b): >A(makeInt(b)) { /* code 2 */ }
private:
  |A(int i): member(i) { /* code 1 */ }
  int member;
};

But I'm not convinced that this should be done at all; after all,
using a base class works just fine in such a case:

class A_base
{
protected:
  A_base(int i): member(i) { /* code 1 */ }
  int member;
};

class A: private A_base
{
public:
  A(int i): A_base(i) {}
  A(B const& b): A_base(makeInt(b)) { /* code 2 */ }
};

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Fri, 11 May 2001 22:39:55 GMT
Raw View
Since everybody is brainstorming, a suggestion for a GUI library might be
the ability to write in R^n (R = the real numbers) third degree polynomial
parametrized simplicies (= Bezier curves when n = 2), and project them
onto R^2 for display.

The underlying math is quite simple:

A n-dimensional (linear) simplex Delta^n is defined to be the set of all
points in R^{n+1} whose coordinates are all non-negative and with sum 1. A
third degree polynomial parametrized n-dimensional simplex is then simply
a map Delta^n -> R^n whose coordinate projections are polynomials of
degree at most three.

One then gets a reasonable class of objects: The boundaries of such a
simplex is also simplicies of the same class, and they can be pasted
together the same Bezier curve segments can.

Addition of such a feature could also help the educational aspect of C++,
as one often when writing programs like Hugs http://www.haskell.org/hugs
has some graphics library included, and it is chore trying to port such
stuff.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 12 May 2001 15:13:07 GMT
Raw View
In article <remove.haberg-1105012010530001@du128-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>Addition of such a feature could also help the educational aspect of C++,
>as one often when writing programs like Hugs http://www.haskell.org/hugs
>has some graphics library included, and it is chore trying to port such
>stuff.

This post reminded me that one of the objectives that Bjarne Stroustrup
suggested in his talk was that we make C++ more teachable. One of the
things that repeatedly irritates me is that there is no portable way of
writing simple graphics programs. This means that novices either get
exposed to platform specific extensions or get (usually non-exciting)
text based programs as examples.

I think a case could be made for adding a small graphics library. If
others think this a good idea, perhaps we could start a new thread to
consider what that might provide (it should be simple, and provide only
primitives and near primitives, so that there is a portable way to
develop graphical displays and manipulation)



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Mark Blewett <mblewett@nildram.co.uk>
Date: Sat, 12 May 2001 15:16:05 GMT
Raw View
On Tue,  8 May 2001 23:58:57 GMT, Francis Glassborow
<francis.glassborow@ntlworld.com> wrote:

>In article <sdsgftcomndg54r9huigjvc2cjmns49aah@4ax.com>, Mark Blewett
><mblewett@nildram.co.uk> writes
>>1) Undefined behaviour. Should it exist in a "defined" language? For
>>example if C++ is a portable language, does undefined behaviour hinder
>>the cross platform / compiler developer?
>
>To the contrary, undefined behaviour makes it easier on the compiler
>developer by shifting the responsibility to the user. Unspecified and
>implementation defined can be more problematical.

I agreed that I should have said "undefined behaviour, unspecified and
implementation defined".

I would say "Undefined behaviour" generally leads to compiler specific
implementations which could be comparable to unspecified.

The greatest problem IMHO about the whole area is that people
generally use one compiler / platform and because of there experience,
sometimes / can rely on compiler "features" (read undefined behaviour,
unspecified and implementation defined =o). Then try and port to
another compiler only to find it fails (or move to another company
which uses a different compiler and find that ideas that used to work
don't!).

After following some of the c++ newsgroups for many years albeit with
minimal postings, "Its undefined behaviour" seems to be a very common
answer to posts. Isn't time to eliminate those questions?

>>
>>2) I'm interested in the quote from the original post "overall goals
>>should include making C++ a better language for systems programming
>>and library building". Does this mean BS thinks C++ has lost the app
>>development battle, and that C++ has a reduce role as an application
>>language?
>
>Not at all, just that as a general purpose language it needs to focus on
>areas where it does not work as well as it might.

Is there any clarification on why the focus on systems and libraries?
In general as a developer prefer the power of C++.

As an app developer, there are a lot of times where I will use other
languages, for example Delphi for UI, db, (windows) automation,
sockets etc... there isn't much space for app developement left for
C++ IMHO, hence the comment.

>From system / backend services I generally use C++, where there are
less platform dependencies (*). Where there is an issue of pltform
independence I construct pimple's containing platform dependent code
from a concrete platform dependent factory for example.

(*) As in I wouldn't like to do do a whole gui this way!

I note that there are mutterings about multi-threading. In my
experience you can use same the factory / pimple mechanism for things
like mutexes, threads, critical sections et al now. May be in the
future we need to define a Standard Multi-Threading Library (SMTL).
May be it's a simplistic view, but if a standard interface was
defined, and compiler vendors implemented their libraries to it we
don't need langauge extenstions.

Going back to the response; Should C++ be a general purpose language?
And what is a general purpose language?

>>3) IMHO C++ is becoming too complex... why should a developer / user
>>learn C++ if it takes a couple of years to become reasonable
>>developer? (I'm a professional C++ developer with over 7 years
>>experience, and the technical abilities of prospective employees
>>claming c++ experience is farcile, a third can't even explain virtual
>>functions and polymorphism!)
>
>Well one of Bjarne's objectives was making the language more teachable,
>but some of the blame lies with the inadequacies of many instructors
>(and the language they use makes little difference)

I agree that an objective should be making the language more
teachable. But I totally disagree on the blame. Who teaches the
instructors? And the instructors of the instructors? It comes down to
someone has to learn the language, and if it's too complex the
mistakes propagate down the learning tree.

Also the populatity of C++ is a problem. Everyone claims to be an
expert because it is/was the in language.

>>
>>C++ may well be getting to the comlexity where the commercial
>>companies prefer to concentrate on their own development environments
>>which have easy access to gui/platform functions, which get people in
>>quickly, and tie them to the language / tools (for example VB /
>>Delphi). Why should a commercial company develop a tool where it takes
>>an individual a couple of years to become reasonable in the language,
>>and then have to learn the plaform?... when it is more profitable to
>>produce a simpler development enviroment for a simpler language?
>
>You mean like getting rid of medicine (as a the trade of doctors etc.)
>and replacing it with grandma's favourite remedy? Don't Americans have a
>word for such practitioners?

No, but it depends what you mean by grandma's favourite remedy =o)

What percentage of commerical software (in terms of sales) written in
the last couple of years has a UI? It's definately the majority. Why
should those applications be developed in C++ when other languages
provide better support for the platform (albeit platform dependent),
and generally better tools to implement UI than the C++ tools?

Look at VB, the worlds worst language IMO but almost every one uses it
because the tool allows the end product to be developed quickly with
minimal experience of the language. Forget portability and
maintainability, getting a flash ui and the product out the door seems
to be the majority option (esp. the sales team)... Whether it's right
in terms of the developement process is a big question (outside the
scope of comp.std.c++ I believe).

Compared to BASIC, Pascal etc C++ IS a complex language. When there
are tools out there which allow a inexperience person to "knock up a
quick program" with a ui in minutes, why should they spend years
learning and experiencing c++?

Hence why should companies developing commerical c++ compilers which
take a lot of effort due to the complexities of the language, when
they can produce languages which are easier to understand and learn,
and take advantage of the platform.

Going back to "grandma's favourite remedy" may be if you grandma's
called Microsoft =o)

>>As far as C++ is concerned stability in a language is good, and the
>>development of the language can helpful missing features but can be
>>bad for stability.
>>
>>What C++ needs now is simplification, consolidation and
>>standardization (not it terms of ANSI, but in terms of the language),
>>possibily with the introduction of a mininimal set of new features.
>
>New features can actually simplify:)

Or perhaps old features can complicate ;oP

Regards
Mark

>
>
>Francis Glassborow      ACCU
>64 Southfield Rd
>Oxford OX4 1PA          +44(0)1865 246490
>All opinions are mine and do not represent those of any organisation
>
>---
>[ 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                ]

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Sat, 12 May 2001 15:21:03 GMT
Raw View
Reified sequences.

The STL algorithms operate on sequences. A sequence is a pair of
iterators. However, there is no type which actually represents a sequence
explicitly. This leads to various theoretical, practical and aesthetic
problems. I suggest the new C++ standard make sequences explicit.

At the simplest level, we could have something like:

    template <typename iterator>
    class sequence {
    public:
         sequence( iterator first, iterator last );

         iterator begin() const;
         iterator end() const;
    };

A sequence would be a concept rather than a class or template, so this
template is merely an illustration. It is merely the usual half-open
range. We would need versions of STL algorithms which accept sequences,
eg:

    template <typename sequence, typename fun>
    fun for_each( const sequence &s, fun f ) {
        return for_each( s.begin(), s.end(), f );
    }

I have used the names "begin" and "end" rather than the more usual
"first" and "last" so as to make STL containers models of sequences. This
means we can use:

    vector<int> v(10);
    for_each( v, f );

directly. However, sequences are not containers. Eg we can also use:

    for_each( sequence( v.begin(), v.begin()+5 ), f );

A sequence is a single object rather than two, so it is easier to pass to
other functions and (especially) to return as a result. Using them will
reduce errors due, eg, to mixing the begin() of one sequence with the
end() of another.

Probably we will need some typedefs to make available the types of the
iterator, value etc. We might also want to add some utility methods, eg:

    template <typename iterator>
    class sequence {
    public:
         //...
         bool empty() const;
         size_type size() const;
         value_type front() const;
         value_type back() const;
    };

These can be defined in terms of the begin() and end() already provided.
It may be more convenient, readable and efficient to supply them
directly. For example, size() could return a cached value if the iterator
is not a random-access one.

I have shown these methods as const, with the idea of passing sequences
by reference instead of by value. Passing a single sequence by reference
will often be more efficient than passing 2 iterators by value. It might
be interesting to have mutable sequences, too. In fact, a sequence can
become something almost like an iterator:

    template <typename iterator>
    class sequence {
    public:
         //...
         reference front() { return *m_begin; }
         reference operator*() { return *m_begin; }
         sequence &operator++() { ++m_begin; return *this; }
    private:
        iterator m_begin;
        iterator m_end;
    };

This allows algorithms to be implemented like:

    template <typename sequence, typename fun>
    fun for_each( sequence s, fun f ) {
        for ( ; !s.empty(); ++s)
            f( *s );
        return f;
    }

This is now a significant generalisation of the notion of what a sequence
is. It creates some new opportunities. For example, we can use
terminating values rather then end() iterators:

    class string_sequence {
    public:
        string_sequence( char *s );

        bool empty() const { return *m_s == '\0'; }
        char &operator*() { return *m_s };
        string_sequence &operator++() { ++m_s; return *this; }

        // ... other sequence methods.
    private:
        char *m_s;
    };

With a bit of work this can be generalised to cover null-terminated char
and w_char strings, null-terminated arrays of strings (as used by the
argv passed to main()), streams terminated by EOF, lines terminated by
'\n', words terminated by ' ', and so forth. In such situations this kind
of sequence is more convenient, more efficient and less clumsy than the
pair of iterators kind.

I put this forward in the spirit of brain-storming. I don't have a
fully-worked out proposal and doing one will obviously involve a lot of
work and careful design. However, I hope the above is enough to show how
explicit sequences may be able to make the STL easier to use, less
error-prone, more generic and more efficient.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Heinz Huber <hhuber@racon-linz.at>
Date: Sat, 12 May 2001 15:22:23 GMT
Raw View
Christopher Eltschka wrote:
>
> Francis Glassborow wrote:
> >
> > In article <memo.20010509061258.57395A@brangdon.madasafish.com>, Dave
> > Harris <brangdon@cix.co.uk> writes
> > >Why do you need operator=() for enums?
> > >
> > >With most functions, they can be added outside the enum's own scope:
> > >
> > >    enum Align { Left, Center, Right, End };
> > >
> > >    Align &operator++( Align &e ) {
> > >        return e = Align(e+1);
> >
> > exactly because of that cast, requiring a cast to do something natural
> > is adding potential for errors being hidden by the cast.
>
> But IMHO allowing "enum = int" globally(!) is worse than this cast.
> And it seems this is exactly what you had in mind, according to
> your example.

I think it would be better to have the compiler treat the addition as:
Align operator+(Align op1, Align op2);
instead of using:
int operator+(int op1, int op2);

By returning the type Align from operators used on values/variables of ONLY the
type Align, you'd get type safe operators for enums and would not have to resort
to the cast.

If you indeed want an int (perhaps because you're breaking out of the possible
values of Align), you'd simply have to cast one of the operands to int:
(Left + (int)Right) has type int

IIRC, assiging a value which won't surely fit into the allowed values of an enum
produces undefined behaviour. Therefore one could choose a wording that allows
the return value of operators like mentioned above to be of the same type as the
enum operands to be treated as having the same type as the operands by the
compiler.

enum Enum { val1, val2 };
Enum e = val1 + val2;
The line above might (would?) trigger undefined behaviour since the result of
(val1 + val2) doesn't fit into Enum.
On the other hand, the following line would be OK:
int i = val1 + val2;
The return type of the addition is int in both cases, but may be used as Enum
without having to rely to a cast.


One argument against this change might be that errors inducing undefined
behaviour (like the assignment to e above) can be hidden. As the standard is
right now, one would have to cast the result of operator+ back to Enum. But as
Francis mentioned, this cast might hide some other errors in itself.

Regards,
Heinz

---
[ 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: "Mirek Fidler" <cxl@iol.cz>
Date: Sat, 12 May 2001 15:22:17 GMT
Raw View
> It is really a must for the next C++ version to support the features
> needed for the implmentation of conservative GC's.

    I do not think so. Any kind of GC is absolutely useless in C++, as there
is better way how to avoid manual freeing of resources (including heap) -
reasource allocation is initialization idiom.

> And one can wrap up the memory management into classes, so they become
> "smart pointers". Then the exception stack unwinding will de-allocate any
> allocated memory.

    Yes, this is the way.

Mirek


---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Sat, 12 May 2001 15:23:11 GMT
Raw View

Francis Glassborow wrote:
>
> In article <3AF91605.81F7206A@divalsim.it>, Nicola Musatti
> <objectway@divalsim.it> writes
> >The problem is that currently if you declare your destructor, it is not
> >synthesised. Normally this is what you want because you declare it to
> >implement it. However when you declare your destructor pure virtual you
> >are forced to provide a body you're often not interested in and to write
> >it outside the class definition.
>
> I do not think that pure virtual dtors actually do anything useful
> (unless their bodies are non-empty)

Declaring a destructor pure virtual is a way of ensuring that a class
remains abstract even if you change your mind about the "purity" of
other member functions.

Best regards,
Nicola Musatti

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 12 May 2001 15:25:08 GMT
Raw View
In article <KutK6.683$bi2.49473@www.newsranger.com>, Michiel Salters
<Michiel.Salters@cmg.nl> writes
>One of the things I didn't see yet is to add another signature
>for main, support mandatory. I propose to add
>int main( std::vector< std::string > ), which would be valid
>only in programs that include both <string> and <vector>. The
>behavior is obvious, I think.

Interesting (actually compilers could support that now) why not write up
a proposal and we can thrash it out (I will bring it to the UK's C++
panel if it seems appropriate as a first filter before promoting it
further)


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Sat, 12 May 2001 15:26:42 GMT
Raw View
"Ney Andr=E9 de Mello Zunino" wrote:

[...]

> Next, I decided to show him the classes' definitions. The moment he put=
 his
> eyes on my abstract class, he asked me: "- What is the deal with that '=
=3D 0'
> over there?" After I told him that was meant to mark a method as pure
> virtual, he asked me: "- So why not just say 'pure' instead? Why make t=
hings
> unnecessarily cumbersome?" Hum... Maybe here is one of the few things I=
 must
> agree with him. :)

BTW, one side remark:

It is implementation defined, if

class X { virtual ~X() =3D NULL; };

is 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                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Sat, 12 May 2001 15:25:03 GMT
Raw View

Wilka wrote:
>
> > 2. using Base;
> >    Example:
> >
> >      class Derived : private Base {
> >        public:
> >        using Base;  // expose the entire public interface of Base.
> >        // ...
> >      };
> >
>
> Or maybe:
>
> class Derived : using Base {
>     // Derived now exposes the entire public interface of Base.
> }

You can already do this with public inheritance. The original example
suffered from the same problem, for that matter.

Best regards,
Nicola Musatti

---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Sat, 12 May 2001 15:28:55 GMT
Raw View

Carl Daniel wrote:
[...]
> 5. Reflection/introspection
>
> IMO, this must be optional - perhaps requested by a new class declaration
> decoration  (along the lines of MSVC's __declspec() but not that ugly).

It should be possible to make this triggered by use, even though the
compiler would probably often generate too much. We could have something
like:

class C { public: void f(int); char c; };

C c;
type_desc * td = make_type_desc(c);

Upon which the compiler would generate the description for the class
hyerarchy rooted at C.

Best regards,
Nicola Musatti

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 12 May 2001 15:26:27 GMT
Raw View
In article <9dgaij$q57$1@cam-news1.cambridge.arm.com>, Al Grant
<tnarga@arm.REVERSE-NAME.com> writes
>This appears to have worked well for C99 in the case of
>numerical programming, which is why C99's support for
>numerical programming is better than C++'s.  It does not
>mean C99 has a library of numerical algorithms.  Its library
>is still far smaller than C++'s.

Yet both (though more seriously C++) had the problem that they lost the
input from domain experts because their companies withdrew support.
Writing good libraries for specific domains is hard, highly skilled
work. I think we need an alternative mechanism for these though boost
seems to be on the right track.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 12 May 2001 15:30:23 GMT
Raw View
In article <9dcq7k$o6e$1@kilmer.bain.oz.au>, Nick Thurn
<nickt@kipling.aus.deuba.com> writes
>The lack of a set of standard containers is one of
>Bjarne's regrets. The RTTI added to C++ is basically useless
>if you wish to use it for persistence or to cross a network
>because there is no portable tag for types.

But RTTI was actually introduced to standardise existing practice :)

>The missing void
>polymorphic pointer

You mean you wanted a way to collect completely unrelated objects?
>has led to gazillions of CObject
>RWCollectable ZObject...etc. The missing synch or barrier
>or whatever makes MT code possibly non portable.
>
>I love and use C++ (and not VMcC++ either :). I'm sorry
>that my frustrations tire you. I'm sure there are many
>stories to tell about the standardisation process and
>that the outcome could have been much worse. Thank you
>for ensuring it wasn't. This doesn't alter the fact that
>std C++ is becoming IMO marginalized.

You mean like standard C, standard BASIC, etc. Why are almost all (and
that includes the much derided MS) implementors trying to ensure that
their compilers provide a strictly standard conforming mode? Of course
for commercial reasons they will also try to seduce you into using their
wonderful proprietary extensions:)


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Sat, 12 May 2001 15:32:16 GMT
Raw View
I liked my idea better.  ie.  Using a version pragma.  It would accomplish
the same thing and more.

Greg Brewer


---
[ 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: "Mirek Fidler" <cxl@iol.cz>
Date: Sat, 12 May 2001 15:32:32 GMT
Raw View
> In the standards committees we refer to core language and standard
> library. We have certainly not closed our minds to the idea that some
> parts of a library might be optional (and note that this is already true
> in C, and always has been since its first standard in 1989)

    What about to split ANSI C++ into two standards - core language and
standard library ?

    It would easier then to "upgrade" both independently and in fact there
is fair amount of people who do not care too much about standard library
(include me).

Mirek


---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sat, 12 May 2001 15:33:32 GMT
Raw View
In article <9dgaij$q57$1@cam-news1.cambridge.arm.com>, "Al Grant"
<tnarga@arm.REVERSE-NAME.com> wrote:
>> Otherwise, I discussed the possibility of inclusion of such a GUI library,
>> whereas I get the impression that you say such discussions should not take
>> place.
>
>Yes.  There are things which a standards committee should
>agree (after discussion, of course) not to discuss, in
>order to save time.  It's just a question of prioritisation.

Is it not a little naive to think that if the standardization committee
excludes considering some features, say like a GUI or whatever, that they
will spend more time on your pet features? :-)

>If every new library proposal has to be formally considered,
>where does it end?

One will probably very quickly become oriented about what is feasible of
inclusion; this is why this brain storming thread currently runs.

> You want a GUI library, someone else
>might want a numerical algorithms library, or a networking
>library, or a cryptography library.

See, you have already come up with three additional good suggestions!

>  If this has to
>be discussed as part of the C++ standards process, the
>people who vote on it have got to become experts in all the
>relevant fields.

I think that the are more likely to lop off experts committees on the
various subfields.

This is for example necessary on the conservative GC question -- only
dedicated experts can be expected to deal with such a question.

Actually, this happened already with the current standard; one decided to
not include the experts suggestion at that time.

>  That's not realistic.  Far better that
>these things are left to the real experts who can tell the
>standards committee what _language features_ they need.
>This appears to have worked well for C99 in the case of
>numerical programming, which is why C99's support for
>numerical programming is better than C++'s.  It does not
>mean C99 has a library of numerical algorithms.  Its library
>is still far smaller than C++'s.
>
>Similarly the crypto experts might ask for a standard
>built-in "rotate" function.  Or the networking people
>might ask for standard "byte swap" functions and a "packed"
>qualifier for structs, or a more general solution to the
>endianness and alignment problems.  That is the way to
>support applications - not by trying to define entire
>libraries when experts in the field have failed to do so.

I think you are here not clearly making a distinction between C++ language
additions and library additions:

The language additions should always be minimized, and preferably only
introduce the hooks needed for library additions.

But once those hooks are in place, if it does not put too much strain on
compiler writers, then one can just as well add a library, if it is
sufficiently general (= platform independent) in nature.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 12 May 2001 15:58:26 GMT
Raw View
In article <3AFBACD0.C3D8F633@divalsim.it>, Nicola Musatti
<objectway@divalsim.it> writes
>Declaring a destructor pure virtual is a way of ensuring that a class
>remains abstract even if you change your mind about the "purity" of
>other member functions.

I know, but why would you actually do this in practice? If every
function has an implementation in the base, why worry about making it
abstract? This sounds like a case for having a protected dtor.



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 12 May 2001 15:58:17 GMT
Raw View
In article <3AFBDB63.CEDBA616@dollywood.itp.tuwien.ac.at>, Christopher
Eltschka <celtschk@dollywood.itp.tuwien.ac.at> writes
>BTW, one side remark:
>
>It is implementation defined, if
>
>class X { virtual ~X() = NULL; };
>
>is legal :-)

? the compiler per se never sees 'NULL' as it has been replaced by the
preprocessor. Now there are stupid things that NULL could be #defined as
that might fail (e.g. #define NULL 1-1) but I do not know of any real
world implementation which would fail. Is there one?


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 12 May 2001 20:12:31 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3AFBDB63.CEDBA616@dollywood.itp.tuwien.ac.at>, Christopher
> Eltschka <celtschk@dollywood.itp.tuwien.ac.at> writes
> >BTW, one side remark:
> >
> >It is implementation defined, if
> >
> >class X { virtual ~X() = NULL; };
> >
> >is legal :-)
>
> ? the compiler per se never sees 'NULL' as it has been replaced by the
> preprocessor. Now there are stupid things that NULL could be #defined as
> that might fail (e.g. #define NULL 1-1) but I do not know of any real
> world implementation which would fail. Is there one?

That's not relevant to the question of whether it's
implementation-defined. Now, the question of whether it's almost always
safe is a different matter entirely.

---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sat, 12 May 2001 20:16:51 GMT
Raw View
Sat, 12 May 2001 15:22:23 GMT, Heinz Huber <hhuber@racon-linz.at> pisze:

> I think it would be better to have the compiler treat the addition as:
> Align operator+(Align op1, Align op2);
> instead of using:
> int operator+(int op1, int op2);

But such addition often doesn't make sense: we can have for example
    DayOfWeek operator+ (DayOfWeek day, int delta);
    DayOfWeek operator- (DayOfWeek day, int delta);
    int operator- (DayOfWeek day1, DayOfWeek day2);
(and they should wrap), but not
    DayOfWeek operator+ (DayOfWeek day1, DayOfWeek day2);

> enum Enum { val1, val2 };
> Enum e =3D val1 + val2;
> The line above might (would?) trigger undefined behaviour since the res=
ult of
> (val1 + val2) doesn't fit into Enum.
> On the other hand, the following line would be OK:
> int i =3D val1 + val2;
> The return type of the addition is int in both cases, but may be used a=
s Enum
> without having to rely to a cast.

I don't see how the above could be derived from consistent rules.
What is the type of val1 + val2?

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: "Wilka" <wilka@ritualistic.com>
Date: Sat, 12 May 2001 20:18:22 GMT
Raw View
Provide a way to force a virtual function to be overridden, the current
'pure' method doesn't work very well when you derive from a class that
already has it's own version of that function. e.g.

class Base
{
    virtual std::string GetStringID() const = 0;
    // ...
};

class Derived : public Base
{
    virtual std::string GetStringID() const { return "Derived";}
    // ...
};

class MoreDerived : public Derived
{
    // no override of GetStringID
    // ...
};

Now when GetStringID is used on MoreDerived, it'll return "Derived" which
will cause problems when used, e.g. persistence and Visitor Design Pattern
(assuming GetStringID was changed to Accept). If Base was instead something
like:

class Base
{
    _Required virtual std::string GetStringID() const = 0;
    // ...
};

It would be an error to create an object of type 'MoreDerived' even though
'Derived' has an override of GetStringID.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 13 May 2001 05:25:42 GMT
Raw View
One might also consider to add a better preprocessor to C++:

Incidentally, I am writing on a macro language which I call a formatter,
which I use, via a Flex/Bison generated parser, to write C++ code. It
turns out that it is quite difficult to write C++ code directly, so I had
to invent this language. (So I might come up with better suggestions later
on, when I have written more on this formatter.)

As the name suggests, the formatter, unlike the C preprocessor, has the
capability to write files that are to some extent formatted, that is,
classes look like normally hand written classes, etc. This is not an
essential functional feature, but is important for debugging purposes,
because it is easy for a human to read.

In order to be able to write arbitrarily nested sub-classes and their
member functions definitions, I had to add TeX style definitions within
definitions, in fact the expanded macro definitions version.

The main difference between this formatter and such macro languages
though, is that I have the capability to define environments globally in a
way that another macro later can enter it and use in the expansion. This
makes it possible to read the formatting macros and the parser generated
environment definitions separately and then merge them in an output.

This makes it easy to let generate say a pair of files, like a header and
a source file.

I have also added special capabilities to create sequences of
environments, which is useful when writing arrays or a sequence of
classes.

So, there are several ways one might enhance the preprocessor that C++ uses.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Wilka" <wilka@ritualistic.com>
Date: Sun, 13 May 2001 05:25:54 GMT
Raw View
> > > > class A {
> > > >   A (int i) { /* code_1 */ }
> > > >   A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
> > > > };
> > > >
> > > > code_2 is executed after full construction and the execution of
code_1.
> > >
> > > If code_2 throws, should the destructor be run?
> >
> > No, because A isn't constructed yet. I would treat the ctor forwarding
> > more like a function call (like your init(), but with the option of a
> > initializer lists).
>
> But then if the A(int) constructor allocates ressources,
> the A(B const&) constructor will have to release them manually
> in case of exceptions, which is quite error prone.

The A(int) constructor will have the same problems when called normally,
i.e. the need to correctly tidy up if an exception is throw. So if there is
an exception when called via the initialiser list, it'll tidy up as normal
and the body of A(B const&) won't be executed.


>
> Also, if A(int) is called directly, then the object is considered
> completely constructed after it's return, i.e. in an usable state.
> If A(int) returns due to a "chained call", the object is already
> in the same state, but this time, it is not considered completely
> constructed. This is IMHO a bad inconsistency.

This could also cause problems with multiple calls to a base class ctor,
e.g.

struct A : B
{
    A::A(int n) : B(n) { /* code */}
    A::A(int n, float f) : B(n), A(n) { /* code */}
};

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sun, 13 May 2001 05:26:17 GMT
Raw View
In article <remove.haberg-1105012010470001@du128-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>The language additions should always be minimized, and preferably only
>introduce the hooks needed for library additions.

Also to increase consistency and simplify using the language.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Sun, 13 May 2001 05:26:22 GMT
Raw View
In article <kvtsXACKd8+6EwHT@ntlworld.com>,
francis.glassborow@ntlworld.com says...
> In article <KutK6.683$bi2.49473@www.newsranger.com>, Michiel Salters
> <Michiel.Salters@cmg.nl> writes
> >One of the things I didn't see yet is to add another signature
> >for main, support mandatory. I propose to add
> >int main( std::vector< std::string > ), which would be valid
> >only in programs that include both <string> and <vector>. The
> >behavior is obvious, I think.
>
> Interesting (actually compilers could support that now) why not write up
> a proposal and we can thrash it out (I will bring it to the UK's C++
> panel if it seems appropriate as a first filter before promoting it
> further)

I think that's a good idea. And if changes to the
signature of main are considered, I suggest that
alternatives for all available signatures be available
with a return type of void. It is very annoying to
have to always return something from main when
normally I never return anything from main. The only
real use for returning something from main is writing
batch programs where the return code is used to direct
a script. I almost never write such programs and I
suspect that most programs don't fall into that
category.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 13 May 2001 11:47:30 GMT
Raw View
In article <hndmft831i2spfnsuojtj6arflt8jjkmf0@4ax.com>, Mark Blewett
<mblewett@nildram.co.uk> wrote:
>After following some of the c++ newsgroups for many years albeit with
>minimal postings, "Its undefined behaviour" seems to be a very common
>answer to posts. Isn't time to eliminate those questions?

I think one should consider ways of eliminating those, but that may not be easy:

Take for example the de-referencing of a 0 pointer, which is undefined. It
is not possible catch such dereferencing at compile time, because a
pointer can be assigned different values at runtime, which then may or may
not be a 0 pointer.

So then one may decide to say that the dereferencing of a zero pointer
should throw an exception or something in order to get rid of the
"undefined" -- but that may cause unacceptable runtime overheads, given
the current computer technology.

In the future, it may be feasible to throw an exception in such cases. But
for now, most surely the bets one can hope for is that the debugger
catches those cases.

Perhaps one should generate a list with all those "undefined" cases, for
easy access as a basis for discussions.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Marco Dalla Gasperina" <marcodg@home.com>
Date: Sun, 13 May 2001 11:49:27 GMT
Raw View
"Dave Harris" <brangdon@cix.co.uk> wrote in message
news:memo.20010511073727.46671A@brangdon.madasafish.com...
[snip]
> I put this forward in the spirit of brain-storming. I don't have a
> fully-worked out proposal and doing one will obviously involve a lot of
> work and careful design. However, I hope the above is enough to show how
> explicit sequences may be able to make the STL easier to use, less
> error-prone, more generic and more efficient.

I'll throw in my support for Mr. Harris' idea as I've tried to
do something similar.  There are additional advantages in that
this supports what I would call virtual sequences: things that
are sequences but don't occupy the memory of sequences...

An example is the sequence of integers from 0 to 1,302,325.
(This brings up the ability to apply a functor to a sequence
as well... the result being another sequence).

marco


---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sun, 13 May 2001 11:50:21 GMT
Raw View
Sun, 13 May 2001 05:26:22 GMT, Michael Lee Finney <michael.finney@acm.org=
> pisze:

> I suggest that alternatives for all available signatures be available
> with a return type of void. It is very annoying to have to always
> return something from main when normally I never return anything
> from main.

You cal declare main as returning int and omit the return statement
at the end. There is a special exception for main which allows to do
that, defaulting to 'return 0;'.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Mon, 14 May 2001 11:17:00 GMT
Raw View
Nicola Musatti wrote:
>
> Wilka wrote:
> >
> > > 2. using Base;
> > >    Example:
> > >
> > >      class Derived : private Base {
> > >        public:
> > >        using Base;  // expose the entire public interface of Base.
> > >        // ...
> > >      };
> > >
> >
> > Or maybe:
> >
> > class Derived : using Base {
> >     // Derived now exposes the entire public interface of Base.
> > }
>
> You can already do this with public inheritance.

The difference is that public inheritance provides also
an implicit conversion (Derived*) -> (Base*), and that
is not wanted.

-- James Dennett

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Mon, 14 May 2001 11:17:32 GMT
Raw View
Francis Glassborow wrote:
> In article <9dcq7k$o6e$1@kilmer.bain.oz.au>, Nick Thurn
> <nickt@kipling.aus.deuba.com> writes
> >The lack of a set of standard containers is one of
> >Bjarne's regrets. The RTTI added to C++ is basically useless
> >if you wish to use it for persistence or to cross a network
> >because there is no portable tag for types.
>
> But RTTI was actually introduced to standardise existing practice :)
>
The smiley is indeed appropriate ;-).

> >The missing void
> >polymorphic pointer
>
> You mean you wanted a way to collect completely unrelated objects?

Yes! Currently you have to provide your own as with useful RTTI.
These things are basic and should be standard IMO.

cheers
Nick

---
[ 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: Alexander Terekhov <terekhov@web.de>
Date: Mon, 14 May 2001 11:18:03 GMT
Raw View
Christopher Eltschka wrote:

> Alexander Terekhov wrote:

[...]
> >
> > however, I would really prefer to write:
> >
> > Singleton& Singleton::getInstance()
> > {
> >    static synch Singleton theSingleton; // synchronized local static
> >    return theSingleton;
> > }
> >
> > so that via "static synch" the language implementation would provide
> > the correct and most effective solution for lazy initialization in
> > MT environment on each particular platform; e.g. DCL with memory
> > barriers or tsd (who knows which is faster) for multiprocessors with
> > weak memory models, "classic" DCL for all uniprocessors and
> > multiprocessors
> > with strong memory model or something completely different; platform
> > specific.
> >
> > that would also ensure zero overhead ("synch" should be just
> > ignored by compiler) if my code/lib would be compiled for running
> > in ST environment only (without -pthread option or similar). btw, that
> > is
> > the only reason why "static synch" locals would do better than already
> > portable pthread_once - I just do not like to maintain two versions;
> > one with pthread_once for MT programs and another with static locals
> > for ST programs.
>
> There is another reason: What happens if the constructor exits with
> an exception? I doubt that pthread_once even defines the behaviour
> in that case (since it's a pure C interface). In addition, even if
> your implementation lets the exception through, it will not create the
> object the next time you get there, since pthread_once notices that
> you already called the function.

well, you are right -- since C++ does not even mention threads
(and pthreads is a pure C interface), C++ exceptions and pthread_once
is a non-portable/implementation specific feature. However, POSIX/
pthread_once defines the following:

"The function pthread_once() is not a cancellation point.
 However, if init_routine() is a cancellation point and
 is canceled, the effect on once_control is as if
 pthread_once() was never called."

so, I would expect that C++ impl. which would have
exceptions integrated with pthreads cancellation
cleanup handlers (basically using the same underlying
mechanism) would have no problems here, but this is
just my expectation..

>The semantics of static already does the right thing.

yup. and I really wish to see thread safe version (e.g.
with added "synch" or something similar) to be defined
in C++0x language (together with some C++ wrappers
for synchronization primitives and some other useful
things such as post-constructors/pre-destructors).

regards,
alexander.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 14 May 2001 11:18:23 GMT
Raw View
In article <remove.haberg-1305011216110001@du136-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>Perhaps one should generate a list with all those "undefined" cases, for
>easy access as a basis for discussions.

Try grepping a copy of the C++ Standard for the word 'undefined'. The
result may shock you. I think some of us will be looking at ways to
reduce the size of that list, but there are many cases where the cost of
removing it exceeds what many want to pay (in many cases you would have
to abandon separate compilation)



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Daniel James <internet@nospam.demon.co.uk>
Date: Mon, 14 May 2001 11:17:57 GMT
Raw View
In article <3AF82117.30D531EE@jps.net>, Dennis Yelle wrote:
> The real problem is not that stuff.x+2 and stuff.y compare equal.
> The real problem is that the clear meaning of the text of the
> standard is that they do NOT compare equal.

Upon reflection (and having had a look at a colleague's copy of the
standard) I think that a literal interpretation of the standard does say
that.

To my mind stuff.x and stuff.y are different objects, and any comparison
of two pointers 'into' them (i.e. one pointer pointing to an element of
stuff.x or one past the end, and another pointer pointing to an elemnt of
stuff.y or one past the end) is not in keeping with the 'spirit' of what
the standard attempts to define. After all, what we're trying to say here
is that two pointers compare equal if they point to the same thing, and
compare unequal if they point to different things, if and only if it is
meaningful to compare them. I would suggest that it isn't (and shouldn't
be) meaningful to compare pointers to different objects and if you try it
you're on your own.

Let me give you another example:

  struct different_junk {
     short x[3];
     long y[2];
   } stuff;
   if ( stuff.x+3 == stuff.y)
     cout << "same\n";
   else
     cout << "different\n";

Here, as in the original example, we are comparing the one-past-the-end
pointer of one array with the start address of another array that follows
it in memory. I can imagine that some compilers will print "same", but
other compilers will print "different" because they have inserted a 2-byte
gap between the end of x and the start of y so that y's elements will be
correctly aligned for efficient (and legal - depending on the platform)
access of y.

A compiler /HAS/ to be free to insert that padding if it needs to, so the
standard cannot constrain stuff.x+3 to be equal to stuff.y - but equally
it certainly shouldn't prohibit them from being equal.

However, I take back my claim that the bahaviour is "undefined", I think
it should be "implementation defined" ... and the discussion we've been
having over it here seems to me to suggest that the standard should be
updated to say that explicitly.

I don't think there's any need to go beyond "implementation defined" and
struggle with the kind of verbiage that James Kuyper tells us the C99
standard has introduced ...

> ... or one is a pointer to one past the end of one array object
> and the other is a pointer to the start of a different array
> object that happens to immediately follow the first array object
> in the address space.

[which is insufficient anyway, because the "other pointer" might be a
pointer to a non-array object that just "happens to follow...".]

Cheers,
 Daniel.


---
[ 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: "Mirek Fidler" <cxl@iol.cz>
Date: Mon, 14 May 2001 13:33:48 GMT
Raw View
> Singleton& Singleton::getInstance()
> {
>    static synch Singleton theSingleton; // synchronized local static
>    return theSingleton;
> }

    I think this could be solved via template:

template <class T>
class Synchronized {
    T   *var;
public:
    Synchronized() {
        if(!var) {
            GlobalLock();
            if(!var) {
                static T x;
                var = &x;
            }
            GlobalUnlock();
        }
    }
    operator T&()        { return *var; }
};

Singleton& Singleton::getInstance() {
    static Synchronized<Singleton> theSingleton;
    return theSingleton;
}

    or even

template <class T>
T& Singleton() {
 static T *p;
 if(!p) {
    GlobalLock();
    if(!p) { static T o; p = &o; }
    GlobalUnlock();
 }
 return *p;
}

    there is no need to add new language features here.

Mirek



---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 9 May 2001 21:16:37 GMT
Raw View
Dennis Yelle wrote:
>
> "James Kuyper Jr." wrote:
> >
> > Radoslav Getov wrote:
> > >
> > > "James Kuyper Jr." <kuyper@wizard.net> wrote in message
> > > news:3AF54E87.C934B2C6@wizard.net...
> > >
> > > [snip]
> > >
> > > >
> > > > The point is that the standard says that the pointers can compare equal
> > > > if, and ONLY if, they are both NULL, both point to the same object, or
> > > > both point one past the end of the same object. Unless you recognize
> > > > stuff.x+2 and stuff.y as pointing at the same object (namely y[0]), then
> > > > having them compare equal looks like a violation of the standard.
> > > >
> > >
> > > It looks to me that this
> > > 'past-the-end-of-an-array-being-a-somewhat-valid-pointer
> > > concept (obviously required by STL) causes this problem. I think, though,
> >
> > The concept predates STL, and even C++ itself. It's used in the C
> > standard as well.
> >
> > > that it might have been easylly fixed by the code generators (by adding
> > > space only for an extra
> > > element at the end of any array).
>
> That "fix" is worse than the problem.
>
> > One interpretation (which I consider false) is that the this wording
> > requires precisely that implementation.
>
> The real problem is not that stuff.x+2 and stuff.y compare equal.
> The real problem is that the clear meaning of the text of the
> standard is that they do NOT compare equal.
>
> Some people claim to be able to bend the text of the standard
> in their minds to the point that it allows stuff.x+2 and stuff.y
> to compare equal.
> I am unable to do that.

Well, it's easy:

Both point to the same object (stuff.y[0]), and both point past
the end of the same array (stuff.x). Therefore even _both_ parts
of the last "or" are fulfilled.

> So I think that the text of the standard should be changed.

I agree, but not because I think the current text doesn't allow it,
but because it is misleading.

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Thu, 10 May 2001 06:22:22 GMT
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote (abridged):
> Now my other concern is really about how operators on enums effectively
> convert the answer to an integer type (which depends on the underlying
> type of the enum) which is fine until you want to use an assignment.
> This may get worse with an explicit requirement that compound
> assignments can only be overloaded in class scope.
>
> A possibility (haven't thought much about it yet) is to make all
> operations on pure enums return an enum of the same type rather than
> default to conversion to an integer type. I think this would mean,
> among other things that:
>
> enum X {x1, x2, x3};
> enum Y {y1, y2, y3};
>
> int main (){
> X x=x1;
> Y y=y1;
>
> int i = x+y;
> // ERROR, no default operator+(X, Y)
> x++; // fine
> x += x2; // fine
> x = x + x2; // fine
> // note that currently there is no way to write this without
> // providing an operator+ for X and you have to provide all
> // the operators you intend to use because you cannot overload
> // the assignment operator
>
> ...
> }

I think it is good that we only have the operators we ask for. Eg:

    enum Colour { Red, Green, Blue, End };

    Colour c = Green + Blue;

addition does not make sense for colours so should not be provided by
default. I agree it would be nice if we could provide it without a cast.

I have toyed with using namespace composition in the past, eg:

    namespace EnumIncrement {
        template <typename E>
        E operator++( E &e ) {
            return e = E(e+1);
        }
        // Post-fix and decrement operators too.
    }

where the operators are in a namespace so they do not apply to enums
where they are not wanted. Then:

    namespace Colour {
        enum Type { Red, Green, Blue, End };
        using namespace EnumIncrement;
    }

has the effect of making the operators available just for my Colour type.
If enums were namespaces this would work better - it would avoid the
meaningless name "Type".

However, using namespaces for access control feels dubious. Perhaps
instead of:

> namespace enum X {begin, end};

it should be:
    class enum X { begin, end };

giving a closed scope, optional private functions etc. Then addition
operator could be system-provided by default, but only privately. We
would need something like:

    class enum Colour {
    public:
        Red, Green, Blue, End;
        using operator++;
    };

to export it.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Thu, 10 May 2001 06:22:37 GMT
Raw View
Martijn Lievaart wrote:
> nickt@kipling.aus.deuba.com (Nick Thurn) dared to utter in
>
> I don't disagree with many of the things you said but:
>
> >
> > One thing the standards process did that was wrong was
> > concentrate too much on invention. In some cases this was
> > gratuitous:
> >      - templatized streams
> >      - templatized string
> >
>
> Gratuitous? A life saver for anyone working with Unicode. I know many
> native English speakers don't care to much beyond ASCII, but for most the
> rest of the world all those at-most-8-bit character codes are a real-life
> headache. These templatizations are a must for working with 16 or 32 bit
> character codes.
>
The fact that the implementation of these classes is shared is a detail
you should not have to be concerned with.

I agree that wide character versions of these are absolutely necessary.
Templatizing the classes is not, it's just one implementation approach.

cheers
Nick

---
[ 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: Herb Sutter <hsutter@acm.org>
Date: Thu, 10 May 2001 06:25:39 GMT
Raw View
Matthew Austern <austern@research.att.com> writes:

>"Rene" <rene413@home.com> writes:
>
>> What I don't understand is why it takes 6 years to make a change to a
>> programming language!!
>
>It doesn't.  We could make changes every six months, if we thought
>that was a good idea.  Most people think it wouldn't be.

Matt is right, although there are ISO bureaucratese requirements that
stretch that time a bit. As I fondly remember Bill Plauger saying (and
probably others have said it before him): "In ISO everything takes at least
two years. At an ISO meeting, if someone yells 'Fire!' it's two years before
the last person makes it to the exit." For a while, the SQL committee was
generating a standard every three years (SQL86, SQL89, SQL92) -- it can be
done.

Matt is still right, though, that we could produce a new standard every six
months anyway, but they'd just be offset -- the one you get this week would
be the one we passed a year ago, and the one one we passed today wouldn't be
officially ratified till a year later, etc. This leads to interesting
situations for fast committees -- recently, the SQL committee was already
doing active work on SQL0x while SQL99 was still being ballotted (i.e., had
not been approved yet!); in fact, at one meeting we were already approving
amendments to a Technical Corrigendum document which did not officially
exist (because it wasn't allowed to) to the SQL99 FDIS which did not
officially exist (it was not yet a standard, it was still in the ballotting
phase). Truly weird, but good for a laugh -- the SQL committee simply
decided that they weren't going to wait to get stuff done.

Herb

---
Herb Sutter (http://www.gotw.ca)

Contributing Editor, C/C++ Users Journal (http://www.cuj.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                ]





Author: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Thu, 10 May 2001 17:24:51 GMT
Raw View
Alexander Terekhov wrote:
>
> Nick Thurn wrote:
>
> [...]
> > No barrier construct for multi-threading:
> >        - no way to make double checked locking work portably
>
> there is a way to make it work portably; using thread locals (tsd).
> here is a compact example in Java (in C++ you would need to have
> a "portable" class similar to ThreadLocal or just stick to C/POSIX
> pthreads for tsd):
>
>   class Singleton {
>     private static Singleton theInstance;
>
>     private static final ThreadLocal perThreadInstance =
>       new ThreadLocal() {
>           public Object initialValue() { return createInstance(); }
>         };
>
>     public static Singleton getInstance() {
>       return (Singleton)perThreadInstance.get();
>     }
>
>     private static synchronized Singleton createInstance() {
>       if (theInstance == null)
>         theInstance = new Singleton();
>       return theInstance;
>     }
>
>   }
>
> however, I would really prefer to write:
>
> Singleton& Singleton::getInstance()
> {
>    static synch Singleton theSingleton; // synchronized local static
>    return theSingleton;
> }
>
> so that via "static synch" the language implementation would provide
> the correct and most effective solution for lazy initialization in
> MT environment on each particular platform; e.g. DCL with memory
> barriers or tsd (who knows which is faster) for multiprocessors with
> weak memory models, "classic" DCL for all uniprocessors and
> multiprocessors
> with strong memory model or something completely different; platform
> specific.
>
> that would also ensure zero overhead ("synch" should be just
> ignored by compiler) if my code/lib would be compiled for running
> in ST environment only (without -pthread option or similar). btw, that
> is
> the only reason why "static synch" locals would do better than already
> portable pthread_once - I just do not like to maintain two versions;
> one with pthread_once for MT programs and another with static locals
> for ST programs.

There is another reason: What happens if the constructor exits with
an exception? I doubt that pthread_once even defines the behaviour
in that case (since it's a pure C interface). In addition, even if
your implementation lets the exception through, it will not create the
object the next time you get there, since pthread_once notices that
you already called the function.
The semantics of static already does the right thing.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Thu, 10 May 2001 17:24:45 GMT
Raw View
Francis Glassborow wrote:
>
> In article <memo.20010509061258.57395A@brangdon.madasafish.com>, Dave
> Harris <brangdon@cix.co.uk> writes
> >Why do you need operator=() for enums?
> >
> >With most functions, they can be added outside the enum's own scope:
> >
> >    enum Align { Left, Center, Right, End };
> >
> >    Align &operator++( Align &e ) {
> >        return e = Align(e+1);
>
> exactly because of that cast, requiring a cast to do something natural
> is adding potential for errors being hidden by the cast.

But IMHO allowing "enum = int" globally(!) is worse than this cast.
And it seems this is exactly what you had in mind, according to
your example.

[...]

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Thu, 10 May 2001 17:24:58 GMT
Raw View
Olaf Krzikalla wrote:
>
> public: //was: private:
>   my little list of wishes:
>
> 1. ctor forwarding. I don't want to derive just to get a new ctor.
> Better:
>
> class A {
>   A (int i) { /* code_1 */ }
>   A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
> };
>
> code_2 is executed after full construction and the execution of code_1.

If code_2 throws, should the destructor be run?

What's wrong with

class A
{
public:
  A(int i) { init(i); }
  A(B const& b) { init(makeInt(b)); /* code_2 */ }
private:
  void init(int i) { /* code_1 */ }
};

[...]

---
[ 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: Tim Sharrock <tim@sharrock.org.uk>
Date: Thu, 10 May 2001 17:25:18 GMT
Raw View
On Sat,  5 May 2001 23:25:08 GMT, Francis Glassborow
<francis.glassborow@ntlworld.com> wrote:

>[...]  For now
>I would like to see the brain storming rules applied -- anything goes
>and people must not be overtly negative about other peoples suggestions.
>When we have a stack of suggestions, then will be the time to winnow thw
>wheat from the chaff.

I would like to be able to use standard containers optimised for space.

std::vector::reserve, for example is specified in such a way that there
you can provide a minimum value for the capacity, but not a maximum.
There is a common idiom for "shrink to fit", involving swapping with a
freshly created copy of the container, but there are no guarantees that
the fresh copy does not have lots of expansion space. At least with
std::vector you can at find out the capacity at run-time.

std::deque, on the other hand, typically uses a paged data-structure,
but there is no standard way to enquire its properties, or to provide
hints as to usage. I would like to be able to hint to a deque that I
am likely to have about 100 elements active at once, but that there
are many of these deques about, so please don't leave much spare
capacity at any time.

Tim

--
Tim Sharrock   (tim@sharrock.org.uk)

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 10 May 2001 17:25:46 GMT
Raw View
In article <3AF91605.81F7206A@divalsim.it>, Nicola Musatti
<objectway@divalsim.it> writes
>The problem is that currently if you declare your destructor, it is not
>synthesised. Normally this is what you want because you declare it to
>implement it. However when you declare your destructor pure virtual you
>are forced to provide a body you're often not interested in and to write
>it outside the class definition.

I do not think that pure virtual dtors actually do anything useful
(unless their bodies are non-empty)


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 10 May 2001 17:25:29 GMT
Raw View
In article <9dasjn$hdhv0$1@ID-49767.news.dfncis.de>, Anthony Williams
<anthwil@nortelnetworks.com> writes
>But you use a pure virtual destructor where you wish to make the base class
>abstract by having at least one pure virtual function, but there is no other
>candidate virtual function that you want overridden in all cases.

Yes, I know the 'idiom' but have yet to see a case where it was really
useful. If all the other functions are OK and do not have to overridden
why make the class abstract? Just give me a good (i.e. not contrived)
example.



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Thu, 10 May 2001 17:26:18 GMT
Raw View
Dima Volodin wrote:
> Nick Thurn wrote:
> >
> > No barrier construct for multi-threading:
> >         - no way to make double checked locking work portably
>
> Why should it be portable?
>
Because simple clear code like:

 static kblather* something;

 if (something == 0)
 {
  Guard guard(somemutex);
  if (something == 0)
   something = new kblather;
 }

should be able to be made portable. Say by being able to tell the compiler
not to do clever swaperoos with code

 static kblather* something;

 if (something == 0)
 {
  new_swaperoo_stopper<thingy> Guard guard(somemutex);
  if (something == 0)
   something = new kblather;
 }

> >         - no way to ensure lock occurs before data access portably
>
> POSIX threads is a pretty portable thing, and while a C++ variant of POSIX would
> be nice to have, I don't think it should be a part of C++ per se.
>
This isn't anything to do with POSIX per se. It is todo with stopping
code being swapped in front of a lock. Which (and correct me if I'm wrong)
there is no way to ensure in C++ at the moment.

> > The simplification Mark speaks of is needed. It should be possible
> > to use the commonly needed subset of the language with efficient
> > compilation and meaningful error reporting. If this requires
> > a martian savant to implement the compiler then the language
> > should be changed so a lowly 21st century human can actually
> > do it.
>
> Just come up with a different name for the language you want (too bad that good
> names like "Java" or "C#" have been taken already). Calling this other language
> "C++" won't fix anything, but mess the things up beyond any repair.
>
Sorry, this is an and unhelpful response - "If you don't like it use
another language". Currently the vast bulk of C++ programmers use VC++ and
largely ignore the standard (statistics based on wild-assed guess but likely
accurate). VC++ probably already qualifies as "another language" (not unlike
C++ Builder!!). Looking at opensource C++ the usage of the standard is also
pretty bad.

I'm not a language lawyer/compiler write/std library implementer/vendor.
I can't recite the standard backwards in my sleep but I attempt to use
C++ for real work and try to conform to the standard. If I'm not mistaken,
C++ needs people like me ;-).

cheers
Nick

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Thu, 10 May 2001 17:27:00 GMT
Raw View
Francis Glassborow wrote:
> In article <9da824$ah1$1@kilmer.bain.oz.au>, Nick Thurn
> <nickt@kipling.aus.deuba.com> writes
> >One thing the standards process did that was wrong was
> >concentrate too much on invention.
>
> I get tired of hearing this, when mostly the work on the core of the
> language was rejecting demands for extensions and invention (note that
> templates and exceptions were in the original specification documents
> for standardisation)
>

Sorry you're tired of this and I'm glad you rejected most of the
extension requests. I have never said templates and exceptions
were invention. Others actually involved in the process complained
bitterly because of the amount of invention rather than
standardisation and were roundly caned for their trouble (at
least that's the impression I have).

> >In some cases this was
> >gratuitous:
> >       - templatized streams
> >       - templatized string
>
> These are library issues, an area in which mistakes are often made, but
> one that can be corrected by substituting alternatives (something that
> cannot so easily be done to the core of the language)
>
No these are *standard* library issues now.

> >
> >Other areas were rendered useless for their main purpose:
> >       - type_info::name for persistence
> >
> >Other common usages were simply ignored as "bad practice"
> >despite these containing the bulk of actual users:
> >       - c++ ala C++/Views, MFC ... basically any GUI tool kit
> >
> >No barrier construct for multi-threading:
> >       - no way to make double checked locking work portably
> >       - no way to ensure lock occurs before data access portably
>
> Now it seems you wanted the Committee to be inventive (often the case
> that people want no inventions other than those they want:)
>

No, what I cite are necessary to quell the chaos caused by their
omission.

The lack of a set of standard containers is one of
Bjarne's regrets. The RTTI added to C++ is basically useless
if you wish to use it for persistence or to cross a network
because there is no portable tag for types. The missing void
polymorphic pointer has led to gazillions of CObject
RWCollectable ZObject...etc. The missing synch or barrier
or whatever makes MT code possibly non portable.

I love and use C++ (and not VMcC++ either :). I'm sorry
that my frustrations tire you. I'm sure there are many
stories to tell about the standardisation process and
that the outcome could have been much worse. Thank you
for ensuring it wasn't. This doesn't alter the fact that
std C++ is becoming IMO marginalized.

cheers
Nick


---
[ 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: "Ney Andr de Mello Zunino" <zunino@ias.unu.edu>
Date: Thu, 10 May 2001 17:27:37 GMT
Raw View
Hi.

"Anthony Williams" <anthwil@nortelnetworks.com> wrote in message
news:9dasjn$hdhv0$1@ID-49767.news.dfncis.de...
>
> What would be good would be to allow bodies for pure virtual functions to
be
> provided in the class definition, in which case writing
>
> class MyClass{
> virtual ~MyClass()=0{}
> };

Agreed. That is something I (and I believe many others too) have wished for
long.

> I also think that a proper keyword (pure?) would be better than the
current
> '=0' syntax for pure virtual functions.

Ditto. I have never really liked the '= 0' syntax. By the way, that reminds
me of a little story. I once had a CS professor who notably disliked C++
(and probably still does). I used to think that the reason for that was
because he did not really know the language and probably assumed that
programming in it was very similar to programming in C.

I can never forget the day I tried to make him change his mind by showing
him an implementation of Graphs that I had written. I started by showing him
the driver code which made use of my Graph template class. I had been
careful enough in the definition of my interfaces, so that clients would
never need to use pointers or the '&' operator upon calling methods. He
agreed that the code looked much clearer than he would ever expect, which
went to show that my suspicions had reason.

Next, I decided to show him the classes' definitions. The moment he put his
eyes on my abstract class, he asked me: "- What is the deal with that '= 0'
over there?" After I told him that was meant to mark a method as pure
virtual, he asked me: "- So why not just say 'pure' instead? Why make things
unnecessarily cumbersome?" Hum... Maybe here is one of the few things I must
agree with him. :)

Regards,

Ney Andr    de Mello Zunino.

"Take of the fruit,
    But guard the seed..."


---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Thu, 10 May 2001 17:27:45 GMT
Raw View
news/comp.std.c++@nmhq.net (Niklas Matthies) wrote (abridged):
> Wouldn't the better approach be to not use numerical precedence levels
> of fixed range and granularity, but instead define the precedence of
> some operator relative to the precedence of already-declared operators?
> I.e. one could specify that opX should have the same precedence as opY,
> or specify that it should have higher precedence than opA but lower
> precedence than opB. The compiler would infer a partial ordering on
> operator precedence from this (after having checked that there are no
> cycles), and would complete it to a total ordering (in some
> implementation-specific way, so that one can only rely on the
> precedence relations that were specified by the operator declarations).

This is the approach Cecil takes. I have no idea whether it is any good
:-)

If this stuff looks too ambitious, I think we should consider adding just
a handful of operators whose sole purpose is to be overloaded. That would
be less surprising than giving new meanings to old names.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Michiel Salters<Michiel.Salters@cmg.nl>
Date: Thu, 10 May 2001 17:28:38 GMT
Raw View
In article <Qnvh1QBNdE96EwZc@ntlworld.com>, Francis Glassborow says...
>
>In article <w2EI6.142$BH6.22342@newsread1.prod.itd.earthlink.net>, Matt
>Seitz <mseitz@yahoo.com> writes
>>One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is Dr.
>>Stroustrup's insistence that new features must be shown to give significant
>>improvements in an actual project before being added to the language.  This
>>often took the form of taking an existing project and showing how it could
>>be significantly improved by adding the new feature.   I would be interested
>>in reading of anyone performing a similar analysis regarding these
>>suggestions.
>
>
>Have no fear, suggestions will be rigorously analysed
>for benefit versus cost but the time for that is a little later. For now
>I would like to see the brain storming rules applied -- anything goes
>and people must not be overtly negative about other peoples suggestions.
>When we have a stack of suggestions, then will be the time to winnow thw
>wheat from the chaff.
>
>Francis Glassborow      ACCU

One of the things I didn't see yet is to add another signature
for main, support mandatory. I propose to add
int main( std::vector< std::string > ), which would be valid
only in programs that include both <string> and <vector>. The
behavior is obvious, I think.

The reason for this is teachability; "This is how other people do it".
I wouldn't want a student of mine passing a variable number of
strings as (char**,int). So why should I accept it from the compiler?

Currently I have to write something like

std::vector< std::string> arg ( argv,argv+argc );

which isn't too bad, only a bit redundant (in code & data memory).

--
Michiel Salters
Consultant Technical Software Engineering
CMG Trade, Transport & Industry
Michiel.Salters@cmg.nl

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Thu, 10 May 2001 17:28:46 GMT
Raw View
"Mirek Fidler" <cxl@iol.cz> wrote in message
news:9dasrk$2ad$1@news.vol.cz...
> > Override.
> > A new keyword, used in place of "virtual", which declares an intent to
> > override. It is an error to declare a member function with "override" if
> > it does not, in fact, override some base class member. Eg:
>
>     Yes, this was number two in my wishlist ;-) I would even suggest just
> the same syntax.

This was in my top 10 too.  But every new keyword hits
programs that already use it as a variable name.
Since this is essentially a source-level checking
feature I'd suggest a pragma.



---
[ 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: xnews.public.home@bogus.rtij.nl (Martijn Lievaart)
Date: Thu, 10 May 2001 17:28:57 GMT
Raw View
nickt@kipling.aus.deuba.com (Nick Thurn) dared to utter in
news:9dcl71$8ik$1@kilmer.bain.oz.au:

> Martijn Lievaart wrote:
>>
>> Gratuitous? A life saver for anyone working with Unicode. I know many
>> native English speakers don't care to much beyond ASCII, but for most
>> the rest of the world all those at-most-8-bit character codes are a
>> real-life headache. These templatizations are a must for working with
>> 16 or 32 bit character codes.
>>
> The fact that the implementation of these classes is shared is a detail
> you should not have to be concerned with.

I don't think this is correct, the implementation might be a
specialisation. They have the same interface, and that is all a user should
be concerned with.

>
> I agree that wide character versions of these are absolutely necessary.
> Templatizing the classes is not, it's just one implementation approach.
>

Yes, although imo a logical one.

Martijn Lievaart

---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 10 May 2001 17:29:49 GMT
Raw View
While we're at it...

Joseph Gottman wrote:
[...]
> template <class X, class Y>
> polynomial<typeof(X() + Y())> operator+(

... it should be legal to write the above as:

polynomial < typeof ( X + Y ) > operator+ (

And possibly also:

template <class X, class Y> typedef typeof(X+Y) polynomial;
template <class A, class B> polynomial<A,B> operator+(...

Best regards,
Nicola Musatti

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Thu, 10 May 2001 17:30:03 GMT
Raw View
On Thu, 10 May 2001 06:22:22 GMT, Dave Harris <brangdon@cix.co.uk> wrote:
> francis.glassborow@ntlworld.com (Francis Glassborow) wrote (abridged):
[=B7=B7=B7]
> > // note that currently there is no way to write this without=20
> > // providing an operator+ for X and you have to provide all=20
> > // the operators you intend to use because you cannot overload=20
> > // the assignment operator
>=20
> I think it is good that we only have the operators we ask for. Eg:
>=20
>     enum Colour { Red, Green, Blue, End };
>=20
>     Colour c =3D Green + Blue;
>=20
> addition does not make sense for colours

Actually, addition does make sense for colors (Green + Blue =3D Cyan), ...

> so should not be provided by default.

... but it is correct that this is hardly something that can be provided
by default.

-- Niklas Matthies

---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 10 May 2001 17:47:41 GMT
Raw View

Dennis Yelle wrote:
[...]
> When typeof, or any new keyword, is introduced, it could
> be introduced as _Typeof in the compiler proper, and then
>   #include <typeof>
> could just do the equivalent of
>   #define typeof _Typeof
>
> This technique can be used to silence those who always
> react to any suggestion of adding a new keyword by
> saying "No!!  That will break existing programs!!"
>
> Another advantage of this is that if a compiler does
> not implement some feature, it will fail cleanly on the
> #include line instead of producing many confusing error messages.

I think it would be simpler to associate a standard macro with every new
feature and require conforming implementation to define each macro if
and only if they implement the feature. We could then write

#ifdef __TYPEID
  typeid(a+b) c = a+b;
#endif

For complex features which might get introduced in steps a set of values
could be associated with each relevant macro so as to allow programmers
to deal with such features by means of #if directives.

Best regards,
Nicola Musatti

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 10 May 2001 18:37:41 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> writes:
> Why not? Make it left to right, and make a X b equivalent to writing
> operator X(a,b); Not that hard to parse.

The usual manner in PL's is to make declare something an operator and then
it only can be used as an operator in order to avoid (human and computer)
parsing problems.

So
    C operator r(A, B) infixl 7;
would require to always write "a r b" and nothing else.

However, if there should be another mechanism to write "r" an a regular
function. In Haskell, one writes
    (r)(a, b)
but C++ already has the construct
    operator r(a,b)
so I think it is better to merely use that one.

As for the compiler implementation, it is not difficult compared to all
the other stuff already in C++:

For strange operator names, one only needs a good way to mangle those names.

For the operator precedence, there are two different methods: If the
number of precedence levels is small, one can in a compiler-compiler like
Bison plug in all the levels:
%token op1l, ...

%left op1l
...

%%
  expr:
      expr op1l expr { /* action */ }
      ...
      expr op9l expr { /* action */ }
and let the lexer make a table lookup of the precedence of an operator
before returning one of the tokens op1l, ...

The other method, which is used when the number of precedence levels is to
instead have a grammar

%token opl, ...

%left opl
...

%%
  expr:
      expr opl expr { /* action */ }

and then the action puts the values in a stack, which is later combined
into an expression value by a separate program.

Pretty straightforward.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 10 May 2001 18:37:54 GMT
Raw View
In article <9dbu9s$c8s$1@cam-news1.cambridge.arm.com>, "Al Grant"
<tnarga@arm.REVERSE-NAME.com> wrote:
>> >There's nothing to stop a group like the X consortium
>> >publishing a C++ GUI library and people adopting it as a
>> >de facto standard.  Why do you think the language standards
>> >committee should spend time on this?
...
>> Your argument could be applied to any language feature
>
>No, because you can't buy a language feature and plug it into
>your compiler, or mix and match language features from different
>vendors.  You _can_ do this with libraries.

There was actually the suggestion a time ago in one of these C++ groups
that people pick down say the public sources of GCC and make their own
version of C++ before presenting it as a suggestion for inclusion into
C++.

So this is what people actually do; GCC is one example.

>> With GUI, as with any other feature, after a while there emerges a core
>> that is pretty much a de facto standard to humans, even though it may not
>> be a standard in the computer language sense.
>
>That's what the OSI VT people thought and they were wrong.

Perhaps they didn't look for a stable core, but something more general

>> The reason one is doing it is that there are people writing programs for
>> several different platforms, and any such prudent addition to a language
>> like C++ will help a lot.
>
>So do it.

Incidentally I gave a suggestion for a GUI feature in another thread.

>  Define a standard C++ GUI library and present it
>to the world.  Why does it impact on the C++ standards
>process?  If you are saying that C++ lacks _language_ features
>that are needed for your GUI library then that is a different
>thing altogether.  Propose those language features.
>Programmers in other areas might find them useful too.

Otherwise, I discussed the possibility of inclusion of such a GUI library,
whereas I get the impression that you say such discussions should not take
place.

It appears that these questions are up on the ball, but no-one knows if it
results in a happy marriage.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Thu, 10 May 2001 20:06:36 GMT
Raw View

Michiel Salters wrote:
>
>
> One of the things I didn't see yet is to add another signature
> for main, support mandatory. I propose to add
> int main( std::vector< std::string > ), which would be valid
> only in programs that include both <string> and <vector>. The
> behavior is obvious, I think.

Frankly, how about just std::string (forget the vector).  The entire
world isn't a UNIX shell.  Even on Windows the command line to ARGC/ARGV
gets a bit contrived.

By the way, if you're going to use std::string for system interfaces
like this (which I wholly recommend), please also allow for std::wstring,
The C++ compiler pretty lamely gets away with using char* because it
claims it's a NTMBS, but if you use std::string it's pretty hard to
continue that farce.

---
[ 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: nickt@kipling.aus.deuba.com (Nick Thurn)
Date: Wed, 9 May 2001 03:07:43 GMT
Raw View
Mark Blewett wrote:
>
> What C++ needs now is simplification, consolidation and
> standardization (not it terms of ANSI, but in terms of the language),
> possibily with the introduction of a mininimal set of new features.
>
Agree.

One thing the standards process did that was wrong was
concentrate too much on invention. In some cases this was
gratuitous:
 - templatized streams
 - templatized string

Other areas were rendered useless for their main purpose:
 - type_info::name for persistence

Other common usages were simply ignored as "bad practice"
despite these containing the bulk of actual users:
 - c++ ala C++/Views, MFC ... basically any GUI tool kit

No barrier construct for multi-threading:
 - no way to make double checked locking work portably
 - no way to ensure lock occurs before data access portably

Binder dependent STL with incomplete binder support.

We have ended up with a language that is tricky, hard to learn,
really hard to compile and not yet implemented in any commercial
compiler. Personally I believe this is bad.

The simplification Mark speaks of is needed. It should be possible
to use the commonly needed subset of the language with efficient
compilation and meaningful error reporting. If this requires
a martian savant to implement the compiler then the language
should be changed so a lowly 21st century human can actually
do it.

cheers
Nick

PS apologies to any martians offended by the above...

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 9 May 2001 12:17:10 GMT
Raw View
In article <XnaglFEVPF+6EwQj@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>So then adding things like a GUI library and a communications library
>>would be possible:
>
>Yes, but we need to be convinced that it can be done well in a manner
>that is portable and useful.

On the more modest GUI level, I think one might add features for the kind
of graphics console window that most use today anyway (at least on
personal computers and up): One can then work with it as a normal console,
but one can also select and enter text anywhere, and the select it and
send it to the program, with the response typically on the next line. Plus
provisions for styled text, and the ability to have more than one window.

I experimented with this style a few years ago, it could improve the
interface of simple console programs a lot.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Dima Volodin <dvv@dvv.org>
Date: Wed, 9 May 2001 12:18:35 GMT
Raw View
Nick Thurn wrote:
>
> No barrier construct for multi-threading:
>         - no way to make double checked locking work portably

Why should it be portable?

>         - no way to ensure lock occurs before data access portably

POSIX threads is a pretty portable thing, and while a C++ variant of POSIX would
be nice to have, I don't think it should be a part of C++ per se.

> The simplification Mark speaks of is needed. It should be possible
> to use the commonly needed subset of the language with efficient
> compilation and meaningful error reporting. If this requires
> a martian savant to implement the compiler then the language
> should be changed so a lowly 21st century human can actually
> do it.

Just come up with a different name for the language you want (too bad that good
names like "Java" or "C#" have been taken already). Calling this other language
"C++" won't fix anything, but mess the things up beyond any repair.

> Nick

Dima

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Wed, 9 May 2001 12:17:27 GMT
Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote (abridged):
> > Allow enum members to be qualified by the name of the enum they
> > belong to.
>
> I think you are really asking that enums have a scope. Actually I would
> like something more, I would like to see enums as full fledged types
> with a scope in which member functions can be placed. Among other
> things that would allow me to provide a specialised operator= for
> enums.

Why do you need operator=() for enums?

With most functions, they can be added outside the enum's own scope:

    enum Align { Left, Center, Right, End };

    Align &operator++( Align &e ) {
        return e = Align(e+1);
    }

With classes some functions have to be member functions, but that's
because classes have a rich private structure. Enums don't have much
hidden structure; I'm not sure why you would want to specialise
operator=() for them.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Wed, 9 May 2001 12:19:42 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote in message
news:3AF88C33.6CED0A0B@acm.org...
>I see that Francis Glassborow has mentioned an idea of promoting
>the "enum" concept to allow more class-like behaviour.

I would like to be able to define one enum as a subset of
another:

  enum Colors { Red, Orange, Blue, Yellow };
  enum PrimaryColors: Colors { Red, Blue, Yellow };
  enum Reddish: Colors { Red, Orange };

The values would be the same size and conversion would be
zero cost.  Assignment of a value of "wider" type to an
lvalue of "narrower" type would require a cast (kind of
like numeric_cast).




---
[ 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: xnews.public.home@bogus.rtij.nl (Martijn Lievaart)
Date: Wed, 9 May 2001 12:20:43 GMT
Raw View
nickt@kipling.aus.deuba.com (Nick Thurn) dared to utter in
news:9da824$ah1$1@kilmer.bain.oz.au:

> Mark Blewett wrote:
>>
>> What C++ needs now is simplification, consolidation and
>> standardization (not it terms of ANSI, but in terms of the language),
>> possibily with the introduction of a mininimal set of new features.
>>
> Agree.

I don't disagree with many of the things you said but:

>
> One thing the standards process did that was wrong was
> concentrate too much on invention. In some cases this was
> gratuitous:
>      - templatized streams
>      - templatized string
>

Gratuitous? A life saver for anyone working with Unicode. I know many
native English speakers don't care to much beyond ASCII, but for most the
rest of the world all those at-most-8-bit character codes are a real-life
headache. These templatizations are a must for working with 16 or 32 bit
character codes.

I'm not saying that the implementations are perfect (although I think them
pretty good), but gratuitous is plain wrong for many, many users of the
language.

HTH,
Martijn Lievaart

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 9 May 2001 12:20:15 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote in message
news:3AF889E2.1964FAFF@acm.org...
> Nicola Musatti wrote:
> >
> > Robert FISHER wrote:
> > [...]
> > > How about being able to place some restrictions on a class that are
> > > enforced by the compiler. Non-derivable classes. Classes that can't be
> > > placed on the stack/heap. Etc. Sure, there are some idioms that allow
> > > some of these things to be done within the existing language, but they
> > > are often verbose, inelegant, or both. (I want to say what I mean,
> > > rather than say something that coincidentally has the side effect of
> > > what I mean.)
> >
> > Along the same lines, I'd like Java's "final" to be added, and maybe an
> > explicit "abstract" would be appropriate too.
>
> I could live with those.  The Java restriction that a class can't
> be both final and abstract might make sense in C++ too, as we can
> have free functions.  In Java it's conventional to use classes to
> simulate free functions, but it's explicitly not legal to declare
> them abstract (though they should not be instantiated) and final
> (though they're not made for inheritance).
>

Agreed this would be good

> The current conventional hack to make a class nonderivable (as a
> friend of a dummy private virtual base class) is ugly and cannot
> be templated.

Yes it can:

template<typename T> class Final;

template<typename T> class AttemptToDeriveFromFinalClass
{
private:
     AttemptToDeriveFromFinalClass(){}
     AttemptToDeriveFromFinalClass(const AttemptToDeriveFromFinalClass&){}
     friend T;
     friend class Final<T>;
};

 template<typename T> class Final:
    virtual AttemptToDeriveFromFinalClass<T>
{
private:
    Final() {}
    Final(const Final&){}
    friend T;
};

class SomeClass: Final<SomeClass>{}; // declare class 'final'
class IllegalDerivedClass: SomeClass{};

IllegalDerivedClass idc; // ERROR

The use of 'AttemptToDeriveFromFinalClass' as the class name hopefully gives
a better hint in the error message, which is usually something about access
to private constructor of virtual base.

> The convention of using a protected constructor
> to indicate that a class is abstract is no defense against derived
> classes; a pure virtual destructor can sometimes help, but just
> being able to use an explicit language feature would be nice.

Agreed

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 9 May 2001 12:22:04 GMT
Raw View
In article <K3EnBeEsUF+6Ewyr@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>... or even better: allow binary (and why not unary?) functions calls using
>>operator notation. After all, you can call user defined operators using both
>>funciton and operator notation. Why not vice versa?
>
>Interesting idea. AFAICS this is just syntactic sugar. That does not
>make it a bad thing in itself. Can you work up a paper showing how such
>a facility would be useful in at least two problem domains by allowing
>the domain expert to write code that was more natural to domain experts.
>
>Actually with it, we could add swap as an operator.

There are such mechanisms in Haskell <http://haskell.org>:

Somehow, operators must be declared in order to indicate precedence and
associativity. If functions have unusual name (according to the specs of
the language), they must be include in quotes of some kind, for example
`name'. Haskell has 10 precedence levels, Prolog 1000.

In a C++ version, one might write (taking an examples from the Hugs Prelude.hs):

T operator+(const& T, const& T) infixl 7; // Left infix operator of precedence 7
T operator quot(const& T, const& T) infixl 7;

or

T operator `quot'(const& T, const& T) infixl 7;

Then use these names as normal as left infix operators of precedence 7.

This helps a lot if one should be able to write code with formulas looking
normal.

As for myself, I have given up on C++ in this respect, so I use Flex and
Bison to make my own parsers, so I do not directly need it, but I still
would have appreciated such a feature.

One example I arrived at a few days ago is that I made some C++ classes
for computed Grobner bases on multivariate polynomials. Then it turns out
that there is no good operator to use for writing exponents: The "^" has
the wrong precedence, so I did not dare using it. And writing polynomials
as
  // F = { g1 = x^2 z - y^2, g2 = y z^2 + z, g3 = y - z }
  polynomial g1, g2, g3;
  g1 = x*x*z - y*y;
  g2 = y*z*z + z;
  g3 = y - z;
is rather cumbersome.

So I think that could help a lot.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 9 May 2001 12:36:47 GMT
Raw View
Anthony Williams wrote:
>
> "James Dennett" <jdennett@acm.org> wrote in message
> news:3AF889E2.1964FAFF@acm.org...
> >
> > [ ... snip ... ]
> >
> > The current conventional hack to make a class nonderivable (as a
> > friend of a dummy private virtual base class) is ugly and cannot
> > be templated.
>
> Yes it can:
>
> template<typename T> class Final;
>
> template<typename T> class AttemptToDeriveFromFinalClass
> {
> private:
>      AttemptToDeriveFromFinalClass(){}
>      AttemptToDeriveFromFinalClass(const AttemptToDeriveFromFinalClass&){}
>      friend T;
>      friend class Final<T>;

That friend declaration is the problem; I believe that the
Standard makes it illegal to declare as a friend a class whose
name depends on a template parameter, and that is exactly what
is needed here.  The rationale of that rule is not known to me.

-- James Dennett

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Wed, 9 May 2001 16:36:34 GMT
Raw View
In article <9da824$ah1$1@kilmer.bain.oz.au>,
nickt@kipling.aus.deuba.com says...
> The simplification Mark speaks of is needed. It should be possible
> to use the commonly needed subset of the language with efficient
> compilation and meaningful error reporting. If this requires
> a martian savant to implement the compiler then the language
> should be changed so a lowly 21st century human can actually
> do it.

I agree with this. I think that the language needs to
be slowly changed so that it is more internally
consistent with fewer exceptions. Things like making
it possible for user defined classes to behave
identically with primitive types. Things like only
recognizing (at least some) keywords where they are
allowed. The latter would certainly reduce keyword
pressure. I don't think its necessary (or possible) to
go as far as PL/1 did, but consider "virtual". It can
only occur in a very limited place, and can never
occur where a variable name is expected. Why not
change the grammar so that "virtual" is only
recognized where it is legal and allow its use as an
identifier elsewhere?

I also think that the language and the library should
be clearly separated. While there has been some
excellent work on the library, it basically evolved
from the C library with stl and iostreams tacked on. I
rarely use any part of the library outside of very
primitive things because basically the library is not
well structured conceptually nor is it necessarily
very efficient. While STL is much better, there is
still way to much ad-hoc in the library.

On the other hand, the language is good, but should be
clarified. Where the library implicitly requires
compiler support, that support should be made explicit
so that replacement libraries can be built which are
entirely independent.

C++ is a great language, and I think the best choice
out there for all around programming. It's what I use
whenever I have the choice. But, the more I use it,
the more the rough edges annoy.

A compiler writer should never have to parse
arbitrarily far ahead to determine if a statement is a
declaration or an executable statement. If primitive
types were stripped down to a single type the grammar
and rules should be clear and concise (acknowledging
that "concise" doesn't necessarily mean "small" <g>).

While, I don't happen to think that LR1 or LL1 parsing
is everything, certainly a fairly reasonable recursive
descent parser should be able to parse the language.

This is not just a rant about the language. The
parsing problem has hindered the development of
language tools because most people and companies that
develop a tool simply don't have the time to actually
parse the language. There are no effective shortcuts
and everybody suffers. I have tried tool after tool
and every single one of them has barfed on my source
code -- if for no other reason than they cannot handle
the preprocessor.

Perhaps the development of a grammar which includes
the preprocessor as a single grammar would help -- but
only if it were understandable and could be
implemented by mortals.

I think a lot of language design ideas have foundered
on this shoal as well because unless you really want
to get into the internals of a really large program
(such as GNU C++) which is not a trivial task, it is
impractical to build a compiler to test language
design ideas. This wasn't true for C, parsers for C
and its variants abound. There is even one in most
programming editors.

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 9 May 2001 16:36:23 GMT
Raw View
Dave Harris wrote:
>
> Override.
>
> A new keyword, used in place of "virtual", which declares an intent to
> override. It is an error to declare a member function with "override" if
> it does not, in fact, override some base class member. Eg:
>
>     class Base {
>     public:
>         virtual void func1( int x );
>         virtual void func2( long x );
>     };
>
>     class Derived: public Base {
>     public:
>         override void func1( int x ); // OK.
>         override void func1( short x ); // Error!
>         void func2( long x );
>     }

This is useful to catch errors such as

class base {
public:
  virtual void func1( int x );
};

class derived: public base {
public:
  override void fumc1( int x );
};

This should give an error as the typo "fumc1" means that
override is wrong.  I've found errors of this type in real
code, more typically caused by inconsistent capitalization
or spelling errors.

-- James Dennett

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 9 May 2001 16:37:04 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:p2$$x4DAOF+6Ew38@ntlworld.com...
> In article <3AF80135.F84E9A0C@divalsim.it>, Nicola Musatti
> <objectway@divalsim.it> writes
> >Another good thing would be having the compiler synthesize an empty body
> >for virtual pure destructors.
>
> Well Bjarne went further in suggesting that we should not need these at
> all. Any class with a virtual member would have a virtual default dtor
> if none was declared by the class author.

But you use a pure virtual destructor where you wish to make the base class
abstract by having at least one pure virtual function, but there is no other
candidate virtual function that you want overridden in all cases. In this
situation, you make the destructor pure virtual as every class has a
destructor, however you may wish for an empty destructor which you then have
to write explicitly outside the class definition.

The problem with having the compiler synthesize an empty body for such
destructors is how to tell whether there is a destructor for the class, just
defined in another translation unit.

What would be good would be to allow bodies for pure virtual functions to be
provided in the class definition, in which case writing

class MyClass{
virtual ~MyClass()=0{}
};

is only one more character than

class MyClass{
virtual ~MyClass()=0;
};

and is clearly indicates that the destructor is empty, without having to
look for the definition elsewhere.

I also think that a proper keyword (pure?) would be better than the current
'=0' syntax for pure virtual functions.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 9 May 2001 16:37:50 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:OnHm12EhaF+6EwzR@ntlworld.com...
> In article <memo.20010508022024.35939F@brangdon.madasafish.com>, Dave
> Harris <brangdon@cix.co.uk> writes
> >Allow enum members to be qualified by the name of the enum they belong
> >to. Eg:
>
> I think you are really asking that enums have a scope. Actually I would
> like something more, I would like to see enums as full fledged types
> with a scope in which member functions can be placed. Among other things
> that would allow me to provide a specialised operator= for enums.

How about extending classes to permit declaration of class values akin to
the declaration of enum values:

class Enum
{
Enum(int i); // Must have a constructor that takes an integral type (the
'underlying type' of the 'enum')

value x; // static Enum x(0);
value y; // static Enum y(1);
value z=23; // static Enum z(23);
value a; // static Enum a(24);

value b,c,d=5,e; // static Enum b(25),c(26),d(5),e(6);
value f(9); // alternative syntax
};

These values (x,y,z,a) are automatically public, and are accessible in the
enclosing namespace as if by a using declaration:

using Enum::x;
using Enum::y;
using Enum::z;
// etc

Enum myVal=x; // OK, x is public and no scope specifier needed
Enum myVal2(999); // error, private constructor
Enum myVal3=Enum::y; // Explicit scope specifier still permitted

The "value" syntax could even be extended to permit initialization with any
value for which there is a constructor, though obviously the implicit
increment wouldn't work for that case.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: "Mirek Fidler" <cxl@iol.cz>
Date: Wed, 9 May 2001 16:37:43 GMT
Raw View
> Override.
>
> A new keyword, used in place of "virtual", which declares an intent to
> override. It is an error to declare a member function with "override" if
> it does not, in fact, override some base class member. Eg:
>
>     class Base {
>     public:
>         virtual void func1( int x );
>         virtual void func2( long x );
>     };
>
>     class Derived: public Base {
>     public:
>         override void func1( int x ); // OK.
>         override void func1( short x ); // Error!
>         void func2( long x );
>     }
>
> Implementations are encouraged to warn about overriding functions which
> don't use "override", such as func2().

    Yes, this was number two in my wishlist ;-) I would even suggest just
the same syntax.

Mirek




---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Wed, 9 May 2001 16:38:09 GMT
Raw View

Francis Glassborow wrote:
>
> In article <3AF80135.F84E9A0C@divalsim.it>, Nicola Musatti
> <objectway@divalsim.it> writes
> >Another good thing would be having the compiler synthesize an empty body
> >for virtual pure destructors.
>
> Well Bjarne went further in suggesting that we should not need these at
> all. Any class with a virtual member would have a virtual default dtor
> if none was declared by the class author.

The problem is that currently if you declare your destructor, it is not
synthesised. Normally this is what you want because you declare it to
implement it. However when you declare your destructor pure virtual you
are forced to provide a body you're often not interested in and to write
it outside the class definition.

Best regards,
Nicola Musatti

---
[ 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: xnews.public.home@bogus.rtij.nl (Martijn Lievaart)
Date: Wed, 9 May 2001 16:38:01 GMT
Raw View
"Greg Brewer" <nospam.greg@brewer.net> dared to utter in
news:9d9p6h$2g30$1@news.hal-pc.org:

[ Alternative way to initialise class members. ]

>
> Ok, that's my glass house.  Start throwing.
> Greg Brewer
>

Having been in the same situation many times, this sounds like a /very/
sound suggestion. Some details should be worked out (f.i. is initialisation
by function call allowed?) but in general I think this is a big win without
any drawbacks I can think of.

The biggest win is that this way the maintenance burden is eased
considerably when there are a lot of members and more than one constructor.
Sure it is possible to encapsulate those members in a seperate class as you
have shown, but there are some drawbacks to that as well.

Using encapsulation, you have to forward any member functions if the type
encapsulated is of class type. This is not possible without an additional
maintenance burden, if the encapsulated type changes, you have to update
these initialisation classes. Not good for frameworks. Also, this technique
does not work well if the type encapsulated is a template parameter.

So one could use public inheritance, this gets around the afore mentioned
problem. However this does not work if the encapsulated class declared the
class you were originally writing as a friend. To be fair, ordinairy
encapsulation works better than outlined above in that situation, as the
classes have to be aware of each other so modifiying both if you modify one
is not prohibitive. OTOH, this still does create havoc with templates as
one cannot derive from a built-in or an enum.

So yes, I think your proposal is a big win. Anyone see any drawbacks?

Martijn Lievaart

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 9 May 2001 16:38:29 GMT
Raw View
In article <9d986b$e2v$1@cam-news1.cambridge.arm.com>, "Al Grant"
<tnarga@arm.REVERSE-NAME.com> wrote:
>> The underlying principle I see is that such features must be sufficiently
>> stable in the sense that if a platform supports say GUI, then it must be
>> fairly easy to implement the C++ standard GUI library.
>
>There's nothing to stop a group like the X consortium
>publishing a C++ GUI library and people adopting it as a
>de facto standard.  Why do you think the language standards
>committee should spend time on this?  There are dozens if
>not hundreds of core language issues that are more
>deserving of the standards commitee's time.

Your argument could be applied to any language feature, so it is of little
use for determining what should and not should be added:

There's nothing to stop a group like the X consortium publishing a C++
language of their own and people adopting it as a de facto standard. Why
do you think the language standards committee should spend time on this?
They are in fact much happier doing sun-tanning on the Hawaii islands. :-)

It appears to be a fact that those things are already to be considered.

>GUI libraries go out of date horribly quickly too.
>If it had been standardised 20 years ago it would have
>had all sorts of features for pen plotters, light pens,
>sprites etc.  Who knows what will be the GUI idioms of
>20 years' time?

With GUI, as with any other feature, after a while there emerges a core
that is pretty much a de facto standard to humans, even though it may not
be a standard in the computer language sense.

So one must isolate such a core that sufficiently stable in the sense that
it will not change much in the future. It will then be relatively easy to
implement on the compilers that host on platforms that already have a GUI.

The reason one is doing it is that there are people writing programs for
several different platforms, and any such prudent addition to a language
like C++ will help a lot.

With respect to GUI, this might be a tricky task, so then one must turn
down the expectations. But the general underlying principle is the same.

>Incidentally it is not the case that most programmable
>devices have GUIs.

The idea is to add a feature that should run on all compilers, but on
those compilers that host on platforms where GUI's already available.

>  And I don't think it ever has been.
>C++ is not like Java, it is a good choice right across
>the application space from embedded up to large-scale
>but could support those extremes better.

If the GUI that Java supplies can be viewed as a standard on the platforms
where GUI is already available, then one could add that to C++. But I
figure it isn't, so one then has to settle for something else.

>  IMHO the way
>to compete with Fortran is not with template libraries
>like Blitz++ but with language features which enable
>optimisations and standardise the floating-point
>environment.  Even C99 now does that better than C++.

I think that C++ should be a general purpose language for those that want
to get things done. Optimizations may be a part of that, but in general,
one should first simply write a working program, and then proceed towards
optimizations, more advanced libraries, etc.

Additions to C++ can greatly simplify that procedure to the programmers.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 9 May 2001 16:38:35 GMT
Raw View
In article <p2$$x4DAOF+6Ew38@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>>Another good thing would be having the compiler synthesize an empty body
>>for virtual pure destructors.
>
>Well Bjarne went further in suggesting that we should not need these at
>all. Any class with a virtual member would have a virtual default dtor
>if none was declared by the class author.

I noticed this in the original post, and I think it is a good suggestion,
because it is so easy to forget making the destructor virtual for
otherwise polymorphic classes, and there appears to be no good reason for
ever making a polymorphic class having a non-virtual destructor.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Jens Kilian <Jens_Kilian@agilent.com>
Date: Wed, 9 May 2001 16:39:01 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> writes:
> In article <mjXJ6.18$v86.417@burlma1-snr2>, Barry Margolin
> <barmar@genuity.net> writes
> >BTW, when defining an operator, you need to specify things like precedence
> >and associativity, unless you're willing for all user-defined operators to
> >group the same.
>
> Why not? Make it left to right, and make a X b equivalent to writing
> operator X(a,b); Not that hard to parse.

Without some more restrictions, user-defined operators *are* really hard
to parse.  Prolog has them (allowing you to specify fixity[1], associativity
and precedence); before the ISO Prolog standard[2] came along, no two Prolog
implementations had compatible parsers.

Bye,
 Jens.

[1] I.e., infix/prefix/postfix.
[2] The standard severely limits the allowable combinations of properties
    that can be assigned to operators with the same name, and states the
    intended interpretation for various ambiguous cases, in order to get
    a grammar that can be parsed deterministically.
--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Wed, 9 May 2001 16:39:26 GMT
Raw View
On Tue,  8 May 2001 18:52:33 GMT, Niklas Matthies <news/comp.std.c++@nmhq=
.net> wrote:
> "Virtual pointers" (and references).
[=B7=B7=B7]
>    +  Built-in types could be allowed to be derived from, and be used i=
n
>       a polymorphic fashion. The standard could even place the built-in
>       types in some class hierarchy and thus allow them to be used
>       polymorphically even without user-derived classes being involved.
>       E.g. (using a "virtual reference"):
>=20
>          Integer virtual &ivref;          // Integer is supposed to be =
a
>          int i; long l;                   // base for both int and long
>          if (some_condition()) ivref =3D i;
>                           else ivref =3D l;
>          ...
>          ivref =3D 5;                       // does the "right thing"

Oops, there's a blatant mistake in this example: The two assignements
within the if statement are supposed to initialize the reference, but of
course this wouldn't work that way. The reason for this mistake is that
I first wrote this example with a pointer instead of a reference,
because I thought that with a pointer one would have to write the final
assignment as

   ivptr->operator=3D(5);

since

   *ivptr =3D 5;

wouldn't work as wanted, on the assumption that the type of `*ivptr'
would be `Integer &' and lose the vtable information.
But actually it would quite make sense to let `*ivptr' have the type
`Integer virtual &', which lets the assignement behave as intended.

However, there's still the unfortunate situation that something like

   Integer virtual &ivref =3D cond() ? i : l;

is not possible. What one would like this to do is
  =20
   Integer virtual &ivref =3D *(cond() ? (Integer virtual *) &i
                                     : (Integer virtual *) &l);

But possibly this won't be a very common need.

-- Niklas Matthies

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 9 May 2001 16:39:32 GMT
Raw View
In article <3AF88C33.6CED0A0B@acm.org>, James Dennett <jdennett@acm.org>
writes
>I see that Francis Glassborow has mentioned an idea of promoting
>the "enum" concept to allow more class-like behaviour.  It might
>be worth making FG-enums distinct from the existing enums, and
>allowing forward declarations for them.  A better name that
>"FG-enum" might also be appropriate.


I have been thinking further in this area. The original request to allow
adding scope information to disambiguate enumeration constants can be
dealt with via namespaces:

namespace X {
  enum X {begin, end};
}

allows us to write X::begin etc. as well as using a using declaration to
restore normal behaviour. So perhaps something such as:

namespace enum X {begin, end};

might be introduced to allow optional scoping without providing a full-
fledged namespace that people could abuse.

Now my other concern is really about how operators on enums effectively
convert the answer to an integer type (which depends on the underlying
type of the enum) which is fine until you want to use an assignment.
This may get worse with an explicit requirement that compound
assignments can only be overloaded in class scope.

A possibility (haven't thought much about it yet) is to make all
operations on pure enums return an enum of the same type rather than
default to conversion to an integer type. I think this would mean, among
other things that:

enum X {x1, x2, x3};
enum Y {y1, y2, y3};

int main (){
X x=x1;
Y y=y1;

int i = x+y;
// ERROR, no default operator+(X, Y)
x++; // fine
x += x2; // fine
x = x + x2; // fine
// note that currently there is no way to write this without
// providing an operator+ for X and you have to provide all
// the operators you intend to use because you cannot overload
// the assignment operator

...
}

That might have some advantages and takes enumerations further along the
path to being full-fledged types.
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Wed, 9 May 2001 16:39:21 GMT
Raw View
On Wed,  9 May 2001 12:22:04 GMT, Hans Aberg <remove.haberg@matematik.su.=
se> wrote:
> In article <K3EnBeEsUF+6Ewyr@ntlworld.com>, Francis Glassborow
> <francisG@robinton.demon.co.uk> wrote:
> >>... or even better: allow binary (and why not unary?) functions
> >>calls using operator notation. After all, you can call user defined
> >>operators using both funciton and operator notation. Why not vice
> >>versa?
[=B7=B7=B7]
> There are such mechanisms in Haskell <http://haskell.org>:
>=20
> Somehow, operators must be declared in order to indicate precedence and
> associativity. If functions have unusual name (according to the specs o=
f
> the language), they must be include in quotes of some kind, for example
> `name'. Haskell has 10 precedence levels, Prolog 1000.
>=20
> In a C++ version, one might write (taking an examples from the Hugs
> Prelude.hs):
>=20
> T operator+(const& T, const& T) infixl 7; // Left infix operator of pre=
cedence 7
> T operator quot(const& T, const& T) infixl 7;
>=20
> or
>=20
> T operator `quot'(const& T, const& T) infixl 7;
>=20
> Then use these names as normal as left infix operators of precedence 7.

Wouldn't the better approach be to not use numerical precedence levels
of fixed range and granularity, but instead define the precedence of
some operator relative to the precedence of already-declared operators?
I.e. one could specify that opX should have the same precedence as opY,
or specify that it should have higher precedence than opA but lower
precedence than opB. The compiler would infer a partial ordering on
operator precedence from this (after having checked that there are no
cycles), and would complete it to a total ordering (in some
implementation-specific way, so that one can only rely on the precedence
relations that were specified by the operator declarations).

-- Niklas Matthies

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 9 May 2001 16:39:38 GMT
Raw View
In article <memo.20010509061258.57395A@brangdon.madasafish.com>, Dave
Harris <brangdon@cix.co.uk> writes
>Why do you need operator=() for enums?
>
>With most functions, they can be added outside the enum's own scope:
>
>    enum Align { Left, Center, Right, End };
>
>    Align &operator++( Align &e ) {
>        return e = Align(e+1);

exactly because of that cast, requiring a cast to do something natural
is adding potential for errors being hidden by the cast.

I have just posted an alternative set of thoughts on this subject.

>    }
>
>With classes some functions have to be member functions, but that's
>because classes have a rich private structure. Enums don't have much
>hidden structure; I'm not sure why you would want to specialise
>operator=() for them.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Alexander Terekhov <terekhov@web.de>
Date: Wed, 9 May 2001 16:39:44 GMT
Raw View
Nick Thurn wrote:

[...]
> No barrier construct for multi-threading:
>        - no way to make double checked locking work portably

there is a way to make it work portably; using thread locals (tsd).
here is a compact example in Java (in C++ you would need to have
a "portable" class similar to ThreadLocal or just stick to C/POSIX
pthreads for tsd):

  class Singleton {
    private static Singleton theInstance;

    private static final ThreadLocal perThreadInstance =
      new ThreadLocal() {
          public Object initialValue() { return createInstance(); }
        };

    public static Singleton getInstance() {
      return (Singleton)perThreadInstance.get();
    }

    private static synchronized Singleton createInstance() {
      if (theInstance == null)
        theInstance = new Singleton();
      return theInstance;
    }

  }

however, I would really prefer to write:

Singleton& Singleton::getInstance()
{
   static synch Singleton theSingleton; // synchronized local static
   return theSingleton;
}

so that via "static synch" the language implementation would provide
the correct and most effective solution for lazy initialization in
MT environment on each particular platform; e.g. DCL with memory
barriers or tsd (who knows which is faster) for multiprocessors with
weak memory models, "classic" DCL for all uniprocessors and
multiprocessors
with strong memory model or something completely different; platform
specific.

that would also ensure zero overhead ("synch" should be just
ignored by compiler) if my code/lib would be compiled for running
in ST environment only (without -pthread option or similar). btw, that
is
the only reason why "static synch" locals would do better than already
portable pthread_once - I just do not like to maintain two versions;
one with pthread_once for MT programs and another with static locals
for ST programs.

regards,
alexander.

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Wed, 9 May 2001 17:35:29 GMT
Raw View
"Hans Aberg" <remove.haberg@matematik.su.se> wrote in message
news:remove.haberg-0905011222010001@du131-226.ppp.su-anst.tninet.se...
> I wrote:
> >There's nothing to stop a group like the X consortium
> >publishing a C++ GUI library and people adopting it as a
> >de facto standard.  Why do you think the language standards
> >committee should spend time on this?  There are dozens if
> >not hundreds of core language issues that are more
> >deserving of the standards commitee's time.
>
> Your argument could be applied to any language feature

No, because you can't buy a language feature and plug it into
your compiler, or mix and match language features from different
vendors.  You _can_ do this with libraries.

> There's nothing to stop a group like the X consortium publishing a C++
> language of their own and people adopting it as a de facto standard. Why
> do you think the language standards committee should spend time on this?

Because language standardisation is what a language standards
committee does.  Not trying to write libraries for every
type of application they consider to be popular.

> With GUI, as with any other feature, after a while there emerges a core
> that is pretty much a de facto standard to humans, even though it may not
> be a standard in the computer language sense.

That's what the OSI VT people thought and they were wrong.

> The reason one is doing it is that there are people writing programs for
> several different platforms, and any such prudent addition to a language
> like C++ will help a lot.

So do it.  Define a standard C++ GUI library and present it
to the world.  Why does it impact on the C++ standards
process?  If you are saying that C++ lacks _language_ features
that are needed for your GUI library then that is a different
thing altogether.  Propose those language features.
Programmers in other areas might find them useful too.



---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Wed, 9 May 2001 17:42:58 GMT
Raw View
That reminds me.  Here's a minor change I would like

class A
{
public:
   virtual void Run(void);
   static void Do(void);
};

////////////  .cpp file ///////////////

virtual void A::Run(void)
{
}
static void A::Do(void)
{
}
/////////////////////////////////////////
putting virtual & static are currently illegal.  But why?  Although they
don't do anything, while stepping through the code with a debugger, I
frequently would find it useful to know that the function is virtual or
static.  I know I could -- and do -- use "/*virtual*/" and "/*static*/" when
I remember.  The problem is that I create the prototype in the class
definition first and copy the declaration down to the code file when time to
code the function.  All I have to do is add the "classname::" to the front
of the function.  But, if its a virtual or static, I have more editting to
do or I simply don't copy that word.

I'm not suggesting that static or virtual actually do anything or be
required; just that they be allowed if they match the declaration.

Greg Brewer


---
[ 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: "Andrew R. Thomas-Cramer" <artc@prism-cs.com>
Date: Wed, 9 May 2001 20:15:50 GMT
Raw View
Yet another wishlist:

* finally blocks
    I spent several hours yesterday, in a particular block of code, trying
either to find a way to use resource-acquisition-is-initialization for an
ad-hoc cleanup in a way that would not result in obfuscated code, or a way
to avoid RAII. The finally block would have been clear and simple, a single
line of code. In the end, for simplicity, I wrote redundant code -- which I
despise -- one line in a catch(...), and a mirror of it below the try/catch.
  I don't need ad hoc cleanup very often, but when I do, defining ad hoc
classes inside a function is messy and less readable than a simple finally
block.

* instanceof
  The syntactic salt of the dynamic_cast<> test is annoying. I don't need
this very often, but when I do, I'd appreciate not being whacked over the
head with salt.

* switch on any type supporting operator=
  Perhaps this is merely syntatic sugar, but I'd find it more convenient,
particularly when switching on strings. I don't do this very often, but when
I do, I'd appreciate not being forced into redundancy.


---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Wed, 9 May 2001 20:45:28 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote in message
news:3AF9373A.36804B68@acm.org...
> Anthony Williams wrote:
> >
> > "James Dennett" <jdennett@acm.org> wrote in message
> > news:3AF889E2.1964FAFF@acm.org...
> > >
> > > [ ... snip ... ]
> > >
> > > The current conventional hack to make a class nonderivable (as a
> > > friend of a dummy private virtual base class) is ugly and cannot
> > > be templated.
> >
> > Yes it can:
> >
> > template<typename T> class Final;
> >
> > template<typename T> class AttemptToDeriveFromFinalClass
> > {
> > private:
> >      AttemptToDeriveFromFinalClass(){}
> >      AttemptToDeriveFromFinalClass(const
AttemptToDeriveFromFinalClass&){}
> >      friend T;
> >      friend class Final<T>;
>
> That friend declaration is the problem; I believe that the
> Standard makes it illegal to declare as a friend a class whose
> name depends on a template parameter, and that is exactly what
> is needed here.  The rationale of that rule is not known to me.

You are right. MSVC (which is what I use) compiles the code OK (what a
surprise, MSVC template support being non-standard....), but Comeau online
doesn't.

It is the "friend T" which is ill formed. It should be "friend class T" as
it must be an elaborated type specifier, but that is not permitted to
evaluate to a typedef name or a template parameter (7.1.5.3p2) I don't
understand the rationale for either, both would have uses.

Since the point of this thread is to provide features we would like, here's
one for the list:

* permit "friend class T" in class templates, where T is a template
parameter.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 9 May 2001 20:46:00 GMT
Raw View
In article <9da824$ah1$1@kilmer.bain.oz.au>, Nick Thurn
<nickt@kipling.aus.deuba.com> writes
>One thing the standards process did that was wrong was
>concentrate too much on invention.

I get tired of hearing this, when mostly the work on the core of the
language was rejecting demands for extensions and invention (note that
templates and exceptions were in the original specification documents
for standardisation)

>In some cases this was
>gratuitous:
>       - templatized streams
>       - templatized string

These are library issues, an area in which mistakes are often made, but
one that can be corrected by substituting alternatives (something that
cannot so easily be done to the core of the language)

>
>Other areas were rendered useless for their main purpose:
>       - type_info::name for persistence
>
>Other common usages were simply ignored as "bad practice"
>despite these containing the bulk of actual users:
>       - c++ ala C++/Views, MFC ... basically any GUI tool kit
>
>No barrier construct for multi-threading:
>       - no way to make double checked locking work portably
>       - no way to ensure lock occurs before data access portably

Now it seems you wanted the Committee to be inventive (often the case
that people want no inventions other than those they want:)

>
>Binder dependent STL with incomplete binder support.

Easy to fix.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 9 May 2001 20:49:20 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Wed,  9 May 2001 12:22:04 GMT, Hans Aberg <remove.haberg@matematik.s=
u.se> wrote:
> > In article <K3EnBeEsUF+6Ewyr@ntlworld.com>, Francis Glassborow
> > <francisG@robinton.demon.co.uk> wrote:
> > >>... or even better: allow binary (and why not unary?) functions
> > >>calls using operator notation. After all, you can call user defined
> > >>operators using both funciton and operator notation. Why not vice
> > >>versa?
> [=B7=B7=B7]
> > There are such mechanisms in Haskell <http://haskell.org>:
> >
> > Somehow, operators must be declared in order to indicate precedence a=
nd
> > associativity. If functions have unusual name (according to the specs=
 of
> > the language), they must be include in quotes of some kind, for examp=
le
> > `name'. Haskell has 10 precedence levels, Prolog 1000.
> >
> > In a C++ version, one might write (taking an examples from the Hugs
> > Prelude.hs):
> >
> > T operator+(const& T, const& T) infixl 7; // Left infix operator of p=
recedence 7
> > T operator quot(const& T, const& T) infixl 7;
> >
> > or
> >
> > T operator `quot'(const& T, const& T) infixl 7;
> >
> > Then use these names as normal as left infix operators of precedence =
7.
>=20
> Wouldn't the better approach be to not use numerical precedence levels
> of fixed range and granularity, but instead define the precedence of
> some operator relative to the precedence of already-declared operators?
> I.e. one could specify that opX should have the same precedence as opY,
> or specify that it should have higher precedence than opA but lower
> precedence than opB. The compiler would infer a partial ordering on
> operator precedence from this (after having checked that there are no
> cycles), and would complete it to a total ordering (in some
> implementation-specific way, so that one can only rely on the precedenc=
e
> relations that were specified by the operator declarations).

IMHO the "relative specification" would be the right choice, because
then you can't get a situation like (exaggerated)

1, 5, 200, 201, 202, 300 ... Hmpf, I'd need an operator between 200 and
201!

Also, you would not have to remember meaningless numbers.

However, I think that the compiler shouldn't complete the order,
but simply give an error message if two operators without
specified order and without explicit parenthesing are used.
Otherwise, a lot of very subtle bugs may go unnoticed because
it works right on the single platform you tried.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Wed, 9 May 2001 20:50:25 GMT
Raw View
Jens Kilian wrote:
>
> Francis Glassborow <francis.glassborow@ntlworld.com> writes:
> > In article <mjXJ6.18$v86.417@burlma1-snr2>, Barry Margolin
> > <barmar@genuity.net> writes
> > >BTW, when defining an operator, you need to specify things like precedence
> > >and associativity, unless you're willing for all user-defined operators to
> > >group the same.
> >
> > Why not? Make it left to right, and make a X b equivalent to writing
> > operator X(a,b); Not that hard to parse.
>
> Without some more restrictions, user-defined operators *are* really hard
> to parse.  Prolog has them (allowing you to specify fixity[1], associativity
> and precedence); before the ISO Prolog standard[2] came along, no two Prolog
> implementations had compatible parsers.
>
> Bye,
>         Jens.
>
> [1] I.e., infix/prefix/postfix.
> [2] The standard severely limits the allowable combinations of properties
>     that can be assigned to operators with the same name, and states the
>     intended interpretation for various ambiguous cases, in order to get
>     a grammar that can be parsed deterministically.

In C++, an operator of one name and "fixity" can only have one
precedence. Why should this be changed for user-defined operators?
Therefore in C++ the problems you mention shouldn't arise.

---
[ 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: James Dennett <jdennett@acm.org>
Date: Mon, 7 May 2001 12:13:32 GMT
Raw View
Ron Natalie wrote:
>
> James Dennett wrote:
> >
> > I'd prefer something like a Standard pragma (though historically
> > pragmas have been a pain) such as
> >
> > #pragram STDC++ always-initialize
>
> Only if it is REQUIRED to be impelemented is this useful.  If it's
> optional, the feature suddenly becomes VERY VERY DANGEROUS.   I suggest
> that if we're going to have compile standardized compile controls that
> they NOT be called PRAGMA.

A possible idea partly stolen from Perl: we could re-use
"using" to turn features on/off within scopes, as in

namespace mystuff {
  using "always-initialize";

  // code in this scope gets default initialization of
  // variables
}

A compiler should be required to issue a diagnostic if
it does not support the facility named by the "using"
statement.  Existing compilers would already do so, as
this isn't currently valid syntax.  Newer compilers would
hopefully produce clearer diagnostics.

-- James Dennett

---
[ 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: xnews.public.home@bogus.rtij.nl (Martijn Lievaart)
Date: Mon, 7 May 2001 13:38:18 GMT
Raw View
remove.haberg@matematik.su.se (Hans Aberg) dared to utter in
news:remove.haberg-0705011147350001@du130-226.ppp.su-anst.tninet.se:

>
> whatever now you would want to call it. (Why not calling the 32-bit
> Unicode type simply uchar).
>

I don't mind breaking a few programs with a new type or keyword, but this
would break more than a few. "uchar" is routinely used as a typedef for
unsigned char. So back to unichar, or even if it contains an underscore
uc_char?

Martijn Lievaart

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 7 May 2001 15:14:57 GMT
Raw View
In article <3AF616E5.B79DA1B@wizard.net>, James Kuyper Jr.
<kuyper@wizard.net> writes
>In C++, there'd be no need to. Just add an initializer:
>={static_cast<Object*>(NULL)}; That takes care of the first element of
>the array, and forces the other elements to be zero-initialized as well.

Why not the simpler
 ={0};

which can be used to initialise arrays of all fundamental types and
pointers.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Peter Dimov <pdimov@MailAndNews.com>
Date: Mon, 7 May 2001 15:15:14 GMT
Raw View
>===== Original Message From "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
>Fri,  4 May 2001 21:24:56 GMT, Peter Dimov <pdimov@MailAndNews.com> pisze:
>
>> std::for_each(vs.begin(), vs.end(), std::cout << _1 << '\n');
>
>This syntax is ambiguous. Does
>    f(g(_1))
>mean
>    lambda(x): f(g(x))
>or
>    f(lambda(x): g(x))

Actually none of them; f(_1) can't be made to work. The syntax that works
(I'm
talking about an actual working implementation) is

bind(f, _1);

--
Peter Dimov
Multi Media Ltd.

---
[ 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: LR <lruss@superlink.net>
Date: Mon, 7 May 2001 16:27:45 GMT
Raw View

Francis Glassborow wrote:

>
> Have no fear, suggestions will be rigorously analysed
> for benefit versus cost but the time for that is a little later. For now
> I would like to see the brain storming rules applied -- anything goes
> and people must not be overtly negative about other peoples suggestions.
> When we have a stack of suggestions, then will be the time to winnow thw
> wheat from the chaff.


"Anything goes"?


Ok, I have a few things that I'd like.  Some of them are suggestions
that others made, some I'm sure that others have made, but I haven't
seen.

Not in any particlular order.

1) A gui library, and maybe also a portable library for character only
screens.  Not everyone has a system with graphics. I doubt that we can
get this, but asking again won't hurt.  Doesn't have to be available in
every implementation. Not every platform has a screen

2) A communications library. Doesn't have to be available in every
implementation.

3) A regular expression library.

4) A library for true decimal types. both fixed and float. Maybe
something that could be used like
 std::decimal<19,2> national_debt("1000000000.00");
or in someparts of the world
 std::decimal<19,2> national_debt("1000000000,00");
so we'd need some nice interaction with locales.

5) I really like the typeof idea I've been reading about here.  I'd also
like something that could resolve polymorphic types at runtime.

6) ... and along those lines,  what are the name and args of the
function or member function that we're in?  At least nice for debugging
purposes.

7) I'm sure that I saw someone mention this, but haven't seen it on the
defect report pages I've been browsing, but I'd really like to be able
to:
 std::string myFileName("x.txt");
 std::ifstream(myFileName);
Maybe it's just my compiler that doesn't support this?

LR.

---
[ 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: Matthew Austern <austern@research.att.com>
Date: Mon, 7 May 2001 17:33:14 GMT
Raw View
"Rene" <rene413@home.com> writes:

> What I don't understand is why it takes 6 years to make a change to a
> programming language!!

It doesn't.  We could make changes every six months, if we thought
that was a good idea.  Most people think it wouldn't be.

---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Mon, 7 May 2001 19:37:55 GMT
Raw View
The main (only?) reason why some people don't want default initialization
are the performance considerations.

I think that (as in almost all other cases) these are somewhat
misconsidered.
Performance considerations are evil. Contemporary compilers are smart
enough to suppress unnesseccary code, including redundant (default)
initializations. E.G.

int x = 0;  // a
int x;  // b
int x = 7;  // c

x = 7;

Do you really believe there is a contemporary compiler that would generate
different code for these? I doubt it. Ten (!) years ago I used a compiler
that
warned me (at compile time) for division by zero in this case:

int a, b;
....
a = b;
...
c = b - a;
....
x = y / c;  // << Warning: division by zero

Default initialization overhead might make difference for arrays,
but arrays DO have default initialization anyway (except for 'auto' arrays.
I really doubt they are widelly used, though).

So, why are we trying to 'save' the compiler from generating code for
something which it will not do anyway? Just to make our lives more
difficult?

Radoslav Getov




"Howard Gardner" <usenet@hgardner.com> wrote in message
news:3AF40516.8020601@hgardner.com...
> Valentin Bonnard wrote:
>
> > Howard Gardner  wrote:
> >
> >> I bet instructors would like to get rid of the whole topic too, for
that matter.
> >
>
> > I want students to initialise variables to the right value,
> > or to assign them the right value before use.
>
> I wonder if you would disagree with any of these statements:
>
> 1) In C++, uninitialized variables are common.
>
> 2) Uninitialized variables often are not discovered until a program is run
on a machine other than the OP's.
> 3) Bugs are much harder to correct in large code bases than they are in
small code bases.
> 4) Code bases tend to grow in time.
> 5) Code is usually run on the OP's machine much earlier than it is run on
other machines
>
> 6) Uninitialized variables often result in bugs that are difficult to
reproduce.
> 7) It is relatively difficult to correct bugs that are difficult to
reproduce.
>
> 8) Bugs that are both difficult to reproduce and hiding in large code
bases can be extremely difficult to correct.
>
> 9) In most circumstances, an uninitialized variable is an error that will
result in a bug.
> 10) It is possible to change the syntax of C++ so that naive variable
declarations result in initialized variables, statements which currently
initialize variables are not affected, and it is possible to create
uninitialized variables when necessary.
>
> Making the kind of change mentioned in statement 10 would save enormous
amounts of time.
>
> I have yet to see anyone attempt to make the case that the miniscule boost
in efficiency resulting from having a naive variable declaration result in
an uninitialized state is worth all of the pain that it brings.
>
> ---
> [ 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                ]
>


---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 7 May 2001 19:36:53 GMT
Raw View
In article <Xns909A9E437C0ADyoudontwannaknow@194.109.133.13>,
xnews.reply.to@rtij.nl wrote:

>remove.haberg@matematik.su.se (Hans Aberg) dared to utter in
>news:remove.haberg-0705011147350001@du130-226.ppp.su-anst.tninet.se:
>> whatever now you would want to call it. (Why not calling the 32-bit
>> Unicode type simply uchar).
...
>I don't mind breaking a few programs with a new type or keyword, but this
>would break more than a few. "uchar" is routinely used as a typedef for
>unsigned char. So back to unichar, or even if it contains an underscore
>uc_char?

It is extremely easy to fix a program that already uses "uchar": Simply
choose another name that does not appear in the program and make a batch
replacement.

If one should choose a name for a type that will be used in almost every
program, it is better choose a good one over worrying about code that can
be easily fixed.

But whatever name is OK with me, as long as it is good.

Another name could be "character", as no-one expects there to be a
replacement of the 32-bit Unicode character for the foreseeable future (as
it is unlikely that one will require the use of the full 2 G characters).

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Mon, 7 May 2001 19:36:29 GMT
Raw View

LR wrote:

>
> 1) A gui library, and maybe also a portable library for character only
> screens.  Not everyone has a system with graphics. I doubt that we can
> get this, but asking again won't hurt.  Doesn't have to be available in
> every implementation. Not every platform has a screen
>
> 2) A communications library. Doesn't have to be available in every
> implementation.

These are really outside the scope of the language.  It would really
be unworkable to leave large chunks of the core language "optional."
This can easily be handled as additional standards.

>
> 3) A regular expression library.

I'd like to see some of the C library stuff (regex, strtok, etc...)
cleaned up and C++-ized as well.

> 6) ... and along those lines,  what are the name and args of the
> function or member function that we're in?  At least nice for debugging
> purposes.

Some of this is existant in the C99 spec.  Hopefully most of these refinements
will be moved into C++ as well.
>
> 7) I'm sure that I saw someone mention this, but haven't seen it on the
> defect report pages I've been browsing, but I'd really like to be able
> to:
>         std::string myFileName("x.txt");
>         std::ifstream(myFileName);
> Maybe it's just my compiler that doesn't support this?
>

No, C++ character handling is really loopy.  On one hand many important
interfaces still use the char* as pointer to NTMBS, on the otherhand there
are some interfaces (string) that require fixed size characters.   I too
would like to see all this cleaned up.

---
[ 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: "Matt Seitz" <mseitz@yahoo.com>
Date: Mon, 7 May 2001 19:37:17 GMT
Raw View
"Dave Harris" <brangdon@cix.co.uk> wrote in message
news:memo.20010506211715.50265F@brangdon.madasafish.com...
>
> Allow dynamic_cast on integral types. Eg:
>
>     long big = 100000000L;
>     int small = dynamic_cast<int>( big );
>
> This would perform a range-check, and throw an exception if the result
> will not fit in the target type. The analogy is with dynamic_cast<derived
> &)( base & ).
>
> Alternatively, provide a standard library function to do the same thing
> in <limits> - but I think the dynamic_case<> notation is a natural fit,
> and consistency might be useful in templates.

In THE DESIGN AND EVOLUTION OF C++, section 14.3.5.2 ("Implicit Narrowing
Conversions"), Dr. Stroustrup gives an example of a function for performing
this task:

    template<class V, class U> V narrow(U u)
    {
        V v  = u;
        if (v!=u) throw bad_narrowing;
        return v;
    }


---
[ 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: Peter Dimov <pdimov@MailAndNews.com>
Date: Mon, 7 May 2001 21:49:50 GMT
Raw View
>===== Original Message From LR <lruss@superlink.net> =====
>
>Consider this fragment:
>
>class Base {};
>class D1 : public Base {};
>class D2 : public Base {};
>
>Base *pb = new Base;
>Base *pd = somecondition ? new D1 : new D2;
>
>Then what should typeof(pb) and typeof(pd), return? Probably they should
>all return Base*.  But isn't it possible that we might want typeof(pd)
>to give us D1*.  Could we have syntax that might be like *typeof(pd)
>that will yield this info?

Where do I start. :-) typeof(pd) is a type, but you're applying operator* to
it. Perhaps you meant typeof(*pd); but consider that sizeof(*pd) is not
evaluated at runtime, and sizeof(x) == sizeof(typeof(x)) is an important
equality. Also, consider this example:

template<class T> void f();

void g(Base * p)
{
  f<typeof(*p)>();
}

Note that g is not itself a template; how would you compile it?

>Assuming that I want to clone what pd points to, maybe something like:
>typeof(pd) px = new *typeof(pd);

Then you need

Base * px = std::clone(pd);

which is actually quite possible to implement, and has the benefit of
actually
doing what you want. :-)

typeof(pd) px = new typeof(*pd); doesn't clone pd;
typeof(pd) px = new typeof(*pd)(*pd) is closer, but *pd's static type is
Base
&, therefore D1::D1(D1 const &) won't bind to it.

--
Peter Dimov
Multi Media Ltd.

------------------------------------------------------------
 Get your FREE web-based e-mail and newsgroup access at:
                http://MailAndNews.com

 Create a new mailbox, or access your existing IMAP4 or
 POP3 mailbox from anywhere with just a web browser.
------------------------------------------------------------

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 7 May 2001 21:50:02 GMT
Raw View
In article <remove.haberg-0705011147390001@du130-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>However, one can think of supporting debugger tools that can detect the
>use of uninitialized values.

Well, Salford C and Salford C++ have been providing such support for a
decade, unfortunately they have done very little to their C++ compiler
since the middle 1990s

>
>In that context, one might need to add some C++ language support: The
>debugger will need what functions that are initializers for each type, and
>which are modifiers that requires initialized values.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Peter Dimov <pdimov@MailAndNews.com>
Date: Mon, 7 May 2001 21:49:43 GMT
Raw View
>===== Original Message From "James Kuyper Jr." <kuyper@wizard.net> =====
>Peter Dimov wrote:
>>
>> >===== Original Message From Christopher Eltschka
>> <celtschk@dollywood.itp.tuwien.ac.at> =====
>> >LR wrote:
>> >>
>> >> Radoslav Getov wrote:
>> >>
>> >> > - did I mention 'typeof'?
>> >>
>> >> Yes.  What do you think that typeof should return?
>> >
>> >Nothing, because it's not a function.
>>
>> ... but an operator.
>
>Do you have any particular reason for saying that it should be an
>operator?

5.3.3 "Sizeof": "The sizeof operator...".

> What would it operate on?

Expressions.

> It's intended to be a type-name, not
>an operator.

No, 'typeof' is not a type-name. 'typeof(_expression_)' is a type-name.

>A large part of what how it's intended to be used would be
>covered by making the following modification to 7.1.5.2p1:
>
> _type-name:_
>  _class-name_
>  _enum-name_
>  _typedef-name_
>  typeof ( _expression_ )

Agreed.

>> That much is obvious, but which type?
>
>The type of the expression that it takes as an argument. If that type is
>ambiguous, the expression is ill-formed, and therefore so is the
>typeof().

The problem with this 'definition' is that everybody has their own ideas of
what the type of an expression is. :-) In particular:

T t;
T f();

What is typeof(t)? What is typeof(f())? Cover the cases where T is
cv-qualified or a reference to a possibly cv-qualified type.

[My opinion is that typeof(f()) should be T, and typeof(t) should be (option
1) T, (option 2) a reference to T.]

Your own example of

typeof(a+b) tmp = a + b;

shows some of the pitfalls. typeof(a + b) may be const, and you wouldn't be
able to modify tmp.

I start to think that the operator's name should be _Typeof. That way users
won't assume that it fits their own 'typeof' expectations. In particular,

for(_Typeof(C)::iterator i = c.begin(); i != c.end(); ++i)

is _not_ going to work. Not that it should.

--
Peter Dimov
Multi Media Ltd.

---
[ 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: LR <lruss@superlink.net>
Date: Mon, 7 May 2001 21:50:10 GMT
Raw View

Joseph Gottman wrote:
>
> "Olaf Krzikalla" <Entwicklung@reico.de> wrote in message
> news:3AF534EF.44D06F3F@reico.de...

> > > Then it can be a great convenience to be able to write:
> > >
> > >         typeof(a+b) c = a+b;
> >
> > But still this isn't the thing I really want to get. Why should I write
> > the expression twice ?  Why not the (IMHO much better) suggestion to
> > overload auto:
> >
> >          auto c = a+b;

>    This is simpler, but typeof() is more flexible.  For instance, suppose
> you want to write a function that adds two polynomials of different types.
> You could declare it as
>
> template <class X, class Y>
> polynomial<typeof(X() + Y())> operator+(
>      const polynomial<X> &f,
>      const  polynomial<Y> &g);
>
> I don't think auto as you use it above would help in this case.
>
> Joe Gottman


No, but, I really like something like the auto idea.  It's partly why we
have things like the += -= etc. assignment operators.  These kinds of
features probably reduce bugs by typo too.

But maybe overloading auto isn't what's best. Besides, I haven't checked
the standard, but my compiler will actually compile:
 int a = 5;
 short b = 7;
 auto c = a + b;
I'm guessing that c is an int. So standard or not, using auto in this
way may break some code that exists within the scope of current
practice.  Probably unlikely. But.....

So instead, how about something like:
 typeof() c = a+b;
or maybe
 typeof c = a+b;

LR.

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Mon, 7 May 2001 21:50:14 GMT
Raw View
On Mon,  7 May 2001 05:24:10 GMT, James Dennett <jdennett@acm.org> wrote:
> Niklas Matthies wrote:
> > On Sun,  6 May 2001 04:26:09 GMT, Dave Harris <brangdon@cix.co.uk> wr=
ote:
> > [=B7=B7=B7]
> > > The main difference is that a pointer to an incomplete class is
> > > itself complete, where-as a pointer to an incomplete enum would
> > > probably not be complete.
> >=20
> > Why would it not?
>=20
> char * might be larger than int *, and some enums might be stored
> as chars for efficiency while larger enums might use ints.=20

And in what way does that differ from pointer to classes that contain
just a single char or a single int?

-- Niklas Matthies

---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Mon, 7 May 2001 21:50:27 GMT
Raw View
"James Kuyper Jr." <kuyper@wizard.net> wrote in message
news:3AF54E87.C934B2C6@wizard.net...

[snip]

>
> The point is that the standard says that the pointers can compare equal
> if, and ONLY if, they are both NULL, both point to the same object, or
> both point one past the end of the same object. Unless you recognize
> stuff.x+2 and stuff.y as pointing at the same object (namely y[0]), then
> having them compare equal looks like a violation of the standard.
>

It looks to me that this
'past-the-end-of-an-array-being-a-somewhat-valid-pointer
concept (obviously required by STL) causes this problem. I think, though,
that it might have been easylly fixed by the code generators (by adding
space only for an extra
element at the end of any array).

This will of course make some things somewhat bigger... and probably
contradicts
to some other parts of the Standard (probably some structure 'sizeof'
requirements). Or maybe not.

Just a thought.

Radoslav Getov



---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Mon, 7 May 2001 21:50:42 GMT
Raw View
"James Kuyper Jr." <kuyper@wizard.net> wrote in message
news:3AF5C59E.F6F8E36D@wizard.net...
[snip]
>
> All I can say is that I've had four nasty bugs pop up after delivery in
> the last couple of years, which each took much longer to detect than
> they should have, due to premature initialization. None of the premature
> initialization occurred in my own code; it occured in the code produced
> by the people I supervise. I let them initialize variables prematurely,
> because I'm not sufficiently sure of my own position on this issue to
> insist that they adopt my coding style.
>

[snip]

I thought in C++ you have a chance to initialize one thing just once (upon
declaration/construction). I wonder what 'premature' in this context could
mean...

Radoslav Getov




---
[ 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: "Matt Seitz" <mseitz@yahoo.com>
Date: Mon, 7 May 2001 21:50:34 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AF3FC40.5E5CC0B8@jps.net...
> Matt Seitz wrote:
> >
> > One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is
Dr.
> > Stroustrup's insistence that new features must be shown to give
significant
> > improvements in an actual project before being added to the language.
This
> > often took the form of taking an existing project and showing how it
could
> > be significantly improved by adding the new feature.   I would be
interested
> > in reading of anyone performing a similar analysis regarding these
> > suggestions.
>
> Well, the implementation of std::vector from SGI which
> I got with gcc version 2.95.3 20010315/djgpp (release)
> has well over 50 lines of source code to avoid storing a
> copy of the allocator in those cases when it can determine
> at compile time that actually storing a copy of the allocator
> is not needed.  Those 50+ lines would all go away if this code:
>
>   template< class T, class Allocator = allocator<T> >
>   class Vector {
>     T* m_data;
>     T* m_size;
>     T* m_capacity;
>     Allocator m_allocator;
>     // ...
>   };
>
> Would produce a class of size 12 instead of 16 in the case
> where Allocator contained no data.
>
> Is that a good enough improvement for you?

That kind of empirical example does make me think much more favorably about
the feature.  It does still leave questions of how much benefit is actually
gained by not storing a copy of the allocator.  If it would save substantial
memory in actual projects, that is a very strong argument for adding the
feature.  If it's only a few dozen bytes per project, the argument is much
weaker.


---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Mon, 7 May 2001 21:50:50 GMT
Raw View
"Howard Gardner" <usenet@hgardner.com> wrote in message
news:3AF579EF.6000509@hgardner.com...
> James Kuyper Jr. wrote:
>
[snip]
>
> I'm not insisting that all variables be initialized, I'm trying to
> make two simple points.
>
> 1) The current language results in leaving variables uninitialized far
> more often than they should be.
>
> 2) Leaving variables uninitialized is very expensive.
> This debate has been going on for a long time.  Last time that there
> seemed a real chance of changing it--in the mid 80's, in regard to
> ANSI C--I was a newbie and neutral on the subject.  Now, having used
> C since 1982 (and C++ since 1989) for a range of applications
> that extends from embedded machine control to globally distributed
> information systems, I have an opinion.
>
> My opinion is that it is far too easy to write applications with
> undefined state, that it therefore happens far too often, and
> that this change would render it fairly rare.
>
> I can count the number of times that I actually needed to leave a
> variable uninitialized on my fingers and toes. I shudder to think
> of the thousands of hours of my life that have been lost because
> someone left a variable uninitialized.
>
[snip]

If now default initialization were adopted, the only consequences will be:

- some code will become simpler, due to taking advantage of the default
initialization and not having to do it explicitelly

- the buggy programs' behaviour will be more predictable (with some luck,
some bugs might even disappear!)

I woud speculate that there will be a little performance degradation due to
the compiler's optimization capabilities. Except for very few 'delayed
initialization' cases, e.g.

struct NoConstructor
{
    ....
};

NoConstructor x; // 'saved' default initialization
Initialize (x);  // 'explicit' delayed initalization

For which cases using of constructors might be more appropriate anyway.

Radoslav Getov



---
[ 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: xnews.public.home@bogus.rtij.nl (Martijn Lievaart)
Date: Mon, 7 May 2001 21:50:58 GMT
Raw View
"Radoslav Getov" <nospam@mai.com> dared to utter in
news:tfdq6htbrp1160@corp.supernews.com:

>
> Default initialization overhead might make difference for arrays,
> but arrays DO have default initialization anyway (except for 'auto'
> arrays. I really doubt they are widelly used, though).

How about arrays in objects?

class CachePage
{
    unsigned char pageBuf[2048];
    unsigned int indices[16];
};

const int initialCacheSize = 1024;
CachePage *cache = new CachePage[initialCacheSize];

>
> So, why are we trying to 'save' the compiler from generating code for
> something which it will not do anyway? Just to make our lives more
> difficult?
>

I agree with some of your sentiment, but you fail to consider a very
important case.

HTH,
Martijn Lievaart

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Mon, 7 May 2001 21:51:05 GMT
Raw View
On Mon,  7 May 2001 19:37:17 GMT, Matt Seitz <mseitz@yahoo.com> wrote:
> "Dave Harris" <brangdon@cix.co.uk> wrote in message
> news:memo.20010506211715.50265F@brangdon.madasafish.com...
> >
> > Allow dynamic_cast on integral types. Eg:
> >
> >     long big = 100000000L;
> >     int small = dynamic_cast<int>( big );
> >
> > This would perform a range-check, and throw an exception if the result
> > will not fit in the target type. The analogy is with dynamic_cast<derived
> > &)( base & ).
> >
> > Alternatively, provide a standard library function to do the same thing
> > in <limits> - but I think the dynamic_case<> notation is a natural fit,
> > and consistency might be useful in templates.
>
> In THE DESIGN AND EVOLUTION OF C++, section 14.3.5.2 ("Implicit
> Narrowing Conversions"), Dr. Stroustrup gives an example of a function
> for performing this task:
>
>     template<class V, class U> V narrow(U u)
>     {
>         V v  = u;
>         if (v!=u) throw bad_narrowing;
>         return v;
>     }

This doesn't always work. For example, on a typical implementation

   int i = narrow<int, unsigned int>(UINT_MAX);

will result in -1 being assigned to i, and no exception thrown.

-- Niklas Matthies

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Mon, 7 May 2001 21:51:22 GMT
Raw View
Howard Gardner wrote:
>
> Valentin Bonnard wrote:
>
> > Howard Gardner  wrote:
> >
> >> I bet instructors would like to get rid of the whole topic too, for that matter.
> >
>
> > I want students to initialise variables to the right value,
> > or to assign them the right value before use.
>
> I wonder if you would disagree with any of these statements:
>
> 1) In C++, uninitialized variables are common.

The simplest cure against this would be to simply disallow
variable definitions without initializers ;-)

>
> 2) Uninitialized variables often are not discovered until a program is run on a machine other than the OP's.
> 3) Bugs are much harder to correct in large code bases than they are in small code bases.
> 4) Code bases tend to grow in time.
> 5) Code is usually run on the OP's machine much earlier than it is run on other machines
>
> 6) Uninitialized variables often result in bugs that are difficult to reproduce.
> 7) It is relatively difficult to correct bugs that are difficult to reproduce.
>
> 8) Bugs that are both difficult to reproduce and hiding in large code bases can be extremely difficult to correct.
>
> 9) In most circumstances, an uninitialized variable is an error that will result in a bug.
> 10) It is possible to change the syntax of C++ so that naive variable declarations result in initialized variables, statements which currently initialize variables are not affected, and it is possible to create uninitialized variables when necessary.

"Default-initialized" variables are "uninitialized" even if they
are defined to be zero-initialized, unless zero-initialisation
was really intended (in which case you could do that initialisation
explicitly).

Note that for uninitialized pointers, something like "0xdeadbeef"
probably works much better than (and is as reproduceable as) NULL
(which could also be a pointer value assigned on 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.research.att.com/~austern/csc/faq.html                ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 7 May 2001 23:19:24 GMT
Raw View
kuyper@wizard.net (James Kuyper Jr.) wrote (abridged):
> > > Default initialization is just way to encourage bad
> > > coding practices.
> >
> > It is only bad practice because it makes undefined behaviour.
>
> If you've explicitly initialized a variable with an incorrect value,
> and forget to give it a correct value before first use, the behavior is
> perfectly well defined, but incorrect. That's what makes it bad
> practice.

Giving variables the wrong value is indeed a bug, but using a random
value instead of 0 will not make the bug go away.


> >         static Object *objects[1000];
>
> > I wouldn't put an explicit initialisation loop in there.
>
> In C++, there'd be no need to. Just add an initializer:
> ={static_cast<Object*>(NULL)}; That takes care of the first element of
> the array, and forces the other elements to be zero-initialized as
> well.

There is no need for that, either. The array is already forced to be
zero-initialised. It is part of the C++ language definition for static
objects. We can write:

        static Object *objects[1000] = { 0 };

but that only makes the first element explicit. The rest are still being
zero-initialised implicitly.


> The tricky case is when it's not possible to know what the right
> values until later, but you initialize it anyway with arbitrary
> values, because there's a dogma that says they must be initialized
> at the point of definition. That's where the bad coding practice
> comes in.

The proposal doesn't advocate that dogma. It allows an explicit
annotation for uninitialised variables.

I take your point, though, even though I still suspect the net effect of
this change would be fewer C++ bugs overall.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: "Matt Seitz" <mseitz@yahoo.com>
Date: Mon, 7 May 2001 23:20:39 GMT
Raw View
"Niklas Matthies" <news/comp.std.c++@nmhq.net> wrote in message
news:slrn9fe0qg.6je.news/comp.std.c++@ns.nmhq.net...
> On Mon,  7 May 2001 19:37:17 GMT, Matt Seitz <mseitz@yahoo.com> wrote:

> > In THE DESIGN AND EVOLUTION OF C++, section 14.3.5.2 ("Implicit
> > Narrowing Conversions"), Dr. Stroustrup gives an example of a function
> > for performing this task:
> >
> >     template<class V, class U> V narrow(U u)
> >     {
> >         V v  = u;
> >         if (v!=u) throw bad_narrowing;
> >         return v;
> >     }
>
> This doesn't always work. For example, on a typical implementation
>
>    int i = narrow<int, unsigned int>(UINT_MAX);
>
> will result in -1 being assigned to i, and no exception thrown.

True, but my compiler (MS Visual C++) will warn that I am comparing a signed
and unsigned type.

---
[ 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: Matthew Austern <austern@research.att.com>
Date: Mon, 7 May 2001 23:21:11 GMT
Raw View
Dennis Yelle <dennis51@jps.net> writes:

> Matt Seitz wrote:
> >
> > One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is Dr.
> > Stroustrup's insistence that new features must be shown to give significant
> > improvements in an actual project before being added to the language.  This
> > often took the form of taking an existing project and showing how it could
> > be significantly improved by adding the new feature.   I would be interested
> > in reading of anyone performing a similar analysis regarding these
> > suggestions.
>
> Well, the implementation of std::vector from SGI which
> I got with gcc version 2.95.3 20010315/djgpp (release)
> has well over 50 lines of source code to avoid storing a
> copy of the allocator in those cases when it can determine
> at compile time that actually storing a copy of the allocator
> is not needed.  Those 50+ lines would all go away if this code:
>
>   template< class T, class Allocator = allocator<T> >
>   class Vector {
>     T* m_data;
>     T* m_size;
>     T* m_capacity;
>     Allocator m_allocator;
>     // ...
>   };
>
> Would produce a class of size 12 instead of 16 in the case
> where Allocator contained no data.

Yes, but that's not the only way to do it.  Instead of the special
tricks in the SGI implementation, you can just inherit from an empty
base and assume that the compiler will optimize away the base class.

Compilers are permitted, but not required, to assign zero space to an
empty base class.  I used complicated tricks in the SGI library
because, at the time, compilers that performed this optimization were
rare.  Nowadays they're less rare.

At least for this case, a new language feature (with possible impact
on existing code) isn't necessary; an already legal optimization is
sufficient.  We just need to encourage compiler vendors to take
advantage of this freedom.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 7 May 2001 23:25:36 GMT
Raw View
Radoslav Getov wrote:
>
> "James Kuyper Jr." <kuyper@wizard.net> wrote in message
> news:3AF54E87.C934B2C6@wizard.net...
>
> [snip]
>
> >
> > The point is that the standard says that the pointers can compare equal
> > if, and ONLY if, they are both NULL, both point to the same object, or
> > both point one past the end of the same object. Unless you recognize
> > stuff.x+2 and stuff.y as pointing at the same object (namely y[0]), then
> > having them compare equal looks like a violation of the standard.
> >
>
> It looks to me that this
> 'past-the-end-of-an-array-being-a-somewhat-valid-pointer
> concept (obviously required by STL) causes this problem. I think, though,

The concept predates STL, and even C++ itself. It's used in the C
standard as well.

> that it might have been easylly fixed by the code generators (by adding
> space only for an extra
> element at the end of any array).

One interpretation (which I consider false) is that the this wording
requires precisely that implementation.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 7 May 2001 23:30:13 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3AF616E5.B79DA1B@wizard.net>, James Kuyper Jr.
> <kuyper@wizard.net> writes
> >In C++, there'd be no need to. Just add an initializer:
> >={static_cast<Object*>(NULL)}; That takes care of the first element of
> >the array, and forces the other elements to be zero-initialized as well.
>
> Why not the simpler
>  ={0};

Simply because I forgot that it wasn't necessary. I work under a
standards and guidelines document which requires all conversions to be
explicit. I think it's a ridiculous requirement, and this is a prime
example of why. This is one of the burdens of being a government
contractor.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 7 May 2001 23:44:58 GMT
Raw View
Hans Aberg wrote:
...
> >I don't mind breaking a few programs with a new type or keyword, but this
> >would break more than a few. "uchar" is routinely used as a typedef for
> >unsigned char. So back to unichar, or even if it contains an underscore
> >uc_char?
>
> It is extremely easy to fix a program that already uses "uchar": Simply
> choose another name that does not appear in the program and make a batch
> replacement.

'uchar' is a standard typedef in certain contexts (POSIX, I think, but I
could be mistaken); you can't simply remove it without requiring a
re-write all of the code that uses it, and that's an awful lot of code.

Technically, the C++ standard has no need to worry about any other
standards; as a practical matter, a change to the C++ standard that gave
uchar a mandatory meaning incompatible with "unsigned char" would cause
a large number of people to start collecting tar and feathers for the
C++ committee.

As I've said before, I have no objection to unsigned char becoming a
16-bit type suitable for storeing 16-bit unicode characters; little of
my code would break (though some of the libraries I link to would
break). However, there's a whole other set of people who'd pull out the
tar and feathers if that became mandatory.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Tue, 8 May 2001 00:39:22 GMT
Raw View
In article <remove.haberg-0705011147350001@du130-
226.ppp.su-anst.tninet.se>,
remove.haberg@matematik.su.se says...

> The only reason one would want to use a 16-bit type internally in the
> program is that is for some efficiency reason, either space or time. With
> a 16-bit type, one can still create a full 2^16 table, but it is unlikely
> that one might construct a full 2^32 table (one should perhaps adding some
> library table compression algorithms).
>
> But apart for such reasons, it seems me that the use of a 16-bit type will
> just be a bother. (But a codecvt would enable one to read and write such
> types.)

I use both types in, not only the same program, but
the same class.

However, this requirement could be eliminated if it
were possible to define efficient user classes which
are indistinguishable from the primitive types. I, and
others, have addressed that in a separate post.

You can always try wrapping one of the primitive
types, but then conversion doesn't work correctly
(which is why I want the "implicit") type. You can
attempt to explicitly provide all of the operators
that might be needed, but then the short circuited
operators don't work correctly. <sigh> C++ is so close
and yet these little glitches wind up costing terrible
time and trouble because programmers wind up choosing
non-optimal solutions.

I would even argue that if user defined classes could
be made indistinguishable from the primitive types,
that the primitive types should be eliminated with
vendor supplied classes wrapping new standard
primitive types such as __unsigned1__, __unsigned2__,
... or the like which would allow the standard types
to be constructed -- and then user defined classes
would be on an exact par with the existing primitive
types. This approach is probably too radical for the
standards process, however.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 8 May 2001 00:44:24 GMT
Raw View
Peter Dimov wrote:
>
> >===== Original Message From "James Kuyper Jr." <kuyper@wizard.net> =====
> >Peter Dimov wrote:
> >>
> >> >===== Original Message From Christopher Eltschka
> >> <celtschk@dollywood.itp.tuwien.ac.at> =====
> >> >LR wrote:
> >> >>
> >> >> Radoslav Getov wrote:
> >> >>
> >> >> > - did I mention 'typeof'?
> >> >>
> >> >> Yes.  What do you think that typeof should return?
> >> >
> >> >Nothing, because it's not a function.
> >>
> >> ... but an operator.
> >
> >Do you have any particular reason for saying that it should be an
> >operator?
>
> 5.3.3 "Sizeof": "The sizeof operator...".

The standard does not define what an operator is, except by giving a
list of examples. However, I hesitate to call something an operator that
can't be described as returning a value.

...
> > It's intended to be a type-name, not
> >an operator.
>
> No, 'typeof' is not a type-name. 'typeof(_expression_)' is a type-name.

Correction accepted.

...
> >> That much is obvious, but which type?
> >
> >The type of the expression that it takes as an argument. If that type is
> >ambiguous, the expression is ill-formed, and therefore so is the
> >typeof().
>
> The problem with this 'definition' is that everybody has their own ideas of
> what the type of an expression is. :-) In particular:

The standard has a well-defined concept of what the type of an
expression is. It doesn't matter if anyone else is confused.

> T t;
> T f();
>
> What is typeof(t)? What is typeof(f())? Cover the cases where T is
> cv-qualified or a reference to a possibly cv-qualified type.

If we're adding features like typeof() that enable us to do some type
calculus, then there's certainly room for something that strips off
cv-qualifications, but there must also be something that retains them.
Of the two, I think the latter is the one that should be called
'typeof'. How about unqual<T> being the unqualified version of T?

> [My opinion is that typeof(f()) should be T, and typeof(t) should be (option
> 1) T, (option 2) a reference to T.]

Again, there's certainly room for something that removes references, but
there also should be something that retains them. There shouldn't be
anything that adds them; that can already be done using '&typeof()'. I
don't think that 'typeof' should be the one that removes it.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 8 May 2001 00:44:43 GMT
Raw View
Radoslav Getov wrote:
>
> "James Kuyper Jr." <kuyper@wizard.net> wrote in message
> news:3AF5C59E.F6F8E36D@wizard.net...
> [snip]
> >
> > All I can say is that I've had four nasty bugs pop up after delivery in
> > the last couple of years, which each took much longer to detect than
> > they should have, due to premature initialization. None of the premature
> > initialization occurred in my own code; it occured in the code produced
> > by the people I supervise. I let them initialize variables prematurely,
> > because I'm not sufficiently sure of my own position on this issue to
> > insist that they adopt my coding style.
> >
>
> [snip]
>
> I thought in C++ you have a chance to initialize one thing just once (upon
> declaration/construction). I wonder what 'premature' in this context could
> mean...

Here's what an example of what I mean by premature initialization:

 char buffer[N]={0}; // premature initialization.
 cin.read(buffer,N); // real initialization.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 00:45:03 GMT
Raw View
In article <3AF6F307.DCF07E40@spamcop.net>, Ron Natalie
<ron@spamcop.net> writes
>These are really outside the scope of the language.  It would really
>be unworkable to leave large chunks of the core language "optional."
>This can easily be handled as additional standards.

In the standards committees we refer to core language and standard
library. We have certainly not closed our minds to the idea that some
parts of a library might be optional (and note that this is already true
in C, and always has been since its first standard in 1989)



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: James Dennett <jdennett@acm.org>
Date: Tue, 8 May 2001 00:44:31 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Mon,  7 May 2001 05:24:10 GMT, James Dennett <jdennett@acm.org> wrot=
e:
> > Niklas Matthies wrote:
> > > On Sun,  6 May 2001 04:26:09 GMT, Dave Harris <brangdon@cix.co.uk> =
wrote:
> > > [=B7=B7=B7]
> > > > The main difference is that a pointer to an incomplete class is
> > > > itself complete, where-as a pointer to an incomplete enum would
> > > > probably not be complete.
> > >
> > > Why would it not?
> >
> > char * might be larger than int *, and some enums might be stored
> > as chars for efficiency while larger enums might use ints.
>=20
> And in what way does that differ from pointer to classes that contain
> just a single char or a single int?
>=20
> -- Niklas Matthies

The C++ Standard requires that for any class/struct X, X* must have
the same size.  That may restrict alignment for a class containing
only a single char.

-- James Dennett

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Tue, 8 May 2001 01:23:31 GMT
Raw View
mseitz@yahoo.com (Matt Seitz) wrote (abridged):
> In THE DESIGN AND EVOLUTION OF C++, section 14.3.5.2 ("Implicit
> Narrowing Conversions"), Dr. Stroustrup gives an example of a
> function for performing this task:

I gather that function doesn't always work.

Anyway, my point is that such a function should be standardised. If
C++ is to compete as a safe language, it needs standard support for safe
idioms.

I won't insist on the dynamic_cast<> notation, but I notice Stroustrup
had the same idea in the section you quote, and seems to think it a good
one. (On the other hand, functions make it easier to vary the semantics,
for example, clipping to the allowed range.)

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Tue, 8 May 2001 12:57:39 GMT
Raw View
"Radoslav Getov" <nospam@mai.com> wrote in message
news:tfdq6htbrp1160@corp.supernews.com...
> Performance considerations are evil.

Performance considerations are a necessary evil.

> Contemporary compilers are smart
> enough to suppress unnesseccary code, including redundant (default)
> initializations. E.G.

No they are not.  They do not have enough information.
In general the problem of detecting whether a variable will
be used before being initialised is equivalent to the halting
problem.  But there are much simpler examples:

  int f(int &);
  int n;
  f(n);

Is n used before being initialised?  Of course, it would be
easier to tell, if the language had an "out" qualifier on
pointer/reference parameters, but it still doesn't.



---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 8 May 2001 12:58:40 GMT
Raw View
Dave Harris wrote:
>
> kuyper@wizard.net (James Kuyper Jr.) wrote (abridged):
...
> > If you've explicitly initialized a variable with an incorrect value,
> > and forget to give it a correct value before first use, the behavior is
> > perfectly well defined, but incorrect. That's what makes it bad
> > practice.
>
> Giving variables the wrong value is indeed a bug, but using a random
> value instead of 0 will not make the bug go away.

No; making them random instead of 0 makes the bug worse; that's the
whole point - ideally it makes the bug so bad that it gets noticed
during the early stages of testing, rather than long after final
delivery.

...
> > >         static Object *objects[1000];
> >
> > > I wouldn't put an explicit initialisation loop in there.
> >
> > In C++, there'd be no need to. Just add an initializer:
> > ={static_cast<Object*>(NULL)}; That takes care of the first element of
> > the array, and forces the other elements to be zero-initialized as
> > well.
>
> There is no need for that, either. The array is already forced to be
> zero-initialised. It is part of the C++ language definition for static
> objects. We can write:

My apologies; when you said that you "wouldn't put an explicit
initialisation loop in there", I just assumed that you were implying
that you thought that C++ differed from Java in that such a loop was
needed in C++. I didn't even notice that it was static. In that case my
"there'd be no need to" is even more emphatically true.

---
[ 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: "Stephen Howe" <SPAMstephen.howeGUARD@tnsofres.com>
Date: Tue, 8 May 2001 13:02:10 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote in message
news:AcrV7JAEbv76EwYK@ntlworld.com...
> I am writing this sitting in a room at the Danish Standards in
> Copenhagen listening to an evening presentation by Bjarne Stroustrup
> launching his view of the next stage in the ongoing development of C++.
> We have had a number of years (three or more) of stability with an ISO
> Standard for C++ and failure to consider change will tend to move from
> stability (good for many reasons) to stagnation (put your own spin on
> that)
>
> BS has just suggested that we should focus on a few major topics while
> considering minor changes that will increase language and standard
> library consistency.

Ok, but unlike others, it is the library I wish to address (I will come onto
my language features later):

1. Add the member function

streamsize pcount()    const;        // ("put count") number of characters
inserted by the last unformatted output member function

to

basic_ostream

This means that makes the library symmetric with the return values of
fread()/fwrite() for C's stdio library.
Code inpact: None

2. Require that width and setw() manipulator apply to all builtin numeric
types for istream and not just character arrays.

So with the usual headers

int  i, j, k;
std::istringstream is("111111112222222233333333");

is >> setw(8) >> i >> setw(8) >> j >> setw(8) >> k;

would mean that i has the value 11111111, j has the value 22222222 and k the
value 33333333. Without this, overflow will occur on extraction to i. This
is analogous to C's sscanf() with widths in the format specifier.

Code inpact: None, nobody was expect width to apply to numeric types so it
will not break anything.

Stephen Howe


---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 8 May 2001 13:03:01 GMT
Raw View
In article <MPG.1561087579d48672989725@news.lynchburg.net>,
michael.finney@acm.org wrote:
>> But apart for such reasons, it seems me that the use of a 16-bit type will
>> just be a bother. (But a codecvt would enable one to read and write such
>> types.)
>
>I use both types in, not only the same program, but
>the same class.

So, is that convenient? :-)

>However, this requirement could be eliminated if it
>were possible to define efficient user classes which
>are indistinguishable from the primitive types.
...
>You can always try wrapping one of the primitive
>types, but then conversion doesn't work correctly
>(which is why I want the "implicit") type.

I figure this was excluded deliberately, because the many automatic type
conversions of the original C is really a bother.

Otherwise, I have a similar idea, that one should be even be able to
define the current primitive types form a more general construct:

For example, one might define (in pseudo-code) a
  primitive type binary<n> {
    data
    signed_addition, unsigned_addition, ...
  };
and then from that define a new
  primitive type int {
    data = binary<32>::data;
    operator+ = binary<32>::signed_addition;
  };

-- I am not sure exactly how the syntax and semantics would look like, but
that is the idea, though.

Then question is though if one can provide efficient compilers that way.
If optimizations relies one more general principles, such a low level
construct could actually make a compiler implementation easier.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Jens Kilian <Jens_Kilian@agilent.com>
Date: Tue, 8 May 2001 13:04:09 GMT
Raw View
LR <lruss@superlink.net> writes:
> So instead, how about something like:
>  typeof() c = a+b;
> or maybe
>  typeof c = a+b;

<heresy>
  Why not simply go to full ML-style type inference?
</heresy>

It would make generic programming so much easier...
--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Tue, 8 May 2001 16:09:16 GMT
Raw View
nospam@mai.com (Radoslav Getov) wrote (abridged):
> The main (only?) reason why some people don't want default
> initialization are the performance considerations.

Not "only". The other reason is that it prevents some error-detection
techniques. For example, an implementation may currently
default-initialise pointers to a value like 0xdeadbeef, which is non-zero
yet guaranteed to produce a hardware error when dereferenced. Microsoft's
VC++ 6 does this.

It is a real Quality of Implementation issue. Undefined behaviour means
an implementation can switch from "safe but slow" in DEBUG mode to "fast
but unsafe" in RELEASE mode.

Similarly, some compilers warn for code like:

    int demo() {
        int result;
        if (condition())
            result = 42;
        else
            expression();
        return result;
    }

With the new rule, such code might be intentional. Admittedly the
compiler can warn about it anyway, but if it becomes common practice the
warnings about intentional uses will drown out the ones about mistakes.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Tue, 8 May 2001 16:09:27 GMT
Raw View
Override.

A new keyword, used in place of "virtual", which declares an intent to
override. It is an error to declare a member function with "override" if
it does not, in fact, override some base class member. Eg:

    class Base {
    public:
        virtual void func1( int x );
        virtual void func2( long x );
    };

    class Derived: public Base {
    public:
        override void func1( int x ); // OK.
        override void func1( short x ); // Error!
        void func2( long x );
    }

Implementations are encouraged to warn about overriding functions which
don't use "override", such as func2().

(I believe C# has something similar but I've not looked at it myself.)

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Tue, 8 May 2001 16:09:33 GMT
Raw View
Qualified enum members.

Allow enum members to be qualified by the name of the enum they belong
to. Eg:

    enum HAlign { left, center, right, end, begin=left };
    enum VAlign { top, center, bottom, end, begin=top };

    bool isCentered( HAlign a ) {
        assert( HAlign::begin <= a && a < HAlign::end );
        return a == HAlign::center;
    }

Currently this would be ambiguous, because the names begin, end, and
center appear in both enums and there is no way to disambiguate them.
It's blindingly obvious what an expression like HAlign::center should
mean, however.

The semantics are similar to:

    namespace HAlign {
        enum Type { left, center, right, end, begin=left };
    }
    using namespace HAlign;

except that we don't need a separate name for the namespace and the enum.
Alas, I don't think it is feasible to just say that enums are namespaces.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 8 May 2001 16:09:57 GMT
Raw View
In article <zwXZwOCvJz96Ewtv@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>It would really
>>be unworkable to leave large chunks of the core language "optional."
>>This can easily be handled as additional standards.
>
>In the standards committees we refer to core language and standard
>library. We have certainly not closed our minds to the idea that some
>parts of a library might be optional (and note that this is already true
>in C, and always has been since its first standard in 1989)

So then adding things like a GUI library and a communications library
would be possible:

The underlying principle I see is that such features must be sufficiently
stable in the sense that if a platform supports say GUI, then it must be
fairly easy to implement the C++ standard GUI library.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Jens Kilian <Jens_Kilian@agilent.com>
Date: Tue, 8 May 2001 16:10:18 GMT
Raw View
"James Kuyper Jr." <kuyper@wizard.net> writes:
> If we're adding features like typeof() that enable us to do some type
> calculus, then there's certainly room for something that strips off
> cv-qualifications, but there must also be something that retains them.
> Of the two, I think the latter is the one that should be called
> 'typeof'. How about unqual<T> being the unqualified version of T?

unqual<T> can be defined using templates, and if we're getting template typedef
then an additional operator won't be needed.  (Of course unqual<T> could be
a templete defined in some standard header.)
--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 8 May 2001 16:10:06 GMT
Raw View
In article <3AF733DA.81C08796@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:
>Hans Aberg wrote:
>> It is extremely easy to fix a program that already uses "uchar": Simply
>> choose another name that does not appear in the program and make a batch
>> replacement.
>
>'uchar' is a standard typedef in certain contexts (POSIX, I think, but I
>could be mistaken); you can't simply remove it without requiring a
>re-write all of the code that uses it, and that's an awful lot of code.

If is already used in major standarads and libraries that may be include
in a C++ program, choose another name (like "character" perhaps).

But strictly, speaking shouldn't names like "uchar" if used in POSIX be
put into a special namespace if rewritten properly for the current C++
standard?

Even "uchar" it is defined as a macro, it is fairly easy to change it from
the viewpint of C++:
  namespace posix {
    extern "C" {
  #include "posix.h"
  #undef uchar
  typedef unsigned char unchar;
    }
  }
or something. One would merely be forced to use another name than "uchar"
(like here, posix::unchar) when working with the POSIX uchar from the
point of view of C++.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Peter Dimov <pdimov@MailAndNews.com>
Date: Tue, 8 May 2001 16:10:40 GMT
Raw View
>===== Original Message From "James Kuyper Jr." <kuyper@wizard.net> =====
>Peter Dimov wrote:
>>
>> >===== Original Message From "James Kuyper Jr." <kuyper@wizard.net> =====
>> >Do you have any particular reason for saying that it should be an
>> >operator?
>>
>> 5.3.3 "Sizeof": "The sizeof operator...".
>
>The standard does not define what an operator is, except by giving a
>list of examples. However, I hesitate to call something an operator that
>can't be described as returning a value.

I called typeof an operator by analogy with sizeof, which is also a
compile-time construct that can be applied to an arbitrary expression and
does
not evaluate its argument. The alternative is probably to not call it
anything
and only describe what typeof(_expression_) is.

>The standard has a well-defined concept of what the type of an
>expression is. It doesn't matter if anyone else is confused.

Seeing how everybody uses different 'typeofs' in hypothetical examples, I'm
not sure whether the confusion is not important. I think that it lowers the
chances of 'typeof' being accepted.

>If we're adding features like typeof() that enable us to do some type
>calculus, then there's certainly room for something that strips off
>cv-qualifications, but there must also be something that retains them.
>Of the two, I think the latter is the one that should be called
>'typeof'. How about unqual<T> being the unqualified version of T?

Then we are in agreement. Having the type-preserving typeof() is a
necessity.
The other version can be derived easily by using boost::remove_cv and
boost::remove_reference.

>> [My opinion is that typeof(f()) should be T, and typeof(t) should be
(option
>> 1) T, (option 2) a reference to T.]
>
>Again, there's certainly room for something that removes references, but
>there also should be something that retains them. There shouldn't be
>anything that adds them; that can already be done using '&typeof()'.

You meant "typeof() &". :-)

I think that you are right, typeof(t) should be T.

Bottom line, typeof() is not a convenience, it's a necessity. The
'convenience' uses that most associate with it:

typeof(x) tmp(x);

and

typeof(c)::iterator i = c.begin();

simply won't work (and have better alternatives, some might say :-).) An
example that shows the need for typeof is:

Write a function object f such that f(x, y) is equivalent to x @ y, where @
is
an operator (for instance, +, <<.)

Ignoring the "non-const ref can't bind to rvalue" problem, the solution is:

struct F
{
  template<class X, class Y>
    typeof(*(X*)0 @ *(Y*)0)
    operator()(X & x, Y & y)
    {
      return x @ y;
    }
};

This is not an academic example; the lambda library
(http://lambda.cs.utu.fi)
and other expression template libraries need to deal with it. Using lambda,
the above function object is spelled

free1 @ free2

--
Peter Dimov
Multi Media Ltd.

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Tue, 8 May 2001 16:11:35 GMT
Raw View
On Mon,  7 May 2001 23:20:39 GMT, Matt Seitz <mseitz@yahoo.com> wrote:
> "Niklas Matthies" <news/comp.std.c++@nmhq.net> wrote in message
> news:slrn9fe0qg.6je.news/comp.std.c++@ns.nmhq.net...
> > On Mon,  7 May 2001 19:37:17 GMT, Matt Seitz <mseitz@yahoo.com> wrote:
>
> > > In THE DESIGN AND EVOLUTION OF C++, section 14.3.5.2 ("Implicit
> > > Narrowing Conversions"), Dr. Stroustrup gives an example of a function
> > > for performing this task:
> > >
> > >     template<class V, class U> V narrow(U u)
> > >     {
> > >         V v  = u;
> > >         if (v!=u) throw bad_narrowing;
> > >         return v;
> > >     }
> >
> > This doesn't always work. For example, on a typical implementation
> >
> >    int i = narrow<int, unsigned int>(UINT_MAX);
> >
> > will result in -1 being assigned to i, and no exception thrown.
>
> True, but my compiler (MS Visual C++) will warn that I am comparing a
> signed and unsigned type.

True, but that's not what is wanted. The original proposal was for
situations where you *want* convert (say) an unsigned int to an int, but
want to be notified (by an exception) if *for the particular value* this
conversion doesn't preserve the value.

-- Niklas Matthies

---
[ 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: Nicola Musatti <objectway@divalsim.it>
Date: Tue, 8 May 2001 16:11:28 GMT
Raw View

Robert FISHER wrote:
[...]
> Finally: I understand that some think that everyone everywhere should
> always, without exception (pun intended), use "resource acquisition is
> initialization". Personally, however, I like the fact that C++ is a
> multiparadigm language, and there are times when I'd find a finally
> block extremely useful.

I've heard this before, but I'm not convinced...

> How about being able to place some restrictions on a class that are
> enforced by the compiler. Non-derivable classes. Classes that can't be
> placed on the stack/heap. Etc. Sure, there are some idioms that allow
> some of these things to be done within the existing language, but they
> are often verbose, inelegant, or both. (I want to say what I mean,
> rather than say something that coincidentally has the side effect of
> what I mean.)

Along the same lines, I'd like Java's "final" to be added, and maybe an
explicit "abstract" would be appropriate too.

[...]
> How about a (good, simple, portable, safe, efficient) way to tell
> whether an object was allocated with new and can be safely deleted? (In
> other words, not one of the kludges that have been created using the
> existing language.) Imagine objects that can actually tell whether it is
> safe to delete themselves or not. This might be the one thing I'd most
> like to see.

I'd prefer this kind of issue to be dealt with at library level.

> (Also, a way to tell whether you should use delete or delete[] might be
> useful. How about a way to find the size of an array allocated by new[].
> Presumably the runtime has to keep track of such information anyway so
> that delete[] works properly.)

Use vector.

> The honorable Mr. Stroustrup has mentioned eliminating the default copy
> constructor and assignment operator for classes with destructors and
> making base classes with virtual member functions have a virtual
> destructor by default. These will be very welcome changes.

Another good thing would be having the compiler synthesize an empty body
for virtual pure destructors.

Best regards,
Nicola Musatti

---
[ 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: cmd@gmrc.gecm.com (Chris Dearlove)
Date: Tue, 8 May 2001 16:11:43 GMT
Raw View
Francis Glassborow (francis.glassborow@ntlworld.com) wrote:
: Have no fear, suggestions will be rigorously analysed
: for benefit versus cost but the time for that is a little later. For now
: I would like to see the brain storming rules applied -- anything goes
: and people must not be overtly negative about other peoples suggestions.
: When we have a stack of suggestions, then will be the time to winnow thw
: wheat from the chaff.

OK, here's my trivial suggestion, add to <complex>

float conj(float x) { return x };

and similarly for double and long double.

Why is this useful? It may (and I have had an example where it did,
but I had to use a function outside namespace std) allow writing a
single templated function which works on real and complex numbers,
where the mathematical definition uses conj, but that doesn't work
for real numbers.

Inlined it should have zero overhead compared to writing the real
specialisation explicitly.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Tue, 8 May 2001 16:48:48 GMT
Raw View
Peter Dimov wrote:
>
> >===== Original Message From Christopher Eltschka
> <celtschk@dollywood.itp.tuwien.ac.at> =====
> >LR wrote:
> >>
> >> Radoslav Getov wrote:
> >>
> >> > - did I mention 'typeof'?
> >>
> >> Yes.  What do you think that typeof should return?
> >
> >Nothing, because it's not a function.
>
> ... but an operator.
>
> >What does int return?
>
> Nothing, because it's not an operator. :-)
>
> >If you think "higher order", typeof returns a type.
>
> That much is obvious, but which type?
>
> typeof(std::cout << 5) f()
> {
>   return std::cout << 5;
> }
>
> What is the return type of f()?

Let's see. std::cout is of type std::ostream. 5 is of type int.
Therefore the operator chosen would be
std::ostream& operator<<(std::ostream&, int)

Now one could debate if typeof should be "reference transparent"
or not. Depending on that choice, typeof(std::cout << 5) would be
either std::ostream& or just std::ostream.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Tue, 8 May 2001 17:00:17 GMT
Raw View
Dave Harris wrote:

[...]

> If we allow enums to be incomplete types, we have a choice. We can either
> allow pointers to enums to be incomplete types too, so that the above
> implementation would still be OK. Or we can require pointers to
> incomplete enums to be complete, in which case the above implementation
> would have to change.
>
> It can change in 2 ways. Firstly, so that:
>
>      assert( sizeof Small == sizeof char );
>      assert( sizeof (Large *) == sizeof (char *) );
>
> This implies some space overhead for all enum pointers. Or:
>
>      assert( sizeof Small == sizeof int );
>
> This implies some space overhead for all small enums.
>
> Ideally the people who write compilers for these weird architectures
> would be consulted about this. Possibly they already use sizeof int for
> all enums anyway.

I guess pointers to enums are rare enough that the space overhead
for pointers to large enums would be no problem.

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Tue, 8 May 2001 17:43:49 GMT
Raw View
"Matt Seitz" <mseitz@yahoo.com> wrote in message
news:w2EI6.142$BH6.22342@newsread1.prod.itd.earthlink.net...
> One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is
Dr.
> Stroustrup's insistence that new features must be shown to give
significant
> improvements in an actual project before being added to the language.
This
> often took the form of taking an existing project and showing how it could
> be significantly improved by adding the new feature.

The problem is that many projects cannot be "shown" at all.
I used to use trigraphs a bit, but I couldn't have shown you
any of the code, in a form that justified the need for them,
and I expect this was typical of those applications.

Also, given that we have people in this newsgroup who say
things like "with modern Pentiums, efficiency is unimportant",
if the only benefit of a feature is a speed or size win, how
big does that win have to be to justify the feature?



---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Tue, 8 May 2001 18:52:33 GMT
Raw View
"Virtual pointers" (and references).

This is an idea I've repeatedly been tossing around my mind within the
past two years, and I'd like to hear what others think about it. So feel
free to rant, especially if this is an old hat.

When thinking about runtime polymorphism of objects, one comes to the
realization that it's actually not the objects that are polymorphic, but
the pointers and references. Under this light, it can appear strange
that, in C++, polymorphism (as denoted by `virtual') is a property of
the object type (i.e. the class) instead of being a property of pointer
and reference types.

And actually, it is rather straightforward to devise an underlying
implementation for the other concept. Instead of storing a vtable
pointer in an object, one would have /virtual pointers/ (and references)
that are really a pair consisting of a pointer to the object plus a
vtable pointer corresponding to the effective (dynamic) type of the
object.

[In the following, I'll talk only about pointers, but everything should
naturally map to references as well.]

Such virtual pointer values could of course only be created in
situations where the effective type the object pointed to is statically
known, or by copy from an existing virtual pointer, or directly from a
regular pointer which assumes that the pointer's base type is the
effective type, or possibly by some dynamic_cast-like mechanism from a
regular pointer. The compiler would automatically create a vtable for
each class or build-in type of which an instance gets such a "virtual
address" taken from.

The invocation of a member function through such a virtual pointer would
of course be performed using the vtable contained in the virtual
pointer.

Here's a simple example to get a feel for how this could look like:

   class Base
   {
      public:  void foo(int);       // need not be virtual
      ...
   };

   class Derived : public Base
   {
      public:  void foo(int);       // need not be virtual
      ...
   };

   void g(Base virtual *vp)
   {
      vp->foo(23);                  // [2]
   }

   void h()
   {
      Derived d;
      Base virtual *vp;
      vp = &d;                      // [1]
      g(vp);
      Derived *dp = new Derived;
      g(dp);                        // [3]
      delete dp;
   }

[1] causes the compiler to include a vtable for Derived in the generated
code, and assigns to vp a pair consisting of the address of d and the
address of the vtable for Derived.

[2] same as if foo() had been declared virtual in Base and vp was a
regular pointer-to-Base. I.e. Derived::foo() gets called.
Pseudo generated code:  (vp.vtab_ptr->[1])(vp.obj_ptr, 23);

[3]: Same effect as in [1].

Some advantages and disadvantages of this approach are:

   +  Classes can be designed independently of whether they will be used
      polymorphically or not. (Can simplify certain design issues.)

   +  Existing classes with non-virtual member functions can be used
      polymorphically without changing their definition. (Enables
      reusing classes which were defined without polymorphism in mind.)
      (Actually, this can even be applied to existing *objects*. While
      some program is already running that uses non-polymorphic objects,
      one can write a shared library to be used by that program that
      uses these objects polymorphically, and dynamically link it to the
      running program, and let it use objects that were already alive
      before the library was written.)

   +  Built-in types could be allowed to be derived from, and be used in
      a polymorphic fashion. The standard could even place the built-in
      types in some class hierarchy and thus allow them to be used
      polymorphically even without user-derived classes being involved.
      E.g. (using a "virtual reference"):

         Integer virtual &ivref;          // Integer is supposed to be a
         int i; long l;                   // base for both int and long
         if (some_condition()) ivref = i;
                          else ivref = l;
         ...
         ivref = 5;                       // does the "right thing"

   +  Non-polymorphic uses of classes that are also to be used
      polymorphically do not incur the overhead of the vtable pointer
      per object. (This makes polymorphic use of built-in types feasible
      in the first place.)

   +  When the programmer uses a virtual pointer, s/he _knows_ that
      method invocations are dynamic, or for example with types like
      vector<Base virtual *> it is obvious that this is supposed to be a
      collection of polymorphic objects. This way, code and interfaces
      implicitly document the intent of polymorphism, which otherwise is
      not evident.

   -  Memory overhead can be noticeably higher because there is a
      vtable pointer per pointer or reference instead of per object.
      (On the other hand, one has the choice whether to use regular
      pointers or virtual pointers; a choice that doesn't exist with
      vtables contained in objects once the class has been defined.)

   -  These vtables need to contain pointers to all member functions of
      a class (as opposed to only virtual-declared member functions).
      Actually, only member functions present in the virtual pointer's
      base type need to be included. I.e. if the compiler knows that the
      program only uses virtual pointers of type `Base virtual *' but
      not of type `Derived virtual *', it can omit any member functions
      that are only introduced in class Derived.

   -  I haven't looked into how to extend this implementations to
      multiple inheritance; this might be tricky.
      (OTOH, implementation of MI already is quite tricky anyway.)

Originally, I had thought of this as an alternative way that C++ could
have been designed, i.e. instead of the current way of doing runtime
polymorphism in C++. But in this thread it occured to me that it is
possible and might actually be worthwhile to add it to current C++ as an
additional feature.

-- Niklas Matthies

---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Tue, 8 May 2001 18:52:23 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AEF1353.87673842@jps.net...
> So, what do we want?
[snip]
> What else?

Named operators? I.e.

X operator roll (const Y& a, const Z& b)
{
.... // whatever
};

X a;
Y b;
Z c;

a = b roll c;

... or even better: allow binary (and why not unary?) functions calls using
operator notation. After all, you can call user defined operators using both
funciton and operator notation. Why not vice versa?

Radoslav Getov




---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 21:03:33 GMT
Raw View
In article <remove.haberg-0805011133430001@du129-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>So then adding things like a GUI library and a communications library
>would be possible:

Yes, but we need to be convinced that it can be done well in a manner
that is portable and useful.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 21:03:42 GMT
Raw View
In article <9d99k4$epk$1@cam-news1.cambridge.arm.com>, Al Grant
<tnarga@arm.REVERSE-NAME.com> writes
>Also, given that we have people in this newsgroup who say
>things like "with modern Pentiums, efficiency is unimportant",
>if the only benefit of a feature is a speed or size win, how
>big does that win have to be to justify the feature?

One of the major work items at the moment is producing a technical
report on performance issues in C++ so at least the standards committees
think it still matters.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Tue, 8 May 2001 21:45:49 GMT
Raw View
Although its similar to the initialization question, I've recently wondered
if the method provided for initializing the member variables of a class is
the clearest method.  Take for example,

///////////////// X.h
class Values
{
   float v1, v2;
public:
   Values(void);
   Values(float v2) : v1(1), v2(v2) {}
};
/////////////  x.cpp
Values::Values(void) : v1(1) {v2 = somecomplicatedformula;}

and contrast the two methods for initializing v1 and v2.  In both cases v1
is 1 and there is no reason for anyone reviewing the .h file to know that.
But if the 2nd overloaded cstor was not present, the knowledge would not be
present.  The other thing is that even if the 2nd overload cstor where the
only one present, if there were sufficient member variables present, the
line seperation between definitition and initialization could be quite
large.

Would there be an advantage to an additional syntax for initializing
membervariables?  I'm thinking something like
class Values
{
   float v1 = 1, v2;
public
   Values(float v2) : v2(v2) {}
};
or perhaps
class Values
{
   float v1(1), v2;
public
   Values(float v2) : v2(v2) {}
};

Even discounting the advantage of the closeness of variable/value,
seperating declaring/initializing can have the effect of doubling the size
of a declaration. Compare
struct GlobalData
{
   bool batchmode;
   GlobalData(void) : batchmode(false) {}
};
with
struct GlobalData
{
   bool batchmode = false;
};
which is a minor increase in size.  However
struct Virgs
{
   float coeff1,
           coeff2,
           ///....
           coeff100;
   Virgs(void)
    :  coeff1(1),
       coeff2(1.02),
       // ....
       coeff100(5.09438) {}
};
would be substantially larger than
struct Virgs
{
   float coeff1=1,
           coeff2(1.02),
           ///....
           coeff100(5.09438);
};
While viewing the 2nd declaration, you are given 3 important pieces of data:
the variable name, the variable type and the initial value of the variable.
In the first declaration, one section has the variable name and the variable
type.  Another, distant section has the variable name and initial value.

I have had maintenance programming that would benefit from this additional
initialization style.  During maintenance, I have found the need to add a
new flag variable to a class with multiple ctors.  Rather than chase down
all the modules with the ctor code, I have done the following
class SomethingLarge
{
// .......
   class GWBFlag
   {
    public:
         bool flag;
         GWBFlag(void) : flag(true) {}
   };
   GWBFlag gwbFlag;
   SetGWBFlag(void) {gwbFlag.flag = true;}
   ClrGWBFlag(void) {gwbFlag.flag = false;}
};

which is a lot of code simply to avoid modifying .cpp files.  Wouldn't it be
so much simpler to just add
   bool gwbFlag = true;
to the existing definition?

Ok, that's my glass house.  Start throwing.
Greg Brewer





---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 22:52:45 GMT
Raw View
In article <memo.20010508022024.35939F@brangdon.madasafish.com>, Dave
Harris <brangdon@cix.co.uk> writes
>Allow enum members to be qualified by the name of the enum they belong
>to. Eg:

I think you are really asking that enums have a scope. Actually I would
like something more, I would like to see enums as full fledged types
with a scope in which member functions can be placed. Among other things
that would allow me to provide a specialised operator= for enums.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Tue, 8 May 2001 22:53:05 GMT
Raw View
On Tue,  8 May 2001 00:44:31 GMT, James Dennett <jdennett@acm.org> wrote:
> Niklas Matthies wrote:
> > On Mon,  7 May 2001 05:24:10 GMT, James Dennett <jdennett@acm.org> wr=
ote:
> > > Niklas Matthies wrote:
> > > > On Sun,  6 May 2001 04:26:09 GMT, Dave Harris <brangdon@cix.co.uk=
> wrote:
> > > > [=B7=B7=B7]
> > > > > The main difference is that a pointer to an incomplete class is
> > > > > itself complete, where-as a pointer to an incomplete enum would
> > > > > probably not be complete.
> > > >
> > > > Why would it not?
> > >
> > > char * might be larger than int *, and some enums might be stored
> > > as chars for efficiency while larger enums might use ints.
> >=20
> > And in what way does that differ from pointer to classes that contain
> > just a single char or a single int?
>=20
> The C++ Standard requires that for any class/struct X, X* must have
> the same size.

Ok, to put it yet another way: If the standard doesn't seem to mind to
restrict classes in that way, why should it mind to restrict enums in
that way?=20

> That may restrict alignment for a class containing only a single char.

The implementation can always use the equivalent of a void * internally
to implement pointers-to-enum.

-- Niklas Matthies

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Tue, 8 May 2001 22:54:01 GMT
Raw View
"James Kuyper Jr." wrote:
>
> Radoslav Getov wrote:
> >
> > "James Kuyper Jr." <kuyper@wizard.net> wrote in message
> > news:3AF54E87.C934B2C6@wizard.net...
> >
> > [snip]
> >
> > >
> > > The point is that the standard says that the pointers can compare equal
> > > if, and ONLY if, they are both NULL, both point to the same object, or
> > > both point one past the end of the same object. Unless you recognize
> > > stuff.x+2 and stuff.y as pointing at the same object (namely y[0]), then
> > > having them compare equal looks like a violation of the standard.
> > >
> >
> > It looks to me that this
> > 'past-the-end-of-an-array-being-a-somewhat-valid-pointer
> > concept (obviously required by STL) causes this problem. I think, though,
>
> The concept predates STL, and even C++ itself. It's used in the C
> standard as well.
>
> > that it might have been easylly fixed by the code generators (by adding
> > space only for an extra
> > element at the end of any array).

That "fix" is worse than the problem.

> One interpretation (which I consider false) is that the this wording
> requires precisely that implementation.

The real problem is not that stuff.x+2 and stuff.y compare equal.
The real problem is that the clear meaning of the text of the
standard is that they do NOT compare equal.

Some people claim to be able to bend the text of the standard
in their minds to the point that it allows stuff.x+2 and stuff.y
to compare equal.
I am unable to do that.
So I think that the text of the standard should be changed.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Howard Gardner <usenet@hgardner.com>
Date: Tue, 8 May 2001 22:54:49 GMT
Raw View
Dave Harris wrote:

> nospam@mai.com (Radoslav Getov) wrote (abridged):
>
>>The main (only?) reason why some people don't want default
>>initialization are the performance considerations.
>
> Not "only". The other reason is that it prevents some error-detection
> techniques. For example, an implementation may currently
> default-initialise pointers to a value like 0xdeadbeef, which is non-zero
> yet guaranteed to produce a hardware error when dereferenced. Microsoft's
> VC++ 6 does this.


I don't think that the particular value needs to be specified
in the standard, because the goal (keeping the program state
defined) is met regardless of the value used.

---
[ 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: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Tue, 8 May 2001 22:54:35 GMT
Raw View
"Hans Aberg" <remove.haberg@matematik.su.se> wrote in message
news:remove.haberg-0805011133430001@du129-226.ppp.su-anst.tninet.se...
> The underlying principle I see is that such features must be sufficiently
> stable in the sense that if a platform supports say GUI, then it must be
> fairly easy to implement the C++ standard GUI library.

There's nothing to stop a group like the X consortium
publishing a C++ GUI library and people adopting it as a
de facto standard.  Why do you think the language standards
committee should spend time on this?  There are dozens if
not hundreds of core language issues that are more
deserving of the standards commitee's time.

GUI libraries go out of date horribly quickly too.
If it had been standardised 20 years ago it would have
had all sorts of features for pen plotters, light pens,
sprites etc.  Who knows what will be the GUI idioms of
20 years' time?

Incidentally it is not the case that most programmable
devices have GUIs.  And I don't think it ever has been.
C++ is not like Java, it is a good choice right across
the application space from embedded up to large-scale
but could support those extremes better.  IMHO the way
to compete with Fortran is not with template libraries
like Blitz++ but with language features which enable
optimisations and standardise the floating-point
environment.  Even C99 now does that better than 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                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 23:02:49 GMT
Raw View
In article <tfgeppjoa8brf4@corp.supernews.com>, Radoslav Getov
<nospam@mai.com> writes
>... or even better: allow binary (and why not unary?) functions calls using
>operator notation. After all, you can call user defined operators using both
>funciton and operator notation. Why not vice versa?

Interesting idea. AFAICS this is just syntactic sugar. That does not
make it a bad thing in itself. Can you work up a paper showing how such
a facility would be useful in at least two problem domains by allowing
the domain expert to write code that was more natural to domain experts.

Actually with it, we could add swap as an operator.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 23:02:26 GMT
Raw View
In article <3AF80135.F84E9A0C@divalsim.it>, Nicola Musatti
<objectway@divalsim.it> writes
>Another good thing would be having the compiler synthesize an empty body
>for virtual pure destructors.

Well Bjarne went further in suggesting that we should not need these at
all. Any class with a virtual member would have a virtual default dtor
if none was declared by the class author.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Matt Seitz" <mseitz@yahoo.com>
Date: Tue, 8 May 2001 23:02:00 GMT
Raw View
"Al Grant" <tnarga@arm.REVERSE-NAME.com> wrote in message
news:9d99k4$epk$1@cam-news1.cambridge.arm.com...
> "Matt Seitz" <mseitz@yahoo.com> wrote in message
> news:w2EI6.142$BH6.22342@newsread1.prod.itd.earthlink.net...
> > One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is
> Dr.
> > Stroustrup's insistence that new features must be shown to give
> significant
> > improvements in an actual project before being added to the language.
> This
> > often took the form of taking an existing project and showing how it
could
> > be significantly improved by adding the new feature.
>
> The problem is that many projects cannot be "shown" at all.
> I used to use trigraphs a bit, but I couldn't have shown you
> any of the code, in a form that justified the need for them,
> and I expect this was typical of those applications.
>
> Also, given that we have people in this newsgroup who say
> things like "with modern Pentiums, efficiency is unimportant",
> if the only benefit of a feature is a speed or size win, how
> big does that win have to be to justify the feature?

I don't think it is necessary to share the source of a project to justify a
benefit.  I think a simple example demonstrating the problem, combined with
an analysis of how large the benefit would be in an actual project would
suffice.  The example is necessary so that others can verify that there is
not a better solution to the problem.  The benefit analysis is necessary to
justify the effort of adding the feature.

The win has to be big enough to convince a significant number of users and
most implementers that it is worth the effort of doing it.  An easy feature
requires a smaller win than a hard feature.  Also, I wouldn't say that speed
or size are the only benefits that could justify a feature.  Another
justification could be showing that a large number of errors (either by
students or within a project) would have been avoided or more easily
detected if a new feature was added.



---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 23:03:02 GMT
Raw View
In article <memo.20010508022022.35939E@brangdon.madasafish.com>, Dave
Harris <brangdon@cix.co.uk> writes
>A new keyword, used in place of "virtual", which declares an intent to
>override. It is an error to declare a member function with "override" if
>it does not, in fact, override some base class member. Eg:

Well one area Bjarne designated for consideration was the accidental
hiding of base class functions, so I think the problem will be looked
at, but the solution may be different.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Barry Margolin <barmar@genuity.net>
Date: Tue, 8 May 2001 23:28:18 GMT
Raw View
In article <tfgeppjoa8brf4@corp.supernews.com>,
Radoslav Getov <nospam@mai.com> wrote:
>Named operators? I.e.
>
>X operator roll (const Y& a, const Z& b)
>{
>.... // whatever
>};
>
>X a;
>Y b;
>Z c;
>
>a = b roll c;
>
>... or even better: allow binary (and why not unary?) functions calls using
>operator notation. After all, you can call user defined operators using both
>funciton and operator notation. Why not vice versa?

Because it makes parsing *really* hard.

BTW, when defining an operator, you need to specify things like precedence
and associativity, unless you're willing for all user-defined operators to
group the same.

--
Barry Margolin, barmar@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ 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: Mark Blewett <mblewett@nildram.co.uk>
Date: Tue, 8 May 2001 23:28:35 GMT
Raw View
>From all the threads a have read (I admit with a project deadline,
following all posts is difficult) there seems to a proliferation of "I
want / would like this"... (whether they are right or wrong).

What with the my deadline, may be I'm "standing on a hill" looking
down...

1) Undefined behaviour. Should it exist in a "defined" language? For
example if C++ is a portable language, does undefined behaviour hinder
the cross platform / compiler developer?

2) I'm interested in the quote from the original post "overall goals
should include making C++ a better language for systems programming
and library building". Does this mean BS thinks C++ has lost the app
development battle, and that C++ has a reduce role as an application
language?

3) IMHO C++ is becoming too complex... why should a developer / user
learn C++ if it takes a couple of years to become reasonable
developer? (I'm a professional C++ developer with over 7 years
experience, and the technical abilities of prospective employees
claming c++ experience is farcile, a third can't even explain virtual
functions and polymorphism!)

C++ may well be getting to the comlexity where the commercial
companies prefer to concentrate on their own development environments
which have easy access to gui/platform functions, which get people in
quickly, and tie them to the language / tools (for example VB /
Delphi). Why should a commercial company develop a tool where it takes
an individual a couple of years to become reasonable in the language,
and then have to learn the plaform?... when it is more profitable to
produce a simpler development enviroment for a simpler language?

As far as C++ is concerned stability in a language is good, and the
development of the language can helpful missing features but can be
bad for stability.

What C++ needs now is simplification, consolidation and
standardization (not it terms of ANSI, but in terms of the language),
possibily with the introduction of a mininimal set of new features.

Regards
Mark



---
[ 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: Olaf Krzikalla <Entwicklung@reico.de>
Date: Tue, 8 May 2001 23:28:40 GMT
Raw View
public: //was: private:
  my little list of wishes:

1. ctor forwarding. I don't want to derive just to get a new ctor.
Better:

class A {
  A (int i) { /* code_1 */ }
  A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
};

code_2 is executed after full construction and the execution of code_1.


2. strong typedef's. This is impossible, because it would break too much
code. Also the capabilities of the current typedef are still needed.
But: an overload of typename could do this:

typedef int tInt; // defines the type tInt
typename int tInt; // adds a synonym for int

I think, this would also matches the meanings of typeDEF and typeNAME.
For backward compatibility there must be any way to say: treat typedef
as typename.


Other wishes I have are already discussed.

Best regards
Olaf Krzikalla

---
[ 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: Olaf Krzikalla <Entwicklung@reico.de>
Date: Tue, 8 May 2001 23:43:31 GMT
Raw View
public: //was: private:
  my little list of wishes:


1. ctor forwarding. I don't want to derive just to get a new ctor.
Better:

class A {
  A (int i) { /* code_1 */ }
  A (const class B& b) : A (makeInt (b)) { /*code_2*/ }
};

code_2 is executed after full construction and the execution of code_1.


2. strong typedef's. This is impossible, because it would break too much
code. Also the capabilities of the current typedef are still needed.
But: an overload of typename could do this:

typedef int tInt;       // defines the type tInt
typename int tInt;      // adds a synonym for int

I think, this would also matches the meanings of typeDEF and typeNAME.
For backward compatibility there must be any way to say: treat typedef
as typename.


Other wishes I have are already discussed.

Best regards
Olaf Krzikalla

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 23:44:31 GMT
Raw View
In article <mjXJ6.18$v86.417@burlma1-snr2>, Barry Margolin
<barmar@genuity.net> writes
>BTW, when defining an operator, you need to specify things like precedence
>and associativity, unless you're willing for all user-defined operators to
>group the same.

Why not? Make it left to right, and make a X b equivalent to writing
operator X(a,b); Not that hard to parse.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 8 May 2001 23:58:57 GMT
Raw View
In article <sdsgftcomndg54r9huigjvc2cjmns49aah@4ax.com>, Mark Blewett
<mblewett@nildram.co.uk> writes
>1) Undefined behaviour. Should it exist in a "defined" language? For
>example if C++ is a portable language, does undefined behaviour hinder
>the cross platform / compiler developer?

To the contrary, undefined behaviour makes it easier on the compiler
developer by shifting the responsibility to the user. Unspecified and
implementation defined can be more problematical.

>
>2) I'm interested in the quote from the original post "overall goals
>should include making C++ a better language for systems programming
>and library building". Does this mean BS thinks C++ has lost the app
>development battle, and that C++ has a reduce role as an application
>language?

Not at all, just that as a general purpose language it needs to focus on
areas where it does not work as well as it might.

>
>3) IMHO C++ is becoming too complex... why should a developer / user
>learn C++ if it takes a couple of years to become reasonable
>developer? (I'm a professional C++ developer with over 7 years
>experience, and the technical abilities of prospective employees
>claming c++ experience is farcile, a third can't even explain virtual
>functions and polymorphism!)

Well one of Bjarne's objectives was making the language more teachable,
but some of the blame lies with the inadequacies of many instructors
(and the language they use makes little difference)

>
>C++ may well be getting to the comlexity where the commercial
>companies prefer to concentrate on their own development environments
>which have easy access to gui/platform functions, which get people in
>quickly, and tie them to the language / tools (for example VB /
>Delphi). Why should a commercial company develop a tool where it takes
>an individual a couple of years to become reasonable in the language,
>and then have to learn the plaform?... when it is more profitable to
>produce a simpler development enviroment for a simpler language?

You mean like getting rid of medicine (as a the trade of doctors etc.)
and replacing it with grandma's favourite remedy? Don't Americans have a
word for such practitioners?

>
>As far as C++ is concerned stability in a language is good, and the
>development of the language can helpful missing features but can be
>bad for stability.
>
>What C++ needs now is simplification, consolidation and
>standardization (not it terms of ANSI, but in terms of the language),
>possibily with the introduction of a mininimal set of new features.

New features can actually simplify:)


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 9 May 2001 00:17:22 GMT
Raw View
Nicola Musatti wrote:
>
> Robert FISHER wrote:
> [...]
> > How about being able to place some restrictions on a class that are
> > enforced by the compiler. Non-derivable classes. Classes that can't be
> > placed on the stack/heap. Etc. Sure, there are some idioms that allow
> > some of these things to be done within the existing language, but they
> > are often verbose, inelegant, or both. (I want to say what I mean,
> > rather than say something that coincidentally has the side effect of
> > what I mean.)
>
> Along the same lines, I'd like Java's "final" to be added, and maybe an
> explicit "abstract" would be appropriate too.

I could live with those.  The Java restriction that a class can't
be both final and abstract might make sense in C++ too, as we can
have free functions.  In Java it's conventional to use classes to
simulate free functions, but it's explicitly not legal to declare
them abstract (though they should not be instantiated) and final
(though they're not made for inheritance).

The current conventional hack to make a class nonderivable (as a
friend of a dummy private virtual base class) is ugly and cannot
be templated.  The convention of using a protected constructor
to indicate that a class is abstract is no defense against derived
classes; a pure virtual destructor can sometimes help, but just
being able to use an explicit language feature would be nice.

-- James Dennett

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 9 May 2001 00:17:12 GMT
Raw View
Dennis Yelle wrote:
...
> The real problem is not that stuff.x+2 and stuff.y compare equal.
> The real problem is that the clear meaning of the text of the
> standard is that they do NOT compare equal.
>
> Some people claim to be able to bend the text of the standard
> in their minds to the point that it allows stuff.x+2 and stuff.y
> to compare equal.
> I am unable to do that.
> So I think that the text of the standard should be changed.

I could agree with that; after all, the comparable wording in the C
standard has changed. Section 6.5.9p6 of the C99 standard says: "Two
pointers compare equal if and only if both are null pointers, both are
pointers to the same object (including a pointer to an object and a
subobject at its beginning) or function, both are pointers to one past
the last element of the same array object, or one is a pointer to one
past the end of one array object and the other is a pointer to the start
of a different array object that happens to immediately follow the first
array object in the address space.91)"

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 9 May 2001 00:21:44 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Tue,  8 May 2001 00:44:31 GMT, James Dennett <jdennett@acm.org> wrot=
e:
> > Niklas Matthies wrote:
> > > On Mon,  7 May 2001 05:24:10 GMT, James Dennett <jdennett@acm.org> =
wrote:
> > > > Niklas Matthies wrote:
> > > > > On Sun,  6 May 2001 04:26:09 GMT, Dave Harris <brangdon@cix.co.=
uk> wrote:
> > > > > [=B7=B7=B7]
> > > > > > The main difference is that a pointer to an incomplete class =
is
> > > > > > itself complete, where-as a pointer to an incomplete enum wou=
ld
> > > > > > probably not be complete.
> > > > >
> > > > > Why would it not?
> > > >
> > > > char * might be larger than int *, and some enums might be stored
> > > > as chars for efficiency while larger enums might use ints.
> > >
> > > And in what way does that differ from pointer to classes that conta=
in
> > > just a single char or a single int?
> >
> > The C++ Standard requires that for any class/struct X, X* must have
> > the same size.
>=20
> Ok, to put it yet another way: If the standard doesn't seem to mind to
> restrict classes in that way, why should it mind to restrict enums in
> that way?

By the time C++ was started, C already imposed this restriction for
structs, presumably on the assumption that the benefit of being able
to forward declare a struct was large enough to outweight the cost
(and indeed the benefit of forward declarations for classes is huge).

If we placed the same restriction on pointers to enums, we would
rule out making efficient large arrays of enums and force people
to use chars instead, hence writing worse code.  The gain from
forward declaring an enum is much smaller than that from forward
declaring a class.

I see that Francis Glassborow has mentioned an idea of promoting
the "enum" concept to allow more class-like behaviour.  It might
be worth making FG-enums distinct from the existing enums, and
allowing forward declarations for them.  A better name that
"FG-enum" might also be appropriate.
=20
> > That may restrict alignment for a class containing only a single char.
>=20
> The implementation can always use the equivalent of a void * internally
> to implement pointers-to-enum.

But that costs, and C++ doesn't like us to pay if we don't=20
have to.

-- James Dennett

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Wed, 9 May 2001 02:00:09 GMT
Raw View
"James Kuyper Jr." wrote:
>
> Dennis Yelle wrote:
> ...
> > The real problem is not that stuff.x+2 and stuff.y compare equal.
> > The real problem is that the clear meaning of the text of the
> > standard is that they do NOT compare equal.
> >
> > Some people claim to be able to bend the text of the standard
> > in their minds to the point that it allows stuff.x+2 and stuff.y
> > to compare equal.
> > I am unable to do that.
> > So I think that the text of the standard should be changed.
>
> I could agree with that; after all, the comparable wording in the C
> standard has changed. Section 6.5.9p6 of the C99 standard says: "Two
> pointers compare equal if and only if both are null pointers, both are
> pointers to the same object (including a pointer to an object and a
> subobject at its beginning) or function, both are pointers to one past
> the last element of the same array object, or one is a pointer to one
> past the end of one array object and the other is a pointer to the start
> of a different array object that happens to immediately follow the first
> array object in the address space.91)"

So all we need to do is add another exception for zero-sized objects.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 11:49:47 GMT
Raw View
On Sun,  6 May 2001 04:25:01 GMT, Niklas Matthies <news/comp.std.c++@nmhq=
.net> wrote:
> On Sat,  5 May 2001 12:10:34 GMT, Carl Daniel <carl@pixami.com> wrote:
[=B7=B7=B7]
> > One idea, which interacts with the idea that there be some
> > standard-mandated implementation options: define new keywords in two
> > forms:  a "plain" form, which should be used in all new code and whic=
h
> > can be optionally disabled (by a standard #pragma or whatever) and a
> > "backward compatible" form, which can be optionally enabled.  The
> > backward compatible form would be deprecated upon introduction, but
> > provided to help the transition to the new language.
[=B7=B7=B7]
> The way this is usually done (well, at least how it's done in C) is to
> let the keyword start with underscore and an upper case letter
> ("_Keyword"), which places it in the namespace reserved for the
> implementation, and then in some (new) standard header define:
>=20
>    #define _Keyword keyword /* "plain" form */

Oops, of course this should have been

   #define keyword _Keyword

or if the keyword in all contexts denotes a type, then

   typedef _Keyword keyword;

-- Niklas Matthies

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 11:50:13 GMT
Raw View
On Sun,  6 May 2001 04:25:50 GMT, James Kuyper Jr. <kuyper@wizard.net> wr=
ote:
> Howard Gardner wrote:
> > Valentin Bonnard wrote:
[=B7=B7=B7]
> > > I want students to initialise variables to the right value,
> > > or to assign them the right value before use.
> >=20
> > I wonder if you would disagree with any of these statements:
>=20
> No, but there's one key issue I've got with the dogma that all variable=
s
> should be initialized immediately after declaration: I've found that
> this dogma can often hide problems. Code that is virtually guaranteed t=
o
> go haywire in an easily detectable fashion when the value is random,
> will often produce symptoms that are far more subtle and correspondingl=
y
> hard to detect, if the variable gets initialized with a premature but
> legal value.
>=20
> However, most of my actual experience has been with C90. Both C++ and
> C99 allow declarations intermixed with statements, which significantly
> reduces the need to declare something before it can be given it's true
> value. Unfortunately, I'm working under a standards and guidelines
> document that requires all local variables to be defined at the top of =
a
> function.

Maybe it would make sense to deprecate declarations without explizit
initializiation altogether (so that there is no "default" behaviour),
and introduce a way to explicitly mark declarations as non-initializing.

E.g.
         int i;

becomes deprecated, and one should either write
  =20
         int i =3D uninitialized;     // or maybe   int i =3D ?;
or
         int i =3D <some-integer-value>;

This may have the effect that programmers think more about whether the
object should be initialized or not, and if so, with what value.

-- Niklas Matthies

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 11:51:13 GMT
Raw View
On Sun,  6 May 2001 04:26:09 GMT, Dave Harris <brangdon@cix.co.uk> wrote:
[=B7=B7=B7]
> The main difference is that a pointer to an incomplete class is itself=20
> complete, where-as a pointer to an incomplete enum would probably not b=
e=20
> complete.

Why would it not?

> (Is it intended that we use this monster thread to rehash all the=20
> features requested over the last 3 years?)

Well, unfortunately (?) I wasn't around for the most part of the last 3
years.

-- Niklas Matthies

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 6 May 2001 12:28:28 GMT
Raw View
In article <MPG.155d7756188fa6cb98971e@news.lynchburg.net>,
michael.finney@acm.org wrote:
>> In Unicode 3.1 characters go up to U+10FFFF.
>> 16 bits are not enough.
>
>No, Unicode is explicitly a 16-bit standard. The
>characters above FFFF are part of ISO 10646, and
>correspond in position to characters allocated for the
>Unicode standard outside of the first "plane" of 64k.
>In Unicode they can only be referenced via the
>low+high method requiring two Unicode characters. This
>allows Unicode to reference a million+ characters, but
>still only use 16-bit characters.

My impression of is that there in effect are 16 bit and 32 bit Unicode
characters, plus two encodings UTF-8 and UTF-16 for translating variable 8
and 16 bit characters back and forth to 32 bit characters.

Regardless whether this is described formally so in those standards, for
practical purposes, it appears that the use of 16 wide characters is
already dead, in view that one misses many of the important characters
that way, for example, the math characters.

The thing is that it appears too complicated and to inefficient to use
variable sized characters in the internals of a program.

So the way I see it, one ends up with mainly a type for 32-bit Unicode
characters. Then one needs codecvt for IO on the other formats.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 6 May 2001 12:30:19 GMT
Raw View
In article <9d1gat$ju8$1@uranium.btinternet.com>, "Chris Newton"
<chrisnewton@no.junk.please.btinternet.com> wrote:

>Hans Aberg <remove.haberg@matematik.su.se> wrote...
>> Exceptions are very pleasing, because a program that
>> always throws exceptions cannot break, except for
>> non-termination.
>
>You forgot the other numerous cases of undefined behaviour allowed to a
>C++ programmer by the standard, typically in the interests of efficiency
>and/or because of fundamental flaws in the exception model (e.g.,
>throwing one exception while another remains unhandled).

Not really, a safe PL would throw exceptions in the cases that now are
labelled "undefined behavior". As you say, "undefined behavior" is
something used as "fixing the language in a logically correct way results
inefficient implementations".

>> Therefore, I expect that the exceptions feature will grow
>> stronger as the computers become more powerful, and one
>> learns better how to implement it in the language.
>
>It may grow more efficient. I don't see how it's going to grow
>significantly more "powerful" for any other definition of the word.

As it becomes more efficient, one will find the use of exceptions more
favorable, as it results in safer programs. So it becomes a politically
stronger feature.

>> So rather than looking for ways to merely exclude exceptions,
>> I think one should look for the prudent inclusion of exceptions.
>
>The problem with that is that proving a program is exception-safe is
>about as difficult as proving a program is thread-safe. In real-world
>applications, you'd like your code to be both, but very rarely can you
>justify the investment to prove that such is the case. When you have to
>do so, you must either invest a vast quantity of resources, or simply
>not use the feature concerned.

The reason that is difficult to prove either of exception-safety and
thread-safety is that C++ lacks the appropriate language support, and that
there is lots of old code that violates it.

One task for the new C++ standard I think is a must is to provide the
appropriate language support for those features.

In the case of exceptions, memory leaks can easily be fixed by the use of
a conservative GC. In the case of thread safety, one must have features
such as locks and atomic code.

>The ability to absolutely forbid the use of exceptions (and hence
>disallow dynamic_cast of a reference and such that might generate them)
>would have value in these circumstances, and is, as far as I can see,
>relatively easy to implement for someone writing a C++ implementation.
>The question is, is C++ used widely enough in areas where verification
>matters to justify the effort in doing so?

Again, this is a part of a general C++ structure problem, namely that one
want to add features that will be available on a wide range on platforms,
but on some, it will be unavailable. One such discussion was support for
Unicode 32-characters, that is a hell to implement in code that should
compile under several different compilers, but on some platforms might be
unnecessary.

So there must be some kind of mechanism in the C++ language that allows
such new features to be added to the language in a way that they can be
excluded on some platforms.

As for the exception feature, if one is writing code for a bread machine
with 50 kB of memory today, then exceptions is perhaps merely a bother.
But if memory doubles ever year, then in twenty years, the bread machine
will have 50 GB of memory, and it will be cheaper to give it its own WWW
site then putting in a mechanical interface. So then exceptions will
probably be pretty attractive.

So whatever the general C++ exclusion mechanism is, it must be so that it
is easy to add it when needed.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sun, 6 May 2001 13:20:09 GMT
Raw View
Daniel James wrote:
...
> > Decide what this program should print based on the quote above,
> > and then try it:
> [snip]
>
> >   struct junk {
> >     int x[2];
> >     int y[2];
> >   } stuff;
> >   if ( stuff.x+2 == stuff.y)
> >     cout << "same\n";
> ..
>
> You're actually not allowed to make that comparison, stuff.x+2 and stuff.y
> are pointers to different objects.

Incorrect. You're not allowed to make relational comparisons (<, >, <=,
>=) except for pointers into the same object, but you are allowed to compare arbitrary valid pointers for equality (==, !=).

...
> I agree that on many typical compilers the undefined behaviour will turn out
> to produce the output "same\n", but you can't rely on it.

The point is that the standard says that the pointers can compare equal
if, and ONLY if, they are both NULL, both point to the same object, or
both point one past the end of the same object. Unless you recognize
stuff.x+2 and stuff.y as pointing at the same object (namely y[0]), then
having them compare equal looks like a violation of the standard.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sun, 6 May 2001 13:52:54 GMT
Raw View
In article <slrn9fa76i.6g8.news/comp.std.c++@nightrunner.nmhq.net>,
Niklas Matthies <news/comp.std.c++@nmhq.net> writes
>Maybe it would make sense to deprecate declarations without explizit
>initializiation altogether (so that there is no "default" behaviour),
>and introduce a way to explicitly mark declarations as non-initializing.

You can only provide initialisation for a definition, pure declarations
have no storage to be initialised.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Joseph Gottman" <joegottman@worldnet.att.net>
Date: Sun, 6 May 2001 14:37:54 GMT
Raw View
"Olaf Krzikalla" <Entwicklung@reico.de> wrote in message
news:3AF534EF.44D06F3F@reico.de...
> Hi,
>
> "James Kuyper Jr." wrote:
> > Here's an example. Imagine that you're deep in template code, where a
> > and b are complicated types, which interact in a complicated fashion.
> > For instance, adding them might involve the use of expression templates.
> > Then it can be a great convenience to be able to write:
> >
> >         typeof(a+b) c = a+b;
>
> But still this isn't the thing I really want to get. Why should I write
> the expression twice ?  Why not the (IMHO much better) suggestion to
> overload auto:
>
>          auto c = a+b;
>
>

   This is simpler, but typeof() is more flexible.  For instance, suppose
you want to write a function that adds two polynomials of different types.
You could declare it as

template <class X, class Y>
polynomial<typeof(X() + Y())> operator+(
     const polynomial<X> &f,
     const  polynomial<Y> &g);

I don't think auto as you use it above would help in this case.

Joe Gottman


---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sun, 6 May 2001 15:12:42 GMT
Raw View
Sun,  6 May 2001 11:49:47 GMT, Niklas Matthies <news/comp.std.c++@nmhq.ne=
t> pisze:

> or if the keyword in all contexts denotes a type, then
>=20
>    typedef _Keyword keyword;

For types it's not necessary to use the _Name at all.
Namespace std serves to separate standard names from other names.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sun, 6 May 2001 15:12:12 GMT
Raw View
Howard Gardner wrote:
>
> James Kuyper Jr. wrote:
>
> > No, but there's one key issue I've got with the dogma that all variables
> > should be initialized immediately after declaration: I've found that
> > this dogma can often hide problems.
>
> You have a point.  Detecting bugs is different from reproducing them,
> and fixing them is different yet again.  The second two are definitely
> easier if the program's state is defined: the first might not be.
>
> Would you go so far as to argue that defining the value of an uninitialized
> declaration would increase the cost of hitting an arbitrary reliability
> goal?

Yes, if the initial value is not a correct value, but just a placeholder
used to satisfy that dogma.

> > Unfortunately, I'm working under a standards and guidelines
> > document that requires all local variables to be defined at the top of a
> > function.
>
> Ouch. Since you have a near-worst-case situation: how hard would a change
> like this hit you?

Not hard. That same document also requires me to code in either C90,
Fortran 77, Fortran 90, or ADA. Therefore, no change to the C++ standard
will affect me until I move on to a position that allows me to use C++;
something I'm hoping to do in the not-to-distant future. The problem is
that scientific programming seems to be dominated by C and Fortran; it
looks like I might have to downgrade to commercial programming in order
to get paid for my knowledge of C++. I also can't point to a single
class I've taken or job I've done that uses C++. I'm entirely
self-taught in C++; a fact that might make employers unwilling to pay me
as much as I'm currently getting for my long, well-documented experience
as a C programmer.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sun, 6 May 2001 15:13:20 GMT
Raw View
In article <9d0oqt$o92$1@plutonium.btinternet.com>, Chris Newton
<chrisnewton@no.junk.please.btinternet.com> writes
>I'm sure there are several such people reading. Could you please post
>details of how to get involved in this process (or a link to same)?

In the UK? The simplest and most straightforward is to turn up at panel
meetings. The alternative is to join ACCU (15ukp) and make a voluntary
contribution to its fund for standards support (we suggest at least
20ukp per year, which is a lot less than the cost of travel is to those
that attend meetings in person) and then ask that you get placed on
those reflectors (mailing lists) which interest you.

The ACCU standards' fund is used to support the standards process in
various ways such as funding the charge made to panel convenors (without
which a panel cannot exist)



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Howard Gardner <usenet@hgardner.com>
Date: Sun, 6 May 2001 17:40:12 GMT
Raw View
James Kuyper Jr. wrote:

>> Would you go so far as to argue that defining the value of an uninitialized
>> declaration would increase the cost of hitting an arbitrary reliability
>> goal?
>
> Yes, if the initial value is not a correct value, but just a placeholder
> used to satisfy that dogma.

Oddly enough, all of the examples that I think of tend to support my
point of view.  Can you think of one that supports yours?

I'm not insisting that all variables be initialized, I'm trying to
make two simple points.

1) The current language results in leaving variables uninitialized far
more often than they should be.

2) Leaving variables uninitialized is very expensive.
This debate has been going on for a long time.  Last time that there
seemed a real chance of changing it--in the mid 80's, in regard to
ANSI C--I was a newbie and neutral on the subject.  Now, having used
C since 1982 (and C++ since 1989) for a range of applications
that extends from embedded machine control to globally distributed
information systems, I have an opinion.

My opinion is that it is far too easy to write applications with
undefined state, that it therefore happens far too often, and
that this change would render it fairly rare.

I can count the number of times that I actually needed to leave a
variable uninitialized on my fingers and toes. I shudder to think
of the thousands of hours of my life that have been lost because
someone left a variable uninitialized.

> looks like I might have to downgrade to commercial programming in order
> to get paid for my knowledge of C++.

Aha! There's the problem!  You don't know the difference between up
and down! <grin>

---
[ 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: "Chris Newton" <chrisnewton@no.junk.please.btinternet.com>
Date: Sun, 6 May 2001 18:09:28 GMT
Raw View
Hans Aberg <remove.haberg@matematik.su.se> wrote [abridged]...
> Not really, a safe PL would throw exceptions in the cases
> that now are labelled "undefined behavior".

Perhaps. However, C++ is not a "safe" programming language. As we've
often noted on the C++ newsgroups, you can build something safe on top
of something efficient, but the converse does not necessarily apply. I
don't imagine the standard will ever force C++ to be safe at the expense
of efficiency, and many of us wouldn't want it to. That would go against
the whole language's current ethos, and there are plenty of other
languages that choose the safety-first route if that is what is desired,
Java being an obvious example.

> As [the exceptions feature] becomes more efficient, one will
> find the use of exceptions more favorable, as it results in
> safer programs. So it becomes a politically stronger feature.

I'm not aware of anyone who has yet proven, by any sensible and
objective standard, that exceptions result in safer programs. They may
make it much easier to write certain types of programs, but whether they
bring safety with them is very much a moot point, IMHO.

[Chris Newton wrote...]
> > The problem with that is that proving a program is exception-
> > safe is about as difficult as proving a program is thread-safe.
> > In real-world applications, you'd like your code to be both,
> > but very rarely can you justify the investment to prove that
> > such is the case. When you have to do so, you must either
> > invest a vast quantity of resources, or simply not use the
> > feature concerned.
>
> The reason that is difficult to prove either of exception-safety
> and thread-safety is that C++ lacks the appropriate language
> support, and that there is lots of old code that violates it.

With respect, I totally disagree. The reason that it's hard to prove
exception- and thread-safety is that these features allow exponentially
growing numbers of execution paths. Verifying that each behaves
correctly is therefore exponentially hard. This is true of any language
that provides these features, and in no way unique to C++.

Also, the fact that lots of existing code is not exception- or
thread-safe does not in any way make them easier or harder to prove. It
just means that we know a lot of existing code isn't safe.

> One task for the new C++ standard I think is a must is to
> provide the appropriate language support for those features.
>
> In the case of exceptions, memory leaks can easily be fixed
> by the use of a conservative GC.

What about other resource leaks? Contrary to popular opinion (and the
implications of certain GC advocates), there are more resources used in
the world than just dynamic memory. These must also be released. Some of
them, unlike dynamic memory in a typical scenario, must also be released
*promptly*.

GC is not appropriate in such cases; indeed, the proliferation of
finally{} blocks in some languages supporting exceptions and GC is one
of their biggest flaws. I don't think we'd want to mandate that C++
introduce these flaws, when currently its destruction model completely
avoids them by having predictable destruction semantics!

None of this is to say that facilitating GC implementations shouldn't be
a goal for the new standard, of course. I just like to keep things in
perspective, and suggesting that GC is the cure-all for all the minor
flaws in the exception system seems a little exaggerated to me.

> In the case of thread safety, one must have features
> such as locks and atomic code.

Basic threading support in the standard would no doubt be useful. Then
again, there are many different systems using many different threading
models in the world, and no standard can cater to all of them without
either being unduly restrictive, or outside help. I suspect the key to
including useful threading support is to keep it minimal but extensible,
as has been done with some success for IOstreams and the
container/iterator/algorithm areas of the library. (I also suspect that
the library is very much where threading support belongs, BTW.)

[Snip... Now discussing adding Unicode support, etc.]

> So there must be some kind of mechanism in the C++ language
> that allows such new features to be added to the language in a
> way that they can be excluded on some platforms.

There is, and there always has been: platform-specific libraries,
typically provided by the vendor of a compiler or others interested in
compiling on a specific platform. This is how graphics, communications,
multi-threading, file system manipulation and numerous other common but
fundamentally platform-specific things are done.

The question is, do you make such things standard for *all* C++
implementations *everywhere*, or do you provide a minimal framework on
which to build, and allow de facto standards to emerge where there is a
need, supported by that standard framework? (See, e.g., Dietmar Kuehl's
library of iterators for working with file systems at www.boost.org for
what I mean.)

This seems, to me, to be one of the fundamental questions regarding the
new standard at the moment, but I've yet to see any of the big names
involved suggest a particular stance on the matter.

Regards,
Chris


---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Mon, 7 May 2001 01:30:33 GMT
Raw View
In article <remove.haberg-0605011422470001@du143-
226.ppp.su-anst.tninet.se>,
remove.haberg@matematik.su.se says...
> My impression of is that there in effect are 16 bit and 32 bit Unicode
> characters, plus two encodings UTF-8 and UTF-16 for translating variable 8
> and 16 bit characters back and forth to 32 bit characters.
>
> Regardless whether this is described formally so in those standards, for
> practical purposes, it appears that the use of 16 wide characters is
> already dead, in view that one misses many of the important characters
> that way, for example, the math characters.
>
> The thing is that it appears too complicated and to inefficient to use
> variable sized characters in the internals of a program.
>
> So the way I see it, one ends up with mainly a type for 32-bit Unicode
> characters. Then one needs codecvt for IO on the other formats.

With the advent of Unicode 3.1 (which is recently
released, and I had not reviewed until today) there is
no longer any real difference in code points between
Unicode and ISO 10646.

However, I still advocate both unichar and isochar
because in many cases the 16-bit encoding is all that
is needed and w_char does not guarantee that it is 16
bits or even unsigned.

I do plead that we *not* see an abomination such as
uni_char or iso_char. Please, please stop the
underscores in the middle of keywords!!!

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 7 May 2001 01:32:38 GMT
Raw View
pmenso57@home.com (Paul Mensonides) wrote (abridged):
> : 1) In C++, uninitialized variables are common.
>
> Whose fault is that?  The programmer not the language.  Default
> initialization is just way to encourage bad coding practices.

It is only bad practice because it makes undefined behaviour. In other
languages which give default values (eg Smalltalk, Eiffel), or in C++
where it does that, it is not bad practice. For example:

    const Object *GetObject( int id ) {
        static Object *objects[1000];
        if (objects[id] == 0)
            objects[id] = new Object(id);
        return objects[id];
    }

In my view it is not bad practice to rely on the default initialisation
of static variables. I wouldn't put an explicit initialisation loop in
there.

If the language were changed to guarantee default initialisation in a
more consistent and uniform way, good practice would change accordingly.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 7 May 2001 01:33:23 GMT
Raw View
Allow dynamic_cast on integral types. Eg:

    long big = 100000000L;
    int small = dynamic_cast<int>( big );

This would perform a range-check, and throw an exception if the result
will not fit in the target type. The analogy is with dynamic_cast<derived
&)( base & ).

Alternatively, provide a standard library function to do the same thing
in <limits> - but I think the dynamic_case<> notation is a natural fit,
and consistency might be useful in templates.

This is a convenience feature which will make it easier to write robust
code. C++ has a great many different integral types - bool, short,
unsigned short, int, unsigned int, long, unsigned long, perhaps soon long
long, int64, int32 etc. Conversions between them are fairly common. A
good compiler will complain about possible loss of precision, but how to
resolve the problem? I expect many programmers use a static cast:

    int small = static_cast<int>( big );

or similar and, if we're lucky, they will also think first whether this
is safe. However, the static cast is fragile. The code may break silently
if the program is applied to bigger domain problems.

We should encourage safe, checked conversions. C++ needs a standard
idiom that can be promoted uniformly by all programming courses and
text-books, and used consistently in all software houses and in published
code.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Mon, 7 May 2001 01:35:34 GMT
Raw View
In article <slrn.pl.9fa0a5.90t.qrczak@qrnik.zagroda>,
qrczak@knm.org.pl says...
> Sun,  6 May 2001 04:23:58 GMT, Michael Lee Finney <michael.finney@acm.org=
> > pisze:
>
>
> > No, Unicode is explicitly a 16-bit standard.
>
> No. It used to be, but no longer. It currently encodes 94140 characters
> in the address space of U+0000..U+10FFFF.
>
> > In Unicode they can only be referenced via the=20
> > low+high method requiring two Unicode characters.
>
> No. There are three important encoding forms, not counting Endianness
> variants: UTF-8, UTF-16 and UTF-32. You are describing UTF-16, not
> the Unicode character space.

At the time I wrote the previous post, I had not
reviewed the recently released Unicode 3.1. With that
release, you are correct. ISO 10646 has removed the
private use characters outside of Unicode's range, and
with that removal, UTF-32 is identical to UCS-4 with
the only difference is that UTF-32 impales the Unicode
semantics whereas UCS-4 does not.

However, many if not most, uses of Unicode only need
the 16-bit character, so I would still advocate both
unichar and isochar as originally suggested.

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Mon, 7 May 2001 05:24:13 GMT
Raw View
Niklas Matthies wrote:
[...]
> One implication with that approach is that each time a new version of
> the standard modifies a facility in a way that is not 100% compatible
> with the previous version, you'll have to introduce a new header. So
> we'll soon have to
>
>    #include <algorithm-v2.1>
>
> or something like that. I'm not sure whether this is really something to
> wish for.

Actually, if we do get brave enough to introduce incompatible
changes to <algorithm> I think that would be a very good idea.

In that case  #include <algorithm>  would get the latest version available,
and #include <algorithm_1998> would get the 1998 version.

> Furthermore, this approach doesn't help if a feature of the language
> proper changes, e.g. what has been suggested with regard to virtual
> destructors. Or do you want the compiler to switch such behavior
> depending on whether some standard header has been included, e.g.
>
>    #include <std::auto-virtual-destructors>
>    #include <std::auto-initialize-locals>

I agree that that looks like a bit of a problem,
but I would have to think about the exact details of
the change to be sure.  In the case of the two examples you
give, I would want the new proposed behavior to be the
default, and I would not oppose an #include to get the
old behavior.  Especially if I thought that this would allow
us to please the folks who still want the old behavior enough
to get the change we want.

Once we define  #include <std::1998>  to allow us to
recompile old code, we really have no limits to what we
can do in the future.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: James Dennett <jdennett@acm.org>
Date: Mon, 7 May 2001 05:24:10 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Sun,  6 May 2001 04:26:09 GMT, Dave Harris <brangdon@cix.co.uk> wrot=
e:
> [=B7=B7=B7]
> > The main difference is that a pointer to an incomplete class is itsel=
f
> > complete, where-as a pointer to an incomplete enum would probably not=
 be
> > complete.
>=20
> Why would it not?

char * might be larger than int *, and some enums might be stored
as chars for efficiency while larger enums might use ints.=20

> > (Is it intended that we use this monster thread to rehash all the
> > features requested over the last 3 years?)

If it is just to enumerate them for the record, I don't think
that would be such a bad idea.  Lengthy debate repeating what
has come before is unlikely to be helpful though.

-- James Dennett

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 7 May 2001 05:24:26 GMT
Raw View
In article <3AF579EF.6000509@hgardner.com>, Howard Gardner
<usenet@hgardner.com> writes
>I can count the number of times that I actually needed to leave a
>variable uninitialized on my fingers and toes. I shudder to think
>of the thousands of hours of my life that have been lost because
>someone left a variable uninitialized.

I thought lint detected such fluff.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 7 May 2001 05:24:32 GMT
Raw View
In article <9d43gd$t2v$1@plutonium.btinternet.com>, Chris Newton
<chrisnewton@no.junk.please.btinternet.com> writes
>The question is, do you make such things standard for *all* C++
>implementations *everywhere*, or do you provide a minimal framework on
>which to build, and allow de facto standards to emerge where there is a
>need, supported by that standard framework? (See, e.g., Dietmar Kuehl's
>library of iterators for working with file systems at www.boost.org for
>what I mean.)

Well, one purpose of boost is to test material before incorporating it
in the standard.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 7 May 2001 05:24:40 GMT
Raw View
news/comp.std.c++@nmhq.net (Niklas Matthies) wrote (abridged):
> > The main difference is that a pointer to an incomplete class is
> > itself complete, where-as a pointer to an incomplete enum would
> > probably not be complete.
>
> Why would it not?

Because the size of pointer may depend on the size of the thing it points
to.

Specifically, on some hardware sizeof(char *) > sizeof(int *). This is
because a character pointer is implemented as an integer pointer plus an
offset to select a part of the integer. So we might have:

     enum Small { x = 255 };
     enum Large { y = 255*255 };

     assert( sizeof Small == sizeof char );
     assert( sizeof Large == sizeof int );
     assert( sizeof Small != sizeof Large );

     assert( sizeof (Small *) == sizeof (char *) );
     assert( sizeof (Large *) == sizeof (int *) );
     assert( sizeof (Small *) != sizeof (Large *) );

as a reasonable implementation choice on such a platform. The analogous
situation does not happen with classes, because the standard requires
that sizeof (Class *) is the same regardless of the size of the Class
pointed to.

If we allow enums to be incomplete types, we have a choice. We can either
allow pointers to enums to be incomplete types too, so that the above
implementation would still be OK. Or we can require pointers to
incomplete enums to be complete, in which case the above implementation
would have to change.

It can change in 2 ways. Firstly, so that:

     assert( sizeof Small == sizeof char );
     assert( sizeof (Large *) == sizeof (char *) );

This implies some space overhead for all enum pointers. Or:

     assert( sizeof Small == sizeof int );

This implies some space overhead for all small enums.

Ideally the people who write compilers for these weird architectures
would be consulted about this. Possibly they already use sizeof int for
all enums anyway.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 7 May 2001 05:25:41 GMT
Raw View
Dave Harris wrote:
>
> pmenso57@home.com (Paul Mensonides) wrote (abridged):
> > : 1) In C++, uninitialized variables are common.
> >
> > Whose fault is that?  The programmer not the language.  Default
> > initialization is just way to encourage bad coding practices.
>
> It is only bad practice because it makes undefined behaviour. In other

If you've explicitly initialized a variable with an incorrect value, and
forget to give it a correct value before first use, the behavior is
perfectly well defined, but incorrect. That's what makes it bad
practice.

> languages which give default values (eg Smalltalk, Eiffel), or in C++
> where it does that, it is not bad practice. For example:
>
>     const Object *GetObject( int id ) {
>         static Object *objects[1000];
>         if (objects[id] == 0)
>             objects[id] = new Object(id);
>         return objects[id];
>     }
>
> In my view it is not bad practice to rely on the default initialisation
> of static variables. I wouldn't put an explicit initialisation loop in
> there.

In C++, there'd be no need to. Just add an initializer:
={static_cast<Object*>(NULL)}; That takes care of the first element of
the array, and forces the other elements to be zero-initialized as well.
It's not the greatest syntax; I'd prefer a Fortran-style ability to
explicitly specify a repeat count on an initializer. However, it does
the same thing you want.

In fact, that's precisely why that is a bad example. In this case, the
default initialization happens to create exactly the right set of
initial values for what you want to do. The tricky case is when it's not
possible to know what the right values until later, but you initialize
it anyway with arbitrary values, because there's a dogma that says they
must be initialized at the point of definition. That's where the bad
coding practice comes in.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 7 May 2001 05:25:37 GMT
Raw View
Howard Gardner wrote:
>
> James Kuyper Jr. wrote:
>
> >> Would you go so far as to argue that defining the value of an uninitialized
> >> declaration would increase the cost of hitting an arbitrary reliability
> >> goal?
> >
> > Yes, if the initial value is not a correct value, but just a placeholder
> > used to satisfy that dogma.
>
> Oddly enough, all of the examples that I think of tend to support my
> point of view.  Can you think of one that supports yours?

All I can say is that I've had four nasty bugs pop up after delivery in
the last couple of years, which each took much longer to detect than
they should have, due to premature initialization. None of the premature
initialization occurred in my own code; it occured in the code produced
by the people I supervise. I let them initialize variables prematurely,
because I'm not sufficiently sure of my own position on this issue to
insist that they adopt my coding style.

...
> > looks like I might have to downgrade to commercial programming in order
> > to get paid for my knowledge of C++.
>
> Aha! There's the problem!  You don't know the difference between up
> and down! <grin>

I've been in the commercial sector before; the salaries are higher, but
it's a whole lot less fun. I know which direction is up, at least as far
as I'm concerned.

---
[ 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: Daniel Frey <daniel.frey@aixigo.de>
Date: Mon, 7 May 2001 10:44:45 GMT
Raw View
Olaf Krzikalla wrote:
>=20
> Hi,
>=20
> now I wonder, that I didn't get any reply to a similar suggestion I mad=
e
> here some weeks ago. My intention was a different one, so it seems to b=
e
> useful in many cases. IMHO it's also a question of uniformity: we have
> simple ways to define compiler-generated default-ctors and dtors by
> leaving their bodies blank.
> But by now we haven't the way to do this with assignment and copy-ctor.
>=20
> I would prefer a keyword _after_ the definition. So it's possible to
> write the definition apart from the declaration:
>=20
> class Foo {
>   protected:
>     Foo( const Foo& );
>     Foo& operator=3D( const Foo& );
> };
>=20
> //somewhere else:
> Foo::Foo( const Foo& ) =3D default;
> Foo& Foo::operator=3D( const Foo& ) =3D default;
>=20
> or inlined:
>=20
> > class Foo
> > {
> > protected:
> >    Foo( const Foo& ) =3D default;
> >    Foo& operator=3D( const Foo& ) =3D default;
> > };
>=20
> The syntax bothers me a little: it looks like a declaration, but it's a
> definition. Maybe it could be rewritten:
>=20
> Foo::Foo( const Foo& ) default {}

Well, now it looks like it's part of the declaration too (like 'const').
But you're right that '=3D default' is ugly too. A possible solution (tha=
t
still breaks no existing code) could be to allow a definition like this:

Foo::Foo( const Foo& ) { default; }

Maybe even with additional code before it??

Foo::Foo( const Foo& f )
{
  // Print a debug message
  std::cout << "Foo-default-ctor for " << f.asString();

  default;
}

Also possible:

Foo::Foo( const Foo& f )
{
  if( f.someProperty() )
    default;

  // else it's more complicated:
  ...
}

Just playing with some thoughts...

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 7 May 2001 10:47:25 GMT
Raw View
In article <3AF5C59E.F6F8E36D@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:
>> >> Would you go so far as to argue that defining the value of an
uninitialized
>> >> declaration would increase the cost of hitting an arbitrary reliability
>> >> goal?
>> >
>> > Yes, if the initial value is not a correct value, but just a placeholder
>> > used to satisfy that dogma.
>>
>> Oddly enough, all of the examples that I think of tend to support my
>> point of view.  Can you think of one that supports yours?
>
>All I can say is that I've had four nasty bugs pop up after delivery in
>the last couple of years, which each took much longer to detect than
>they should have, due to premature initialization. None of the premature
>initialization occurred in my own code; it occured in the code produced
>by the people I supervise. I let them initialize variables prematurely,
>because I'm not sufficiently sure of my own position on this issue to
>insist that they adopt my coding style.

Here is an input:

For efficiency reasons, it is not possible to mandate initializations in C++.

However, one can think of supporting debugger tools that can detect the
use of uninitialized values.

In that context, one might need to add some C++ language support: The
debugger will need what functions that are initializers for each type, and
which are modifiers that requires initialized values.

That is entirely static inormation that only the debugger uses, so it will
not slow down any runtime programs when the debugger initialzer checking
is off.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 7 May 2001 10:47:06 GMT
Raw View
In article <9d43gd$t2v$1@plutonium.btinternet.com>, "Chris Newton"
<chrisnewton@no.junk.please.btinternet.com> wrote:
>Hans Aberg <remove.haberg@matematik.su.se> wrote [abridged]...
>> Not really, a safe PL would throw exceptions in the cases
>> that now are labelled "undefined behavior".
>
>Perhaps. However, C++ is not a "safe" programming language. As we've
>often noted on the C++ newsgroups, you can build something safe on top
>of something efficient, but the converse does not necessarily apply.

This is the reason that it is so difficult to build exception safety on
top of C++, because C++, as you say, in the name of efficiency is not a
safe language.

If one should be able to make combine efficiency with safety in C++, given
that they contradict each other, then one way might be to layer the
language: One lower, unsafe, but efficient level, and one higher, safe,
level.

I am not sure exactly how to get by with such a construction, but it might
be something for the embedded people, which then would prefer often to
program in the lower level. -- But in the future, I think that they will
increasingly prefer to make use of the higher safe level.

Also, often the right way is to first write an inefficient but safe
program that actually works, and then go in and optimize. So the
transition between these levels must be smooth.

> I
>don't imagine the standard will ever force C++ to be safe at the expense
>of efficiency, and many of us wouldn't want it to.

As matter stand, it would be too inefficient. But with an upper level
approach, that would surely be possible. But one would not want to loose
the ability to program in the lower level.

>> As [the exceptions feature] becomes more efficient, one will
>> find the use of exceptions more favorable, as it results in
>> safer programs. So it becomes a politically stronger feature.
>
>I'm not aware of anyone who has yet proven, by any sensible and
>objective standard, that exceptions result in safer programs. They may
>make it much easier to write certain types of programs, but whether they
>bring safety with them is very much a moot point, IMHO.

Well, the theory says that such programs cannot fail, so it will that
theoretical fact that pulls the development _in the long run_.

>> The reason that is difficult to prove either of exception-safety
>> and thread-safety is that C++ lacks the appropriate language
>> support, and that there is lots of old code that violates it.
>
>With respect, I totally disagree. The reason that it's hard to prove
>exception- and thread-safety is that these features allow exponentially
>growing numbers of execution paths. Verifying that each behaves
>correctly is therefore exponentially hard. This is true of any language
>that provides these features, and in no way unique to C++.

If the objects are correctly written only each object needs to be checked.
Thus the number of checks only grow linearly.

>> In the case of exceptions, memory leaks can easily be fixed
>> by the use of a conservative GC.
>
>What about other resource leaks? Contrary to popular opinion (and the
>implications of certain GC advocates), there are more resources used in
>the world than just dynamic memory. These must also be released. Some of
>them, unlike dynamic memory in a typical scenario, must also be released
>*promptly*.

When an exception is thrown, the program jumps to a new point, and the
objects in between the two points needs to be killed off. This can be done
either in the exception stack unwinding by the use of automatic objects,
or by the _conservative_ GC method that traces the live objects and then
kills them off.

You can kill off any resource by the use a suitable combination of these
methods.

>GC is not appropriate in such cases; indeed, the proliferation of
>finally{} blocks in some languages supporting exceptions and GC is one
>of their biggest flaws.

One reason for making use of a conservative GC is that there are resources
that cannot be killed off otherwise. This happens if the user of the
program is allowed to create circular structures, for example.

Conservative GC's can be combined with C++ style ~T() GC.

> I don't think we'd want to mandate that C++
>introduce these flaws, when currently its destruction model completely
>avoids them by having predictable destruction semantics!
>
>None of this is to say that facilitating GC implementations shouldn't be
>a goal for the new standard, of course. I just like to keep things in
>perspective, and suggesting that GC is the cure-all for all the minor
>flaws in the exception system seems a little exaggerated to me.

I think that the first task for C++ is to introduce the features needed in
order to write conservative GC libraries. This is very far of mandating
the use of a conservative GC in the C++ language, which I do not think is
even up to consideration.

>> So there must be some kind of mechanism in the C++ language
>> that allows such new features to be added to the language in a
>> way that they can be excluded on some platforms.
>
>There is, and there always has been: platform-specific libraries,
>typically provided by the vendor of a compiler or others interested in
>compiling on a specific platform. This is how graphics, communications,
>multi-threading, file system manipulation and numerous other common but
>fundamentally platform-specific things are done.

Well, that is not a mechanism of the C++ language standard, but add ons to
the compiler implementations.

>The question is, do you make such things standard for *all* C++
>implementations *everywhere*, or do you provide a minimal framework on
>which to build, and allow de facto standards to emerge where there is a
>need, supported by that standard framework?
>
>This seems, to me, to be one of the fundamental questions regarding the
>new standard at the moment, but I've yet to see any of the big names
>involved suggest a particular stance on the matter.

Well, this is what I said: In order to move forward, it appears that it
must be possible to add new feature to the C++ language that can be
excluded on some platforms. The C++ standard must then specify in which
cases such exclusions are allowed, and who such exclusions are made.

One example is threading: Some OS's do not support that. Then one would
expect that a program that does not make use of threading should compile
on such a platform. On the other hand, one should be able to write a
program so that it is thread safe on platforms with threads, but still
compiles where threads are not supported.

Another case is the use of a console as a standard output: Most computers
now use a graphical window, and could support more advanced IO. It seems
reasonable to have such an enhancement in the C++ standard.

A simple approach would be to merely introduce macros for the C++ language
features not supported. But perhaps one can look for something more
sophisticated.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 7 May 2001 11:23:25 GMT
Raw View
In article <MPG.155fb3aea10d17989723@news.lynchburg.net>,
michael.finney@acm.org wrote:
>> So the way I see it, one ends up with mainly a type for 32-bit Unicode
>> characters. Then one needs codecvt for IO on the other formats.
>
>With the advent of Unicode 3.1 (which is recently
>released, and I had not reviewed until today) there is
>no longer any real difference in code points between
>Unicode and ISO 10646.
>
>However, I still advocate both unichar and isochar
>because in many cases the 16-bit encoding is all that
>is needed and w_char does not guarantee that it is 16
>bits or even unsigned.

There was a long discussion about this recently, and as you say, the
w_char is pretty useless if one wants to _ensure_ that one writes for this
or another Unicode standard.

So this calls for at least one 32-bit Unicode character type,

>I do plead that we *not* see an abomination such as
>uni_char or iso_char. Please, please stop the
>underscores in the middle of keywords!!!

whatever now you would want to call it. (Why not calling the 32-bit
Unicode type simply uchar).

>However, I still advocate both unichar and isochar
>because in many cases the 16-bit encoding is all that
>is needed

The only reason one would want to use a 16-bit type internally in the
program is that is for some efficiency reason, either space or time. With
a 16-bit type, one can still create a full 2^16 table, but it is unlikely
that one might construct a full 2^32 table (one should perhaps adding some
library table compression algorithms).

But apart for such reasons, it seems me that the use of a 16-bit type will
just be a bother. (But a codecvt would enable one to read and write such
types.)

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Sat, 5 May 2001 12:08:30 GMT
Raw View
Dennis Yelle  wrote:
> Niklas Matthies wrote:

>> Currently the Standard says: "Two pointers of the same type compare
>> equal if and only if they are both null, both point to the same object
>> or function, or both point one past the end of the same array". You mean
>> you would want to break this property?

No, he won't break it.

> It is already broken.

No, it is not.

Addresses do, and will always (even in D++ (= Dennis C++))
uniquely identify object identity. No one proposes to break
that. No one _knows_ how to break that.

  -- VB

---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Sat, 5 May 2001 12:09:19 GMT
Raw View
Howard Gardner  wrote:

> I bet instructors would like to get rid of the whole topic too, for that matter.

Then you loose.

As an instructor, I only want to get rid variables that don't
have the right value at the right moment. A programming language
knows nothing about what's the right value, and can't help here.

I want students to initialise variables to the right value,
or to assign them the right value before use.

I don't want them to initialise a variable to a given value
unless this value is the right one, and the iniatialisation
serves some purpose.

Students who initialise all pointers to NULL for safety
won't get a high mark with me. People (not just student)
must understand why things need to be done, and learn to
do things on purpose rather than to apply a general rule.

I want to get rid of things done ``just in case''.

  -- VB, and, before I forget, I also want to get rid
         of students

---
[ 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: "Carl Daniel" <carl@pixami.com>
Date: Sat, 5 May 2001 12:10:34 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AEF1353.87673842@jps.net...
> So, what do we want?
>
> Let's start a list:
>

One other thing I left off my other list...

New keywords!  I don't know what they are, but I think the language definers
should be able to add keywords without fear of loss of backwards
compatibility.

One idea, which interacts with the idea that there be some standard-mandated
implementation options: define new keywords in two forms:  a "plain" form,
which should be used in all new code and which can be optionally disabled
(by a standard #pragma or whatever) and a "backward compatible" form, which
can be optionally enabled.  The backward compatible form would be deprecated
upon introduction, but provided to help the transition to the new language.

e.g.   abstract  -  "plain" form
        __abstract - "backward compatible" form

I just think it's high time that we allow the language to evolve without
a-priori dismissing all English language words as candidates for new
keywords simply becuase they might break some existing code - as others have
pointed out, most programmers have access to high-powered editing tools that
would enable one to rename something which collided with a new keyword in a
very short time - even on a project with 100's or 1000's of source files.

-cd



---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Sat, 5 May 2001 12:11:08 GMT
Raw View
Anthony Williams wrote:
[...]
> * enable non-const references to temporaries

Do you mean all the time?
Or just in some specific situations?

I think the current rule is intended to
protect us from things like this:

  int get_num() { return 3; }

  void increment( int& i) { ++i; }
  //...
  increment( get_num());  // Error!

Would you like to make the above legal?

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 5 May 2001 12:12:32 GMT
Raw View
Peter Dimov wrote:
>
> >===== Original Message From Christopher Eltschka
> <celtschk@dollywood.itp.tuwien.ac.at> =====
> >LR wrote:
> >>
> >> Radoslav Getov wrote:
> >>
> >> > - did I mention 'typeof'?
> >>
> >> Yes.  What do you think that typeof should return?
> >
> >Nothing, because it's not a function.
>
> ... but an operator.

Do you have any particular reason for saying that it should be an
operator? What would it operate on? It's intended to be a type-name, not
an operator.  A large part of what how it's intended to be used would be
covered by making the following modification to 7.1.5.2p1:

 _type-name:_
  _class-name_
  _enum-name_
  _typedef-name_
  typeof ( _expression_ )


> >What does int return?
>
> Nothing, because it's not an operator. :-)
>
> >If you think "higher order", typeof returns a type.
>
> That much is obvious, but which type?

The type of the expression that it takes as an argument. If that type is
ambiguous, the expression is ill-formed, and therefore so is the
typeof().

---
[ 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: "Matt Seitz" <mseitz@yahoo.com>
Date: Sat, 5 May 2001 12:12:47 GMT
Raw View
One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is Dr.
Stroustrup's insistence that new features must be shown to give significant
improvements in an actual project before being added to the language.  This
often took the form of taking an existing project and showing how it could
be significantly improved by adding the new feature.   I would be interested
in reading of anyone performing a similar analysis regarding these
suggestions.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sat, 5 May 2001 12:13:37 GMT
Raw View
In article <slrn.pl.9f4c89.nk7.qrczak@qrnik.zagroda>, "Marcin 'Qrczak'
Kowalczyk" <qrczak@knm.org.pl> wrote:
>Thu,  3 May 2001 20:37:17 GMT, Hans Aberg <remove.haberg@matematik.su.se>=
> pisze:
>
>> Exceptions are very pleasing, because a program that always throws
>> exceptions cannot break, except for non-termination.
>
>I'm not sure what do you mean by this, but
>http://cseng.awl.com/book/related/0,3833,020163371X+11,00.html
>shows that exceptions are not as safe as they might seem.

All I mean is that from the theoretical point of view a program that
systematically throws exceptions never break. So one gets a
computationally closed universe.

That it is difficult to implement exceptions in practise with respect to
various code practises, that is a different matter.

But it means, I figue, that as one learns how to implement and use
exceptions properly, the code will eventually become safer with a less
effort.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Sai Shankar <Sai.Shankar@blr.spcnl.co.in>
Date: Sat, 5 May 2001 12:15:25 GMT
Raw View
James Dennett wrote:
> > >>> For the love of humanity, define the value of a "default" constructed builtin!
> > >>
> > >> If the Standard mandates safety, efficiency will be impossible.
> > >
> > > I'm not even sure, if what you would get is safety. If you've
> > > forgotten to initialize variables, why would zero be the _safe_
> > > choice?
> >
> > It doesn't make the program correct (unless 0 really was the
> > right value), it makes the resulting disaster easier to reproduce.
> > That, in turn, makes the error easier to find.
>
> I agree with that.
>
> >
> > I can't count the hours I've spent tracking down uninitialized
> > variable bugs (sometimes even my own) of one form or another.
>
> I spent several hours a couple of weeks ago tracking down an
> uninitialized pointer bug in some third-party code.  A waste
> of time, but it probably would have been no easier (maybe
> even less easy) if the pointer value was 0 rather than garbage.

As a nice side effect, it would tend to make implementations on some
OSs more conforming. I'm thinking here about OSs that do over-eager
memory  allocation and allocate memory even when enough is not
available. Under current implementations, this causes new to break,
because no error is reported when you try to allocate memory over
what the system currently has available.

If the implementation were to try to (zero) initialize the
allocated memory, the OS would be forced to report the memory
allocation failure immediately and the implementation would become
conforming.

Regards
Sai Shankar

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Sat, 5 May 2001 12:15:55 GMT
Raw View
Greg Brewer wrote:
[...]
> Such a feature would also help with future changes to the language.  Very
> time a new keyword is added to the language, some code somewhere is likely
> going to be broken.  Take for example the typeof operator a lot of us
> desire.  If code written today tells the compiler that the code was written
> to todays standard and it uses typeof as a variable, tomorrows compiler
> would be able to accept the use of typeof as a variable.
>
> Greg Brewer

Actually, we already have a mechanism to do that.
It is called #include.

When typeof, or any new keyword, is introduced, it could
be introduced as _Typeof in the compiler proper, and then
  #include <typeof>
could just do the equivalent of
  #define typeof _Typeof

This technique can be used to silence those who always
react to any suggestion of adding a new keyword by
saying "No!!  That will break existing programs!!"

Another advantage of this is that if a compiler does
not implement some feature, it will fail cleanly on the
#include line instead of producing many confusing error messages.

Remember that system includes are allowed to contain
arbitrary amounts of magic.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sat, 5 May 2001 13:19:03 GMT
Raw View
On Sat,  5 May 2001 12:05:54 GMT, Dave Harris <brangdon@cix.co.uk> wrote:
> Allow enums to be forward-declared. Eg:
>
>     enum Color;
>
>     Color proc( Color arg );
>
>     enum Color { Red, Green, Blue };
>
> Semantics would be analogous to forward declared classes. The advantage
> is better dependency management; it avoids having to #include the header
> which defines the enum.
>
> Also it simplifies the language. Newcomers naturally expect enums to be
> forward-declarable. "Why can't I do this?" is a common question in the
> newsgroups, with no good answer.

But a forward-declared enum would have to be an incomplete type, because
its size depends (or can depend) on the actual enumerators. This would
severly restrict the use of an only-forward-declared enum type.

-- Niklas Matthies

---
[ 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: "Wilka" <wilka@ritualistic.com>
Date: Sat, 5 May 2001 15:47:41 GMT
Raw View
> But a forward-declared enum would have to be an incomplete type, because
> its size depends (or can depend) on the actual enumerators. This would
> severly restrict the use of an only-forward-declared enum type.
>

This is already true for a forward declared class, I don't see why an enum
would be any trouble. I'd also like to be able to forward declare nested
types. e.g.

class some_class;
class some_class::inner_class;
enum some_class::an_enum;

---
[ 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: Howard Gardner <usenet@hgardner.com>
Date: Sat, 5 May 2001 15:48:43 GMT
Raw View
Valentin Bonnard wrote:

> Howard Gardner  wrote:
>
>> I bet instructors would like to get rid of the whole topic too, for that matter.
>

> I want students to initialise variables to the right value,
> or to assign them the right value before use.

I wonder if you would disagree with any of these statements:

1) In C++, uninitialized variables are common.

2) Uninitialized variables often are not discovered until a program is run on a machine other than the OP's.
3) Bugs are much harder to correct in large code bases than they are in small code bases.
4) Code bases tend to grow in time.
5) Code is usually run on the OP's machine much earlier than it is run on other machines

6) Uninitialized variables often result in bugs that are difficult to reproduce.
7) It is relatively difficult to correct bugs that are difficult to reproduce.

8) Bugs that are both difficult to reproduce and hiding in large code bases can be extremely difficult to correct.

9) In most circumstances, an uninitialized variable is an error that will result in a bug.
10) It is possible to change the syntax of C++ so that naive variable declarations result in initialized variables, statements which currently initialize variables are not affected, and it is possible to create uninitialized variables when necessary.

Making the kind of change mentioned in statement 10 would save enormous amounts of time.

I have yet to see anyone attempt to make the case that the miniscule boost in efficiency resulting from having a naive variable declaration result in an uninitialized state is worth all of the pain that it brings.

---
[ 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: "glancaster" <glancaster@ntlworld.com>
Date: Sat, 5 May 2001 15:49:44 GMT
Raw View
Johan Ericsson:
> > >Currently, a public base class is practically required to have a
virtual
> > >destructor (even if empty). These classes with empty destructors do
have
> > >proper compiler generated copy-ctors and assignment operators. Are we
> > >going
> > >to start distinguishing between empty and non-empty destructors?

Francis Glassborow:
> > But he is also proposing that virtual default dtors be provided for any
> > class with a virtual member so it would no longer be necessary to write
> > and empty dtor.
> >

Carl Daniel:
> I, for one, would hate to see such a change to the language - I suspect
that
> it would silently break a lot of code (which is overtly or covertly
> dependent on vtable layout).

Although it would be nice to avoid breaking code that relies on undefined
behaviour, it is almost inevitable that some will be broken by a new C++.

> Windows compilers would be virtually required
> to provide an option to suppress that behavior as it breaks COM.

^^^^^^^^^^^^^^^^^^^^^^
Not if C++0x COM-compliant compilers ("COMpilers"?) implement vtables like
this:

            dtor ptr
vptr -> first "real" member fn ptr
           second "real" member fn ptr
           third "real" member fn ptr
            ...

I have an idea that this "trick" is already in use to support RTTI on some
compilers.

A better reason for objecting to this proposal is that it goes against the
"you don't pay for what you don't use" ethos that has always influenced C++,
but then RTTI does this already (at least in one common, sane,
implementation). On the compilers I use the cost of the proposal would be 4
bytes per each class with virtual functions *that didn't already need a
virtual dtor*. I'm not prepared to argue against it on that basis, though
others might be.

Regards

Garry Lancaster
Codemill Ltd
mailto: glancaster@*nospamplease*codemill.net
Visit our web site at http://www.codemill.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.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 5 May 2001 23:23:46 GMT
Raw View
In article <9culno$cfi@dispatch.concentric.net>, Carl Daniel
<carl@pixami.com> writes
>for one, would hate to see such a change to the language - I suspect that
>it would silently break a lot of code (which is overtly or covertly
>dependent on vtable layout).

Please post some well formed code that would be broken by this.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Chris Newton" <chrisnewton@no.junk.please.btinternet.com>
Date: Sat, 5 May 2001 23:24:48 GMT
Raw View
Hans Aberg <remove.haberg@matematik.su.se> wrote...
> Exceptions are very pleasing, because a program that
> always throws exceptions cannot break, except for
> non-termination.

You forgot the other numerous cases of undefined behaviour allowed to a
C++ programmer by the standard, typically in the interests of efficiency
and/or because of fundamental flaws in the exception model (e.g.,
throwing one exception while another remains unhandled).

> Therefore, I expect that the exceptions feature will grow
> stronger as the computers become more powerful, and one
> learns better how to implement it in the language.

It may grow more efficient. I don't see how it's going to grow
significantly more "powerful" for any other definition of the word.

> This will also be true for programs that now require small code.

But again, that's talking about efficiency, not any power of expression
or range of applicability.

> So rather than looking for ways to merely exclude exceptions,
> I think one should look for the prudent inclusion of exceptions.

The problem with that is that proving a program is exception-safe is
about as difficult as proving a program is thread-safe. In real-world
applications, you'd like your code to be both, but very rarely can you
justify the investment to prove that such is the case. When you have to
do so, you must either invest a vast quantity of resources, or simply
not use the feature concerned.

The ability to absolutely forbid the use of exceptions (and hence
disallow dynamic_cast of a reference and such that might generate them)
would have value in these circumstances, and is, as far as I can see,
relatively easy to implement for someone writing a C++ implementation.
The question is, is C++ used widely enough in areas where verification
matters to justify the effort in doing so?

Cheers,
Chris


---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 5 May 2001 23:25:08 GMT
Raw View
In article <w2EI6.142$BH6.22342@newsread1.prod.itd.earthlink.net>, Matt
Seitz <mseitz@yahoo.com> writes
>One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is Dr.
>Stroustrup's insistence that new features must be shown to give significant
>improvements in an actual project before being added to the language.  This
>often took the form of taking an existing project and showing how it could
>be significantly improved by adding the new feature.   I would be interested
>in reading of anyone performing a similar analysis regarding these
>suggestions.


Have no fear, suggestions will be rigorously analysed
for benefit versus cost but the time for that is a little later. For now
I would like to see the brain storming rules applied -- anything goes
and people must not be overtly negative about other peoples suggestions.
When we have a stack of suggestions, then will be the time to winnow thw
wheat from the chaff.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Pete Becker <petebecker@acm.org>
Date: Sun, 6 May 2001 00:50:26 GMT
Raw View
Chris Newton wrote:
>
> Hans Aberg <remove.haberg@matematik.su.se> wrote...
> > Exceptions are very pleasing, because a program that
> > always throws exceptions cannot break, except for
> > non-termination.
>
> You forgot the other numerous cases of undefined behaviour allowed to a
> C++ programmer by the standard,

"Allowed to the compiler" would be more accurate. Programmers have no
business writing code whose effects depend on behavior that is not
defined by the standard.

> typically in the interests of efficiency
> and/or because of fundamental flaws in the exception model (e.g.,
> throwing one exception while another remains unhandled).

The behavior in that case is not undefined. Exception handling is
abandoned by a call to terminate().

> The problem with that is that proving a program is exception-safe is
> about as difficult as proving a program is thread-safe.

That simply isn't true. An exception can only occur as the result of an
explicit throw, so the points where an exception can occur can be
directly determined by a simple text search in the source code.

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.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                ]





Author: "Paul Mensonides" <pmenso57@home.com>
Date: Sun, 6 May 2001 00:52:48 GMT
Raw View
"Valentin Bonnard" <Valentin.Bonnard@free.fr> wrote in message
news:9cuhtu$267s$9@nef.ens.fr...
: Dennis Yelle  wrote:
: > Andrei Alexandrescu wrote:
:
: >> Imagine C++ had a keyword
: >> 'uninitialized' that you could use like so:
: >>
: >> void Fun()
: >> {
: >>     int i = uninitialized;
: >>     int j; // initialized with zero
: >>     ...
: >> }
: >>
: >> There are multiple advantages to this approach - defaults to safe, and
: >> allows you to optimize when you need.
: >
: > Yes, I think you are right.
: > It is time to do this.
:
: Since when ? This morning ? This month ? This year ?
:
:   -- VB

I agree with you Mr. Bonnard, the people want to make C++ into a Java or VB
(excuse the acronym), instead of a the low-level capable language that it is.

Paul Mensonides

: ---
: [ 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                ]
:

---
[ 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: "Paul Mensonides" <pmenso57@home.com>
Date: Sun, 6 May 2001 00:52:31 GMT
Raw View
"Howard Gardner" <usenet@hgardner.com> wrote in message
news:3AF40516.8020601@hgardner.com...
: Valentin Bonnard wrote:
:
: > Howard Gardner  wrote:
: >
: >> I bet instructors would like to get rid of the whole topic too, for that
matter.
: >
:
: > I want students to initialise variables to the right value,
: > or to assign them the right value before use.
:
: I wonder if you would disagree with any of these statements:
:
: 1) In C++, uninitialized variables are common.

Whose fault is that?  The programmer not the language.  Default initialization
is just way to encourage bad coding practices.  Look at the amazingly difficult
difference:

int x;
int x = 0;

Why is this too difficult?

Maybe a better idea would be allowing inline initialization of built-in types:

class X {
    public:
        int m_x = 0;
        int m_y = 10;
};

Which is optional of course, and can be overridden by a constructor:

X::X(int x, int y) : m_x(x), m_y(y) {
    return;
}

: 2) Uninitialized variables often are not discovered until a program is run on
a machine other than the OP's.

Once again, bad programming habits.

: 3) Bugs are much harder to correct in large code bases than they are in small
code bases.

And code that is well written minimizes bugs and makes finding them easier.

: 4) Code bases tend to grow in time.
: 5) Code is usually run on the OP's machine much earlier than it is run on
other machines
:
: 6) Uninitialized variables often result in bugs that are difficult to
reproduce.

Then:  Initialize your variables when it is necessary.

: 7) It is relatively difficult to correct bugs that are difficult to reproduce.

Only if the code was lazily written (as a result of un-initialized variables)

: 8) Bugs that are both difficult to reproduce and hiding in large code bases
can be extremely difficult to correct.
:
: 9) In most circumstances, an uninitialized variable is an error that will
result in a bug.

This is not true at all.  Many, many times an uninitialized variable is used to
hold 'extra' retvals from a function call:

bool populateTheseVars(int& x, int& y) {
    if (/* can't get resource */) return false;
    x = 10;
    y = 10;
    return true;
}

void f() {
    int x, y; // not initialized
    if (populateTheseVars(x, y)) {
        // use x, y
    }
    return;
}

This 'type' of situation is common.

: 10) It is possible to change the syntax of C++ so that naive variable
declarations result in initialized variables, statements which currently
initialize variables are not affected, and it is possible to create
uninitialized variables when necessary.
:
: Making the kind of change mentioned in statement 10 would save enormous
amounts of time.

It takes me approximately 1/4 sec. (or less) to write the extra " = 0" .
You could even save more time by typing this: int x=0; // with no spaces!

: I have yet to see anyone attempt to make the case that the miniscule boost in
efficiency resulting from having a naive variable declaration result in an
uninitialized state is worth all of the pain that it brings.

The point of C++ is not to coddle the programmer.  The *primary* tenant of C++
is "you don't pay for what you don't use."

miniscule?

class X {
    private:
        int m_x[1000000];
    public:
        X(const X& x) {
            // note: at this point, m_x has already be thoroughly initialized to
0
            for (int i = 0; i < 1000000; ++i) {
                m_x[i] = x.m_x[i];
            }
            return;
        }
        X(int xc, int[] x) {
            // note: at this point, m_x has already be thoroughly initialized to
0
            if (xc > 1000000) {
                for (int i = 0; i < 1000000; ++i) {
                    m_x[i] = x.m_x[i];
                }
            }
            else {
                for (int i = 0; i < xc; ++i) {
                    m_x[i] = x[i];
                }
            }
            return;
        }
};

How can you say this is *always* miniscule?  Granted, this is somewhat contrived
example, but similar situations exist.
This may not be all that significant on a typical desktop, but these operations
are typically compounded:

    template<class T, int U> class MyVector {
        private:
            T m_t[U];
        public:
            MyVector(const MyVector& x) {
                for (int i = 0; i < U; ++i) {
                    m_t[i] = x.m_t[i];
                }
                return;
            }
            MyVector(void) {
                return;
            }
    };

    MyVector<MyVector<int> > m_vecVecInt;

Obviously, this compounds the 'little' performance overhead.  And this is a
small example.  What about this:

    class X2 {
        private:
            MyVector<MyVector<int> > m_vec1;
            MyVector<MyVector<int> > m_vec2;
    };

    // then some other person does this:

    class X2_Cont {
        private:
            MyVector<X2> m_x2_vec;
    };

Unitialized variables that should have been are the fault of bad programming
habits, not the language.  A pragma to turn this on or off would be even more of
a porting nightmare:

#pragma default_init(push -1)

// 100,000 lines of lazy programming without var initializations

#pragma default_init(pop)

This code is then ported to some other implementation which (suprise, suprise)
doesn't support this pragma.  All this other implementation supports is
default_init().  Now you have a *real* problem.

Paul Mensonides

:
: ---
: [ 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                ]
:

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Sun, 6 May 2001 00:53:36 GMT
Raw View
Francis Glassborow wrote:
>
> In article <w2EI6.142$BH6.22342@newsread1.prod.itd.earthlink.net>, Matt
> Seitz <mseitz@yahoo.com> writes
> >One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is Dr.
> >Stroustrup's insistence that new features must be shown to give significant
> >improvements in an actual project before being added to the language.  This
> >often took the form of taking an existing project and showing how it could
> >be significantly improved by adding the new feature.   I would be interested
> >in reading of anyone performing a similar analysis regarding these
> >suggestions.
>
> Have no fear, suggestions will be rigorously analysed
> for benefit versus cost but the time for that is a little later. For now
> I would like to see the brain storming rules applied -- anything goes
> and people must not be overtly negative about other peoples suggestions.
> When we have a stack of suggestions, then will be the time to winnow thw
> wheat from the chaff.

Well, OK, you asked for it:

1. Compile time if, while, and for.
   Yes, I know we already have this, but it is hidden inside
   the template instantiation engine, and does not have pleasing
   syntax.  I propose If, While, and For, and _If, _While, and _For.
   I also propose _Compilable and Compilable.
   The _ versions would always be available, and the others
   would be activated with
      #include <compile_time_conditionals>

   Example use:

      _If ( _Compilable({ return a.b; }) {
         return a.b;
      } else {
         return a.b();
      }

   This also requires that syntax checking be relaxed inside blocks
   skipped by _If.  All I think you need to do inside skipped blocks is
   match up things like ', ", (, ), {, and }.

2. A reference counted pointer that can be used in standard containers.

3. A way to specify that a standard container owns the things
   that it points to, and will delete them when the container
   is cleared or destructed.

4. Clarification that non-owning containers can contain pointers
   to deleted objects.

5. integers and unsigned integers of any size I want up to
   at least 32000 bits:
   int<5> i;  // a 5 bit int
   int<128> j; // a 128 bit int
   unsigned<1024> k; // a 1024 bit unsigned int

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Sun, 6 May 2001 04:23:56 GMT
Raw View
In article <3AF2BECF.F5328CFA@aixigo.de>,
daniel.frey@aixigo.de says...
> > On Fri,  4 May 2001 02:12:19 GMT, Michael Lee Finney
> > <michael.finney@acm.org> wrote:
> >=20
> > >   label: while (exp)
> > >      {
> > >      // some code
> > >      continue label;
> > >      // some code
> > >      break label;
> > >      }
>
> Good, but the label should better be a 'named' loop like:
>
> while label() { ...  break label; };

I don't like that because I think that the label
should precede the control structure keyword. However,
there are other alternatives as well. For example...

   label::while (...)
   while::label (...)
   while.label (...)

The first of these is interesting because it builds on
the idea of "scope". The corresponding break and
continue would then be...

   label::break
   label::continue

to "qualify" the use of break and continue. The last
idea is interesting in that . could be considered to
introduce an "attribute" of the control structure.

There are several alternative syntax approaches, and
other than explicitly rejecting the numerical approach
as suggested by another poster, almost any of them
would do reasonably well. If adopted, the winner would
probably be selected more on the basis of political
merit than technical merit. The approach I first
suggested

   label: while (exp)

has the advantage that the only change to the syntax
is in the break and continue statements which
minimizes the possible effects on compilation. The
only other issues are semantic and reasonably trivial.
The fact that the label can still be explicitly used
as a target for a goto is consistent with the way that
the switch statement is implemented.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Sun, 6 May 2001 04:23:58 GMT
Raw View
In article <slrn.pl.9f569o.qae.qrczak@qrnik.zagroda>,
qrczak@knm.org.pl says...
> Fri,  4 May 2001 10:35:54 GMT, Michael Lee Finney <michael.finney@acm.org=
> > pisze:
>
> > I also want two new primtive types: "unichar" and=20
> > "isochar" where unichar is unsigned and at least 16=20
> > bits and where isochar may be signed or unsigned, but=20
> > must be able to represent 31 bits of positive value.=20
> > In practice, a unichar would normally be exactly 16=20
> > bits and an isochar would be either signed or unsigned=20
> > and 32 bits.

> In Unicode 3.1 characters go up to U+10FFFF.
> 16 bits are not enough.

No, Unicode is explicitly a 16-bit standard. The
characters above FFFF are part of ISO 10646, and
correspond in position to characters allocated for the
Unicode standard outside of the first "plane" of 64k.
In Unicode they can only be referenced via the
low+high method requiring two Unicode characters. This
allows Unicode to reference a million+ characters, but
still only use 16-bit characters.

Of course, that is why I also want isochar as a
primitive type, so that if I need characters outside
of the first plane, I can reference them directly.

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Sun, 6 May 2001 04:24:05 GMT
Raw View
In article <slrn.pl.9f68b5.i9s.qrczak@qrnik.zagroda>, "Marcin 'Qrczak'
Kowalczyk" <qrczak@knm.org.pl> wrote:
>> http://cseng.awl.com/book/related/0,3833,020163371X+11,00.html
>> shows that exceptions are not as safe as they might seem.
>
>Sorry, this link appears to be dead and I can't find the
>contents anywhere with Google or Altavista. I've put it in
><http://qrczak.ids.net.pl/exceptions.html>.

This article discusses the problem with memory leaks in the context of C++
exceptions. There are two simple ways to avoid such memory leaks:

The first is to make use of a conservative GC: At GC time, it will trace
the valid pointers from the root set, removing the other objects.

It is really a must for the next C++ version to support the features
needed for the implmentation of conservative GC's.

And one can wrap up the memory management into classes, so they become
"smart pointers". Then the exception stack unwinding will de-allocate any
allocated memory.

The overhead generated by such techniques require faster computers, but
that will surely happen in the future as well.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Chris Newton" <chrisnewton@no.junk.please.btinternet.com>
Date: Sun, 6 May 2001 04:24:18 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote...
> I cannot speak for other countries, but within the UK we
> try to run an open system and have (through the
> auspices of ACCU) mechanisms for including anyone
> with sufficient interest into electronic consultation/
> contribution.

I'm sure there are several such people reading. Could you please post
details of how to get involved in this process (or a link to same)?

Thanks,
Chris


---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 04:24:28 GMT
Raw View
On Sat,  5 May 2001 12:15:55 GMT, Dennis Yelle <dennis51@jps.net> wrote:
> Greg Brewer wrote:
> [...]
> > Such a feature would also help with future changes to the language.  Very
> > time a new keyword is added to the language, some code somewhere is likely
> > going to be broken.  Take for example the typeof operator a lot of us
> > desire.  If code written today tells the compiler that the code was written
> > to todays standard and it uses typeof as a variable, tomorrows compiler
> > would be able to accept the use of typeof as a variable.
> >
> > Greg Brewer
>
> Actually, we already have a mechanism to do that.
> It is called #include.
>
> When typeof, or any new keyword, is introduced, it could
> be introduced as _Typeof in the compiler proper, and then
>   #include <typeof>
> could just do the equivalent of
>   #define typeof _Typeof
>
> This technique can be used to silence those who always
> react to any suggestion of adding a new keyword by
> saying "No!!  That will break existing programs!!"
>
> Another advantage of this is that if a compiler does
> not implement some feature, it will fail cleanly on the
> #include line instead of producing many confusing error messages.

One implication with that approach is that each time a new version of
the standard modifies a facility in a way that is not 100% compatible
with the previous version, you'll have to introduce a new header. So
we'll soon have to

   #include <algorithm-v2.1>

or something like that. I'm not sure whether this is really something to
wish for.

Furthermore, this approach doesn't help if a feature of the language
proper changes, e.g. what has been suggested with regard to virtual
destructors. Or do you want the compiler to switch such behavior
depending on whether some standard header has been included, e.g.

   #include <std::auto-virtual-destructors>
   #include <std::auto-initialize-locals>

?

-- Niklas Matthies

---
[ 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: Daniel James <internet@nospam.demon.co.uk>
Date: Sun, 6 May 2001 04:24:11 GMT
Raw View
In article <3AF18EAB.FABB084A@jps.net>, Dennis Yelle wrote:
> > Currently the Standard says: "Two pointers of the same type compare
> > equal if and only if they are both null, both point to the same object
> > or function, or both point one past the end of the same array". You mean
> > you would want to break this property?
>
> It is already broken.

No, I don't think it is.

> Decide what this program should print based on the quote above,
> and then try it:
[snip]

>   struct junk {
>     int x[2];
>     int y[2];
>   } stuff;
>   if ( stuff.x+2 == stuff.y)
>     cout << "same\n";
..

You're actually not allowed to make that comparison, stuff.x+2 and stuff.y
are pointers to different objects.

The only thing the standard says about stuff.x+2 is that if you companre it
with with stuff.x+2 it will be equal. Comparison with stuff.y results in
"undefined behaviour".

I agree that on many typical compilers the undefined behaviour will turn out
to produce the output "same\n", but you can't rely on it.

Cheers,
 Daniel.



---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 04:25:01 GMT
Raw View
On Sat,  5 May 2001 12:10:34 GMT, Carl Daniel <carl@pixami.com> wrote:
[=B7=B7=B7]
> One other thing I left off my other list...
>=20
> New keywords!  I don't know what they are, but I think the language
> definers should be able to add keywords without fear of loss of
> backwards compatibility.
>=20
> One idea, which interacts with the idea that there be some
> standard-mandated implementation options: define new keywords in two
> forms:  a "plain" form, which should be used in all new code and which
> can be optionally disabled (by a standard #pragma or whatever) and a
> "backward compatible" form, which can be optionally enabled.  The
> backward compatible form would be deprecated upon introduction, but
> provided to help the transition to the new language.
>=20
> e.g.   abstract  -  "plain" form
>         __abstract - "backward compatible" form
>=20
> I just think it's high time that we allow the language to evolve
> without a-priori dismissing all English language words as candidates
> for new keywords simply becuase they might break some existing code -
> as others have pointed out, most programmers have access to
> high-powered editing tools that would enable one to rename something
> which collided with a new keyword in a very short time - even on a
> project with 100's or 1000's of source files.

The way this is usually done (well, at least how it's done in C) is to
let the keyword start with underscore and an upper case letter
("_Keyword"), which places it in the namespace reserved for the
implementation, and then in some (new) standard header define:

   #define _Keyword keyword /* "plain" form */

Old code won't include that header and hence not break. New code will
include the header if it wants to use the plain form. So what you want
is already possible with the current language.

-- Niklas Matthies

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Sun, 6 May 2001 04:24:51 GMT
Raw View
Matt Seitz wrote:
>
> One of the reasons that THE DESIGN AND EVOLUTION OF C++ impressed me is Dr.
> Stroustrup's insistence that new features must be shown to give significant
> improvements in an actual project before being added to the language.  This
> often took the form of taking an existing project and showing how it could
> be significantly improved by adding the new feature.   I would be interested
> in reading of anyone performing a similar analysis regarding these
> suggestions.

Well, the implementation of std::vector from SGI which
I got with gcc version 2.95.3 20010315/djgpp (release)
has well over 50 lines of source code to avoid storing a
copy of the allocator in those cases when it can determine
at compile time that actually storing a copy of the allocator
is not needed.  Those 50+ lines would all go away if this code:

  template< class T, class Allocator = allocator<T> >
  class Vector {
    T* m_data;
    T* m_size;
    T* m_capacity;
    Allocator m_allocator;
    // ...
  };

Would produce a class of size 12 instead of 16 in the case
where Allocator contained no data.

Is that a good enough improvement for you?

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 04:25:14 GMT
Raw View
On Sat,  5 May 2001 01:03:57 GMT, Greg Brewer <nospam.greg@brewer.net> wr=
ote:
> "Niklas Matthies" <news/comp.std.c++@nmhq.net> wrote in message > You c=
an
> already do this, like
> >
> >    #if __cplusplus =3D=3D 199711L
> >       // compiling under C++98
> >    #elif __cplusplus > 199711L
> >       // compiling under C++ newer than C++98
> >    #else
> >       // compiling under pre-standard C++
> >    #endif
> >
> > And compilers usually have their own pre-defined version macros.
>=20
> But that is kludgy and it doesn't do anything.
[=B7=B7=B7]

Well, meanwhile I see your point.
For purely aesthetical reasons (and because Perl does something very
similar), I'd suggest overloading "using" for that purpose, i.e.

   using <C++ version number>;

And compiler vendors could be encouraged to provide
  =20
   using <vendor/compiler name>::<compiler extension or version number>;

-- Niklas Matthies

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Sun, 6 May 2001 04:25:24 GMT
Raw View
On Sat,  5 May 2001 15:47:41 GMT, Wilka <wilka@ritualistic.com> wrote:
> > But a forward-declared enum would have to be an incomplete type, because
> > its size depends (or can depend) on the actual enumerators. This would
> > severly restrict the use of an only-forward-declared enum type.
>
> This is already true for a forward declared class, I don't see why an enum
> would be any trouble.

I didn't mean to imply that it would be any trouble.
But it might not have the advantages expected by the original poster.

-- Niklas Matthies

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sun, 6 May 2001 04:25:50 GMT
Raw View
Howard Gardner wrote:
>
> Valentin Bonnard wrote:
>
> > Howard Gardner  wrote:
> >
> >> I bet instructors would like to get rid of the whole topic too, for that matter.
> >
>
> > I want students to initialise variables to the right value,
> > or to assign them the right value before use.
>
> I wonder if you would disagree with any of these statements:

No, but there's one key issue I've got with the dogma that all variables
should be initialized immediately after declaration: I've found that
this dogma can often hide problems. Code that is virtually guaranteed to
go haywire in an easily detectable fashion when the value is random,
will often produce symptoms that are far more subtle and correspondingly
hard to detect, if the variable gets initialized with a premature but
legal value.

However, most of my actual experience has been with C90. Both C++ and
C99 allow declarations intermixed with statements, which significantly
reduces the need to declare something before it can be given it's true
value. Unfortunately, I'm working under a standards and guidelines
document that requires all local variables to be defined at the top of a
function.

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Sun, 6 May 2001 04:25:56 GMT
Raw View
dennis51@jps.net (Dennis Yelle) wrote (abridged):
> I think the current rule is intended to
> protect us from things like this:
>
>   int get_num() { return 3; }
>
>   void increment( int& i) { ++i; }
>   //...
>   increment( get_num());  // Error!
>
> Would you like to make the above legal?

I would. There doesn't seem to be anything wrong with it. The code
creates a value which is thrown away. The worst we can say is that it may
not be what the author intended. However, similar code can be useful. I
don't see any easy way to permit the useful cases while denying the
unintended ones.

I think the language is simpler without the current rule. Eg it seems
illogical to permit:

    vector<int>().swap( v );

but deny:

    v.swap( vector<int>() );


  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Sun, 6 May 2001 04:26:09 GMT
Raw View
news/comp.std.c++@nmhq.net (Niklas Matthies) wrote (abridged):
> But a forward-declared enum would have to be an incomplete type,
> because its size depends (or can depend) on the actual enumerators.
> This would severly restrict the use of an only-forward-declared
> enum type.

Agreed. But even with those restrictions it would still be useful. In
particular, as my example showed, we could declare functions which took
incomplete enums as arguments or returned them as results.

    class Point; // sizeof Point not known.
    enum Color; // sizeof Color not known.

    Point move( Point p, int dx ); // OK - size not needed.
    Color tint( Color c, float f ); // OK - size not needed.

This enables us to write header files which declare functions without
#including the header files which define the enums and classes they use.
It helps dependency management.

The main difference is that a pointer to an incomplete class is itself
complete, where-as a pointer to an incomplete enum would probably not be
complete. The ramifications of this need to be thought through. I refer
you to the many previous discussions.

Another objection is that a similar effect can be got by wrapping the
enum in a struct. However, this is clumsy and doesn't achieve the
objective of simplifying the language.

(Is it intended that we use this monster thread to rehash all the
features requested over the last 3 years?)

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Howard Gardner <usenet@hgardner.com>
Date: Sun, 6 May 2001 02:09:55 CST
Raw View
Paul Mensonides wrote:

> : 1) In C++, uninitialized variables are common.
> Whose fault is that?  The programmer not the language.  Default initialization
> is just way to encourage bad coding practices.

So you agree that the problem is common?

> : 2) Uninitialized variables often are not discovered until a program is run on
> a machine other than the OP's.
> Once again, bad programming habits.

So you agree that the problem is common?

> : 3) Bugs are much harder to correct in large code bases than they are in small
> code bases.
> And code that is well written minimizes bugs and makes finding them easier.

It's easier to find bugs in bad code if there's less of it, and it's easier to find bugs in good code if there's less of it.

> : 7) It is relatively difficult to correct bugs that are difficult to reproduce.
> Only if the code was lazily written (as a result of un-initialized variables)

The number of situations in which variables are commonly left uninitialized is very large.  It's a mistake born of inexperience, not of laziness.

> : 9) In most circumstances, an uninitialized variable is an error that will
> result in a bug.
> This is not true at all.  Many, many times an uninitialized variable is used to
> hold 'extra' retvals from a function call:
>
> bool populateTheseVars(int& x, int& y)
{
>     if (/* can't get resource */) return false;
>     x = 10;
>     y = 10;
>     return true;
> }
>
> void f() {
>     int x, y; // not initialized
>     if (populateTheseVars(x, y)) {
>         // use x, y
>     }
>     return;
> }
>
> This 'type' of situation is common.

I'm not arguing that it should be impossible to create an uninitialized variable, only that creating uninitialized variables should not be the default behavior.

As an aside, I haven't run across the situation very often since I switched to C++.  I did see it a lot in C.  People neglected to check the return value and ended up using the uninitialized variables a lot then too.

> : 10) It is possible to change the syntax of C++ so that naive variable
> declarations result in initialized variables, statements which currently
> initialize variables are not affected, and it is possible to create
> uninitialized variables when necessary.
> :
> : Making the kind of change mentioned in statement 10 would save enormous
> amounts of time.
>
> It takes me approximately 1/4 sec. (or less) to write the extra " = 0" .
> You could even save more time by typing this: int x=0; // with no spaces!

The amount of time that it takes to type the line is not the issue: the amount of time that it takes to discover that someone typed the wrong line is.

> : I have yet to see anyone attempt to make the case that the miniscule boost in
> efficiency resulting from having a naive variable declaration result in an
> uninitialized state is worth all of the pain that it brings.
>
> The point of C++ is not to coddle the programmer.  The *primary* tenant of C++
> is "you don't pay for what you don't use."

The price of leaving the default behavior undefined is very high, and it's a feature that I don't often use.

> miniscule?
>

> class X {
>     private:
>         int m_x[1000000];
What I'd actually prefer is

class X {
  private:
    uninitialized int m_x[1000000];
or maybe

class X {
   private:
     ticking int m_x[1000000];

; )


======================================= MODERATOR'S COMMENT:
 Please hard-wrap your lines at <80 columns.  Thanks!

---
[ 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: Howard Gardner <usenet@hgardner.com>
Date: Sun, 6 May 2001 07:55:45 GMT
Raw View
James Kuyper Jr. wrote:

> No, but there's one key issue I've got with the dogma that all variables
> should be initialized immediately after declaration: I've found that
> this dogma can often hide problems.

You have a point.  Detecting bugs is different from reproducing them,
and fixing them is different yet again.  The second two are definitely
easier if the program's state is defined: the first might not be.

Would you go so far as to argue that defining the value of an uninitialized
declaration would increase the cost of hitting an arbitrary reliability
goal?


> Unfortunately, I'm working under a standards and guidelines
> document that requires all local variables to be defined at the top of a
> function.

Ouch. Since you have a near-worst-case situation: how hard would a change
like this hit you?

---
[ 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: Olaf Krzikalla <Entwicklung@reico.de>
Date: Sun, 6 May 2001 11:27:51 GMT
Raw View
Hi,

"James Kuyper Jr." wrote:
> Here's an example. Imagine that you're deep in template code, where a
> and b are complicated types, which interact in a complicated fashion.
> For instance, adding them might involve the use of expression templates.
> Then it can be a great convenience to be able to write:
>
>         typeof(a+b) c = a+b;

But still this isn't the thing I really want to get. Why should I write
the expression twice ?  Why not the (IMHO much better) suggestion to
overload auto:

         auto c = a+b;


Best regards
Olaf Krzikalla

---
[ 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: Olaf Krzikalla <Entwicklung@reico.de>
Date: Sun, 6 May 2001 11:46:55 GMT
Raw View
Hi,

now I wonder, that I didn't get any reply to a similar suggestion I made
here some weeks ago. My intention was a different one, so it seems to be
useful in many cases. IMHO it's also a question of uniformity: we have
simple ways to define compiler-generated default-ctors and dtors by
leaving their bodies blank.
But by now we haven't the way to do this with assignment and copy-ctor.

I would prefer a keyword _after_ the definition. So it's possible to
write the definition apart from the declaration:

class Foo {
  protected:
    Foo( const Foo& );
    Foo& operator=( const Foo& );
};

//somewhere else:
Foo::Foo( const Foo& ) = default;
Foo& Foo::operator=( const Foo& ) = default;

or inlined:

> class Foo
> {
> protected:
>    Foo( const Foo& ) = default;
>    Foo& operator=( const Foo& ) = default;
> };

The syntax bothers me a little: it looks like a declaration, but it's a
definition. Maybe it could be rewritten:

Foo::Foo( const Foo& ) default {}

Anyway, I like 'default' more than 'auto' (my suggestion).


Best regards
Olaf Krzikalla

---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sun, 6 May 2001 11:47:25 GMT
Raw View
Sun,  6 May 2001 04:23:58 GMT, Michael Lee Finney <michael.finney@acm.org=
> pisze:

>> In Unicode 3.1 characters go up to U+10FFFF.
>> 16 bits are not enough.
>=20
> No, Unicode is explicitly a 16-bit standard.

No. It used to be, but no longer. It currently encodes 94140 characters
in the address space of U+0000..U+10FFFF.

> In Unicode they can only be referenced via the=20
> low+high method requiring two Unicode characters.

No. There are three important encoding forms, not counting Endianness
variants: UTF-8, UTF-16 and UTF-32. You are describing UTF-16, not
the Unicode character space.

    Date: Mon, 19 Feb 2001 17:42:41 -0800 (GMT-0800)
    From: no.spam.DougEwell2@cs.com
    Subject: Perception that Unicode is 16-bit (was: Re: Surrogate space =
in Unicode)
    Message-ID: <200102200150.RAA26641@unicode.org>
    To: "Unicode List" <no.spam.unicode@unicode.org>
   =20
    A few days ago I said there was a "widespread belief" that Unicode is=
 a
    16-bit-only character set that ends at U+FFFF.  A corollary is that t=
he
    supplementary characters ranging from U+10000 to U+10FFFF are either
    little-known or perceived to belong to ISO/IEC 10646 only, not to
    Unicode.

    [...]

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 02:13:06 GMT
Raw View
I sometimes want an abstract class, but do not have a
virtual function. It would be nice to be able to
define a class as "abstract" so that the class cannot
be instantiated. The keyword "abstract" could be used
on the class declaration for that purpose. It could
also be used to (optionally) replace "=0" for a
abstract member function. There is no particular
reason why you could not declare an abstract member
function which is not virtual. You are merely
declaring that it must be implemented by a non-
abstract subclass, but it is would not be referenced
from a pointer to the base class. So, I could write
something like...

   class abc
      {
      void aFunction() abstract;
      virtual void bFunction() abstract;
      };

Then, given "abc * p", I could use p->bFunction()
because it is virtual, but I could not use p->
aFunction() because it is not virtual. In either case,
a class...

   class def : abc
      {...};

would have to implement both aFunction() and bFunction
() for it to be non-abstract. Also...

   abstract class abc
      {...};

could not be instantiated, but...

   class def : abc
      {...};

could be instantiated, given no other constraints.

---
[ 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: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Fri, 4 May 2001 10:33:03 GMT
Raw View
LR wrote:
>
> Radoslav Getov wrote:
>
> > - did I mention 'typeof'?
>
> Yes.  What do you think that typeof should return?

Nothing, because it's not a function.
What does int return?

If you think "higher order", typeof returns a type.

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Fri, 4 May 2001 10:33:31 GMT
Raw View
On Thu,  3 May 2001 20:33:19 GMT, Greg Brewer <nospam.greg@brewer.net> wrote:
> "Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message >
> That might be useful. One thing Bjarne suggested is that C++ compilers
> > in transition from today to the future should be required to implement
> > new features in a specified order. IOWs if it supports feature X it is
> > required to support all features prior to X.
>
> I like that idea.  One problem I would like to see addressed though is
> forward compatability.  New language features often break existing code.
> Wouldn't it be nice if there was a pragma that you could code at the start
> of your source modules that declare the version -- either of the compiler or
> of the standard.  Examples might be
> #pragma version cppstd 1998 cstnd 2000 // c++ standard and c standard should
> be required
> #pragma version msc 2.42 // Microsoft specific information ignored by all
> others
> #pragma version bc 5.01 // Borland specific information ignored by all
> others

You can already do this, like

   #if __cplusplus == 199711L
      // compiling under C++98
   #elif __cplusplus > 199711L
      // compiling under C++ newer than C++98
   #else
      // compiling under pre-standard C++
   #endif

And compilers usually have their own pre-defined version macros.

What might be more useful is to introduce feature-specific macros, e.g.
__STD__RTTI_98_AVAILABLE, __STD__AUTO_INITIALIZE_OBJECTS.

> That is just a spur of the moment idea.  Even if this idea won't fly I
> would like to see the standards committee take a look at forward
> compatability so that code I write today will have a chance of
> compiling with a 2010 c++ compiler.

Usually you use flags to tell the compiler which version of C++ with
which extensions you want your code to be compiled with, and check using
the preprocessor like above that you actually got the version your code
is comfortable with.

-- Niklas Matthies

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Fri, 4 May 2001 10:33:56 GMT
Raw View
On Thu,  3 May 2001 20:36:45 GMT, Dennis Yelle <dennis51@jps.net> wrote:
> Niklas Matthies wrote:
[=B7=B7=B7]
> > > > and how would pointers to zero-sized objects behave?
> > >
> > > When you increment them, decrement them, or add (or subtract)
> > > a size_t to (from) them, they do not change.
> >=20
> > Currently the Standard says: "Two pointers of the same type compare
> > equal if and only if they are both null, both point to the same objec=
t
> > or function, or both point one past the end of the same array". You m=
ean
> > you would want to break this property?
>=20
> It is already broken.
> Decide what this program should print based on the quote above,
> and then try it:
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> #include <iostream>
> using namespace std;
>=20
> int main()
> {
>   struct junk {
>     int x[2];
>     int y[2];
>   } stuff;
>   if ( stuff.x+2 =3D=3D stuff.y)
>     cout << "same\n";
>   else
>     cout << "different\n";
>   return 0;
> }
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>=20
> Both of my compilers print "same".

Even though stuff.x+2 points one past the end of the array stuff.x, it
may very well at the same time also point to the object denoted by=20
stuff.y[0]. Since "one past the end of the array" doesn't refer to an
object that is part of the array, I don't see that anything is broken.
both stuff.x+2 and stuff.y happen point to the same one object, and
therefore compare equal (assuming there's no padding between x and y).

-- Niklas Matthies

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 10:35:54 GMT
Raw View
I also want two new primtive types: "unichar" and
"isochar" where unichar is unsigned and at least 16
bits and where isochar may be signed or unsigned, but
must be able to represent 31 bits of positive value.
In practice, a unichar would normally be exactly 16
bits and an isochar would be either signed or unsigned
and 32 bits.

This is a lot better than having to figure out which
primitive type is available and also allows us to
explicitly overload on those types (and, yes, I have
programs where I simultaneously use char, unichar and
isochar in the same translation unit and need to
overload on those types).

Perhaps it isn't (yet) appropriate to adopt Unicode or
ISO extension as the native character set, but surely
we should require our language to support these as
native types!

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Fri, 4 May 2001 10:35:22 GMT
Raw View
Harvey Taylor wrote:
>
> In article <3af13a91$0$15026$ed9e5944@reading.news.pipex.net>,
> <SPAMstephen.howeGUARD@tnsofres.com> Stephen Howe wrote:
> > Ron Natalie <ron@spamcop.net> wrote in message
> > news:3AF091B3.F6F5630D@spamcop.net..
> >> Dennis Yelle wrote:
> >>>
> >>> When you increment them, decrement them, or add (or subtract)
> >>> a size_t to (from) them, they do not change.
> >>>
> >> And the use of this nothingness is?
> >
> > nothing :-)
> >
>
>         I don't know what Dennis has in mind [please do elucidate, Dennis]
>         but somehow I can imagine some first millenium arithmetician
>         saying the same of zero.
> <curious>

Well, I thought the uses of empty structs were well known because of
the STL, where they are used a lot.  But I agree they are a bit
mysterious.

Maybe this example will help show when the current situation
is a problem:
=================================
#include <iostream>
using namespace std;

struct Base1 {
  int stuff;
};

struct Base2 {
  int foo() { return 3; }
};

struct Both : Base1, Base2 {};

int main()
{
  cout << "Base1 size: " << sizeof(Base1) << '\n';
  cout << "Base2 size: " << sizeof(Base2) << '\n';
  cout << "Both  size: " << sizeof(Both ) << '\n';
  return 0;
}
=================================

For the program above, one of my compilers gives this result:

  Base1 size: 4
  Base2 size: 1
  Both  size: 8

And my other compiler gives this result:

  Base1 size: 4
  Base2 size: 1
  Both  size: 4

Now, it may be that they both conform to the standard
for this particular program, but to me, they are both wrong.
In the first case, using a second empty base class, something
which should logically be free, costs me 4 bytes per object.
In the second, we see that seemingly a total of 5 bytes
fits in a struct 4 bytes long.

I guess I just don't understand why it was felt that
an empty struct should have a size of 1, and then
invent some special cases to make that 1 byte
go away some times.  Just doing the natural thing of
allowing it to be 0 bytes long would, it seems to me,
lead to all of the right results.

I think part of the problem was that when this decision
was originally made, we did not have enough experience
with empty classes and structs to see that they should
actually have a size of zero.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 10:36:29 GMT
Raw View
Here's an idea which is a bit more unusual. Replace
the syntax:

   do <statement> while (<exp>;

with:

   do <statement> while (<exp>) statement

This is backward compatible because ; is a valid
statement. It also allows me to write:

   do
         {
         // some code
         }
      while (exp)
         {
         // some more code
         }

and explicitly solves the n and a half loop problem
which occurs in many algorithms. This neither
introduces new keywords nor does it break existing
code. But is would be welcome extension which makes
structured code for some problems easier to write.

---
[ 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: "Joseph Gottman" <joegottman@worldnet.att.net>
Date: Fri, 4 May 2001 10:37:04 GMT
Raw View
    I'd like to see some way to declare a class's default constructor, copy
constructor, or assignment operator, then automatically use the one that the
compiler would have generated for the class if I hadn't declared it.  This
would be useful if the only reason I declared the function was to make it
private or protected.  One possible way of doing this without adding a new
keyword is by reusing the keyword 'using';

class Foo {
     protected:
        using Foo(const Foo &); // Autogenerate protected copy constructor
         using Foo &operator=(const Foo &); // Autogenerate protected
assignment operatror
};

Joe Gottman

---
[ 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: "John Crickett" <john@crickett.co.uk>
Date: Fri, 4 May 2001 10:38:50 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote in message
news:3AF03BF7.CA94F1A3@acm.org...

> Howard Gardner wrote:
> > I can't count the hours I've spent tracking down uninitialized
> > variable bugs (sometimes even my own) of one form or another.
>
> I spent several hours a couple of weeks ago tracking down an
> uninitialized pointer bug in some third-party code.  A waste
> of time, but it probably would have been no easier (maybe
> even less easy) if the pointer value was 0 rather than garbage.

Surely then the issue is to "persude" compiler writers to issues some decent
warnings?

Or just buy Lint, it would have pointed this problem out immediately.

> And many of us don't want to pay for a feature (possibly more
> easily reproducible bugs) that we don't use at the expense of
> code which runs more slowly.

I'd hate to pay for this feature that's a fix for poor diagnostics, or the
lack of a tool like lint to make up for them.

Regards, John


---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 4 May 2001 10:38:11 GMT
Raw View
In article <988905919.101639@cswreg.cos.agilent.com>, Johan Ericsson
<livedog65@hotmail.com> writes
>Currently, a public base class is practically required to have a virtual
>destructor (even if empty). These classes with empty destructors do have
>proper compiler generated copy-ctors and assignment operators. Are we going
>to start distinguishing between empty and non-empty destructors?

But he is also proposing that virtual default dtors be provided for any
class with a virtual member so it would no longer be necessary to write
and empty dtor.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Jens Kilian <Jens_Kilian@agilent.com>
Date: Fri, 4 May 2001 10:39:20 GMT
Raw View
Michael Lee Finney <michael.finney@acm.org> writes:
> I want to eliminate the problem of the right shift
> operator being undefined for signed operands.

I'd like bit-rotation, population count, highest-bit-set and lowest-bit-set
operators (or standard functions that could be implemented efficiently
on machines with the appropriate instructions).

Also, standard library functions for float-to-ASCII and ASCII-to-float
conversions which guarantee accuracy, similar to the ones found in most Lisps.
(Efficient implementations for these are freely available.)

Some kind of lambda feature would be nice, but people tend to disagree about
how much power is needed and how it should be implemented.
--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Fri, 4 May 2001 10:40:54 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.155bcfc9b16b6aab989716@news.lynchburg.net...
> In article <3AF14C18.6D2A3A3A@wizard.net>,
> kuyper@wizard.net says...
> > > We already have "explict" to indicate that a
> > > conversion can only happen explicitly. How about
> > > allowing "implicit" so that a conversion is treated at
> > > the same level as other implicit conversions?
>
> > > Having the built-in conversions on a level we can't
> > > reach can be very awkward sometimes. It should be
> > > possible for a user defined conversion to be treated
> > > identically to the language defined conversions.
>
> > User-defined conversion functions and converting constructors are
> > already treated almost the same as the built-in conversions. The main
> > difference is that an implicit conversion sequence cannot contain more
> > than one user-defined conversion. Is that the restriction you're asking
> > to have removed for functions declared "implicit"?
>
> The point here is directed towards what another poster
> stated more explicitly -- the ability to define a
> class which is indistinguishable from a "primitive"
> object. One thing needed is "implicit" conversion
> operators because that affects type conversion rules.

Agreed - allow chaining of "implicit" conversions.

> Another thing needed is the ability to define && and
> || as proper short-circuited operators.

Agreed

> One way to do
> that is to define the operands as "lazy" so that they
> are conceptually passed as a thunk and only evaluated
> when referenced. If inlined, the thunk could be
> optimized away, resulting in short circuit operators.

I like the idea. This is effectively just a lambda function, created
on-the-fly from an arbitrary expression

bool func(bool lambda x) // x is a lambda function returning bool
{
  if(someCondition)
     return x;  // x is only evaluated here
  else return false;
}

func(a+b+c); // invocation of func()

the expression (a+b+c) is converted to a lambda function (ie not evaluated).
If the result can be converted to bool, then it is a match for the
declaration of func above. Any expression can be converted to a lambda
function, by effectively defining a functor with a reference data member for
each object named in the expression, and operator() that replicates the
original expression using these members, e.g. (for a+b+c)

struct lambda1
{
  typeof(a)& a_;
  typeof(b)& b_;
  typeof(c)& c_;

  typeof(a+b+c) operator() { return a_+b_+c_;}
};

Also, you can declare a lambda function (e.g. for use as a functor)

std::vector<std::string> vs;
std::for_each(vs.begin(),vs.end(),
    void lambda(const std::string&b)
    {
        std::cout<<b<<'\n';
    }
);


> Also, the ability to overload the ?: operator is
> desirable.

Agreed, but I don't like the suggestion of splitting it into two.

[SNIP]

> Another way to handle ?: is to explicitly recognize it
> as an overloadable operator (much cleaner than trying
> to break it into two peaces) which accepts three
> parameters. Then you could define...
>
>    inline Integer operator?:(
>       Boolean   choice,
>       Integer   @trueValue,
>       Integer   @falseValue)
>       {
>       if (choice)
>             return trueValue;
>          else
>             return falseValue;
>       }
>
> This approach also has the benefit that lazy
> evaluation only needs to be allowed in function
> parameters, and so the calling stack problem doesn't
> arise.

I think the first parameter should always be a UDT, but the others need not
be. The second and third parameters must also always be of the same type,
except that one or both may be lambda functions returning the common type.
operator?: may be defined as a class member, thus omitting the first
parameter.

e.g.

struct MyClass
{
    std::string operator?:(std::string lhs,std::string lambda rhs);
}

> So, three features
>
>    implicit constructors
>    lazy evaluation for function parameters
>    overloadable operator?:()
>
> gets us much closer to the ability to be able to
> define a user class with exactly the same behaviour as
> one of the built in types which I consider to be
> extremely important.

My list is (in no particular order):

* explicitly "implicit" conversions
* "explicit" conversion operators - to permit int a; a=int(myClassObject);,
but not int a; a=myClassObject;
* lambda functions
* permit operator?: overloading
* typeof
* template typedef
* require local classes to have linkage, so they can be used as template
arguments
* local functions
* enable proxy types (a natural extension to smart pointers) => permit
overloading of "operator."
* enable non-const references to temporaries

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: amj25@cam.ac.uk (Andrew Jenner)
Date: Fri, 4 May 2001 10:41:28 GMT
Raw View
On Fri,  4 May 2001 02:12:19 GMT, Michael Lee Finney
<michael.finney@acm.org> wrote:

>   label: while (exp)
>      {
>      // some code
>      continue label;
>      // some code
>      break label;
>      }

I like this idea. Here is another way it could be done, with numeric
arguments to break and continue:

  while(x) {
    ...
    while(y) {
      ...
      if (z)
        break 2; // breaks out of both loops, ends up at ***
    }
  }
  // ***

and

  while(x) {
    // ***
    ...
    while(y) {
      ...
      if (z)
        continue 2; // breaks out of inner loop, ends up at ***
    }
  }

Advantage: named break statements are effectively gotos anyway - this
method is more structured.

Disadvantage: If you add another nesting of loop inbetween the
outermost and innermost loop the meaning of the code changes in this
method but not in Michael's. Of course, making such a radical change
would usually require a lot of other changes as well.

Another way of writing these could be "break break;" or "break
continue;".

All three of these syntaxes can coexist.

Andrew

---
[ 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: Jens Kilian <Jens_Kilian@agilent.com>
Date: Fri, 4 May 2001 11:25:58 GMT
Raw View
"Anthony Williams" <anthwil@nortelnetworks.com> writes:
> Also, you can declare a lambda function (e.g. for use as a functor)
>
> std::vector<std::string> vs;
> std::for_each(vs.begin(),vs.end(),
>     void lambda(const std::string&b)
>     {
>         std::cout<<b<<'\n';
>     }
> );

I would prefer a syntax like the following, which parallels templates and
new-style casts, and which also may be easier to parse:

    std::vector<std::string> vs;
    std::for_each(vs.begin(),vs.end(),
        lambda<void>(const std::string&b)
        {
            std::cout<<b<<'\n';
        }
    );

--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ 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: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Fri, 4 May 2001 21:23:26 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.155bd570fa82493298971a@news.lynchburg.net...
> Also, how about allowing a function to qualified by
> "stable" in the same way it can be qualified as
> "const". The meaning of "stable" would be that the
> function has no side effects other than optional side
> effects to mutable data elements, and that two calls
> to the function with the same parameter values will
> result in exactly the same result.
>
> This could be very useful in assisting the compiler to
> eliminate unnecessary function calls by allowing it to
> cache the result when it knows that the function call
> might be needed again. This can already be done if the
> function can be inlined and the optimize can see both
> function invocations, but without extensive analysis,
> the compiler cannot do the same thing for non-inlined
> functions.
>
> Obviously, the use of the keyword would be optional,
> but if a pointer to a function is "stable" then any
> function assigned to the pointer would also have to be
> stable.
>

Obviously, a stable function would have to be verified as such by the
compiler when defined, meaning that it could only call stable functions
itself.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Fri, 4 May 2001 21:23:15 GMT
Raw View
Thu,  3 May 2001 20:37:17 GMT, Hans Aberg <remove.haberg@matematik.su.se>=
 pisze:

> Exceptions are very pleasing, because a program that always throws
> exceptions cannot break, except for non-termination.

I'm not sure what do you mean by this, but
http://cseng.awl.com/book/related/0,3833,020163371X+11,00.html
shows that exceptions are not as safe as they might seem.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: comeau@panix.com (Greg Comeau)
Date: Fri, 4 May 2001 21:23:42 GMT
Raw View
In article <zXTH6.143994$fs3.22936614@typhoon.tampabay.rr.com>,
Scott Robert Ladd <scott@coyotegulch.com> wrote:
>Fourth: While I understand how standards committees work, most programmers
>don't. The Standards process would do well to use the web actively in
>keeping the community well-informed as to its activities. If we're going to
>ask people to participate, they need to feel included, even if they can't
>afford to travel. That is the strength of the Internet -- bringing people
>together. Let's do it.

I agree, and that is exactly why Francis posted his message here! :)
Anyway, there was some discussion and action at the Copenhagen meeting
(which ended about an hour ago) about publicizing more.  As well,
there are less official aspects, though certainly to be considered
tentacles of the committee, such as the links from my web site,
http://www.comeaucomputing.com/iso, the dkuug.dk site, and probably
others.  What do you feel is incomplete on those sites?
--
Greg Comeau                 Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==>         http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo!       NEW: Try out our C99 mode!
comeau@comeaucomputing.com  http://www.comeaucomputing.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                ]





Author: Gerhard Menzl <gerhard.menzl@sea.ericsson.se>
Date: Fri, 4 May 2001 21:23:37 GMT
Raw View
Ron Natalie wrote:

> > Can you think of a name more suitable than:
> >
> >    #dogma always-initialize
> >
>
> I love it.

It's been on my mind for years, but I never saw a practical need for it.
Now, eventually!

What about a standardized way of ignoring warnings using

   #phlegma ...

?

Gerhard Menzl

---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Fri, 4 May 2001 21:24:24 GMT
Raw View
Fri,  4 May 2001 10:35:54 GMT, Michael Lee Finney <michael.finney@acm.org=
> pisze:

> I also want two new primtive types: "unichar" and=20
> "isochar" where unichar is unsigned and at least 16=20
> bits and where isochar may be signed or unsigned, but=20
> must be able to represent 31 bits of positive value.=20
> In practice, a unichar would normally be exactly 16=20
> bits and an isochar would be either signed or unsigned=20
> and 32 bits.

In Unicode 3.1 characters go up to U+10FFFF.
16 bits are not enough.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: LR <lruss@superlink.net>
Date: Fri, 4 May 2001 21:24:01 GMT
Raw View
Christopher Eltschka wrote:
>
> LR wrote:
> >
> > Radoslav Getov wrote:
> >
> > > - did I mention 'typeof'?
> >
> > Yes.  What do you think that typeof should return?
>
> Nothing, because it's not a function.
> What does int return?
>
> If you think "higher order", typeof returns a type.

Ok, your point is well made, and well taken.  Please allow me to ask a
slightly different question.  Maybe the answer is obvious.

Consider this fragment:

class Base {};
class D1 : public Base {};
class D2 : public Base {};

Base *pb = new Base;
Base *pd = somecondition ? new D1 : new D2;

Then what should typeof(pb) and typeof(pd), return? Probably they should
all return Base*.  But isn't it possible that we might want typeof(pd)
to give us D1*.  Could we have syntax that might be like *typeof(pd)
that will yield this info?

And how can typeof be used?  Anywhere that I can specify a type?

Assuming that I want to clone what pd points to, maybe something like:
typeof(pd) px = new *typeof(pd);


Maybe I should ask what typeof will or should do? Or what people see as
it's intended use.

LR.

---
[ 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: Daniel Frey <daniel.frey@aixigo.de>
Date: Fri, 4 May 2001 21:24:30 GMT
Raw View
Joseph Gottman wrote:
>=20
>     I'd like to see some way to declare a class's default constructor, =
copy
> constructor, or assignment operator, then automatically use the one tha=
t the
> compiler would have generated for the class if I hadn't declared it.  T=
his
> would be useful if the only reason I declared the function was to make =
it
> private or protected.  One possible way of doing this without adding a =
new
> keyword is by reusing the keyword 'using';
>=20
> class Foo {
>      protected:
>         using Foo(const Foo &); // Autogenerate protected copy construc=
tor
>          using Foo &operator=3D(const Foo &); // Autogenerate protected
> assignment operatror
> };

What about 'default' (already a reserved keyword)?

class Foo
{
protected:
   Foo( const Foo& ) =3D default;
   Foo& operator=3D( const Foo& ) =3D default;
};

or

class Foo
{
protected:
   default Foo( const Foo& );
   default Foo& operator=3D( const Foo& );
};

seems to make sense too. If we have a way to access the
default-copy-ctor and default-assignment-operator, we could also do
funny things like:

class auto_foo
{
public:
   auto_foo& operator=3D( auto_foo& f ) { ... }
   auto_foo& operator=3D( const auto_foo& ) =3D default; //1
};

//1: Could be faster than a 'real' implementation, as the compiler has a
better chance to optimize it, right?

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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: Daniel Frey <daniel.frey@aixigo.de>
Date: Fri, 4 May 2001 21:24:37 GMT
Raw View
> On Fri,  4 May 2001 02:12:19 GMT, Michael Lee Finney
> <michael.finney@acm.org> wrote:
>=20
> >   label: while (exp)
> >      {
> >      // some code
> >      continue label;
> >      // some code
> >      break label;
> >      }

Good, but the label should better be a 'named' loop like:

while label() { ...  break label; };

because a label is expected to be accessed via 'goto label' and so I'd
expect the code to continue where label is, not at the end of the loop
followed by label. OTOH a named loop is easy to understand and it should
be intuitive what break label is doing. You example could easily be
obfuscated like this:

label:

  // Now I start the loop
  while( exp ) {
    // some code
    break label;
    // some code
    goto label;
    // some code
    continue label;
  }

  // some other code
  goto label;

I suggest the label of a named loop is only visible inside the loop and
not a real label accessible by goto.

Andrew Jenner wrote:
>=20
> I like this idea. Here is another way it could be done, with numeric
> arguments to break and continue:

No, please don't! This will lead to more errors and makes the code
unmaintainable.

> Advantage: named break statements are effectively gotos anyway - this
> method is more structured.

This has nothing to do with 'structured' programming if I have to count
nestings.

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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: Peter Dimov <pdimov@MailAndNews.com>
Date: Fri, 4 May 2001 21:24:42 GMT
Raw View
>===== Original Message From Christopher Eltschka
<celtschk@dollywood.itp.tuwien.ac.at> =====
>LR wrote:
>>
>> Radoslav Getov wrote:
>>
>> > - did I mention 'typeof'?
>>
>> Yes.  What do you think that typeof should return?
>
>Nothing, because it's not a function.

... but an operator.

>What does int return?

Nothing, because it's not an operator. :-)

>If you think "higher order", typeof returns a type.

That much is obvious, but which type?

typeof(std::cout << 5) f()
{
  return std::cout << 5;
}

What is the return type of f()?

--
Peter Dimov
Multi Media Ltd.

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Fri, 4 May 2001 21:24:47 GMT
Raw View

James Dennett wrote:

>
> Luckily number 10 made it into the 1998 Standard, though not
> into MSVC++6.
>
> It's quite legal to write:
>
> struct X;
>
> X* px;
>
> class X {
> };
>
This works in VC++ it just gives a warning about a class previously
seen called "struct."

---
[ 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: Peter Dimov <pdimov@MailAndNews.com>
Date: Fri, 4 May 2001 21:24:56 GMT
Raw View
>===== Original Message From Jens Kilian <Jens_Kilian@agilent.com> =====
>
>I would prefer a syntax like the following, which parallels templates and
>new-style casts, and which also may be easier to parse:
>
>    std::vector<std::string> vs;
>    std::for_each(vs.begin(),vs.end(),
>        lambda<void>(const std::string&b)
>        {
>            std::cout<<b<<'\n';
>        }
>    );

How about

std::for_each(vs.begin(), vs.end(), std::cout << _1 << '\n');

This has the slight advantage that it's possible to implement in the current
language. :-)

--
Peter Dimov
Multi Media Ltd.

---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Fri, 4 May 2001 21:25:11 GMT
Raw View
Dennis Yelle  wrote:

> I think part of the problem was that when this decision
> was originally made, we did not have enough experience
> with empty classes and structs to see that they should
> actually have a size of zero.

I think part of the problem is that you don't understand
what object identity is, why it maybe critical, and why
the compiler doesn't know when.

  -- VB

---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Fri, 4 May 2001 21:25:25 GMT
Raw View
Howard Gardner  wrote:
> Francis Glassborow wrote:

>> Keep the zero overhead principle

> For the love of humanity, define the value of a "default" constructed builtin!

For the love of programmers, define it to deadbeef (or your
prefered invalid value).

  -- VB

---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Fri, 4 May 2001 21:25:28 GMT
Raw View
Niklas Matthies wrote:

> Preferably, a compiler would have a mode where all accesses (that are
> not predictable at compile time) are checked at runtime whether they
> access uninitialized values (a flag or special value would have to be
> added by the compiler for each object).

> it's a feature that more than a few
> higher-level languages already have built-in.

Can you name one   ?

  -- VB

---
[ 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: "Carl Daniel" <carl@pixami.com>
Date: Fri, 4 May 2001 21:25:40 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:Z29zRgACIl86EwhT@ntlworld.com...
> In article <988905919.101639@cswreg.cos.agilent.com>, Johan Ericsson
> <livedog65@hotmail.com> writes
> >Currently, a public base class is practically required to have a virtual
> >destructor (even if empty). These classes with empty destructors do have
> >proper compiler generated copy-ctors and assignment operators. Are we
going
> >to start distinguishing between empty and non-empty destructors?
>
> But he is also proposing that virtual default dtors be provided for any
> class with a virtual member so it would no longer be necessary to write
> and empty dtor.
>

I, for one, would hate to see such a change to the language - I suspect that
it would silently break a lot of code (which is overtly or covertly
dependent on vtable layout).  Windows compilers would be virtually required
to provide an option to suppress that behavior as it breaks COM.
Personally, I'd be happy with wording in the standard that encourages
implementations to give warnings on such classes, but not change the default
behavior.  If a standard mechanism for requesting advanced features is
incorporated into the next standard (something I'm highly in favor of), then
we could have it both ways.

-cd


---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Fri, 4 May 2001 21:25:33 GMT
Raw View
"Andrea Ferro"  wrote:

> I'd rather like
>
> int f()
> {
>     int i;
>     return i;
> }
>
> "ill formed, no diagnostic required" in the language definition, than having the
> overhead of zeroing the local.

Please explain what you would like the language definition to be.

If changing the _C++_ definition impresses you, take any other
language as an example.

  -- VB

---
[ 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: "Wilka" <wilka@ritualistic.com>
Date: Fri, 4 May 2001 21:25:48 GMT
Raw View
> 2. using Base;
>    Example:
>
>      class Derived : private Base {
>        public:
>        using Base;  // expose the entire public interface of Base.
>        // ...
>      };
>

Or maybe:

class Derived : using Base {
    // Derived now exposes the entire public interface of Base.
}

---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Fri, 4 May 2001 21:26:01 GMT
Raw View
"Michael Lee Finney" <michael.finney@acm.org> wrote in message
news:MPG.155bd6c92144f96098971b@news.lynchburg.net...
[snip]
> For example:
>
>    label: while (exp)
>       {
>       // some code
>       continue label;
>       // some code
>       break label;
>       }
>
> This would allow multi-level break and continue
[snip]

This reminded to me an old idea of mine - keyword 'leave':

{
   code.....
   leave;

   more code.....
   leave;
} <<<

The effect of 'leave' would be to leave the current block. Existing
'continue' and 'break' are inapropriate, cause they have somewhat other
meaning. There is an ugly hack

do
{
     here, use 'break' to leave the block

}
while false;

but it is ugly indeed.

Radoslav Getov






---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Fri, 4 May 2001 21:40:25 GMT
Raw View
Fri,  4 May 2001 21:23:15 GMT, Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.=
pl> pisze:

> http://cseng.awl.com/book/related/0,3833,020163371X+11,00.html
> shows that exceptions are not as safe as they might seem.

Sorry, this link appears to be dead and I can't find the
contents anywhere with Google or Altavista. I've put it in
<http://qrczak.ids.net.pl/exceptions.html>.

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: "Carl Daniel" <carl@pixami.com>
Date: Fri, 4 May 2001 22:57:31 GMT
Raw View
"Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl> wrote in message
news:slrn.pl.9f68b5.i9s.qrczak@qrnik.zagroda...
Fri,  4 May 2001 21:23:15 GMT, Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl>
pisze:

> http://cseng.awl.com/book/related/0,3833,020163371X+11,00.html
> shows that exceptions are not as safe as they might seem.

>Sorry, this link appears to be dead and I can't find the
>contents anywhere with Google or Altavista. I've put it in
><http://qrczak.ids.net.pl/exceptions.html>.

The link worked fine for me.

While Cargil's article on exception safety is a must-read, keep in mind that
it's been seven (7) years since it was published.  Once you've read that
article, go out & find a copy of Herb Sutter's book "Exceptional C++", or
read all the GoTW issues related to exception safety.

In the end, you'l find that exception safety is hard - but it's not as bleak
as Cargil speculated.  There do exist techniques which, when applied
consistently and correctly lead to exception safe C++ code.

-cd



---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 4 May 2001 23:43:20 GMT
Raw View
LR wrote:
...
> Consider this fragment:
>
> class Base {};
> class D1 : public Base {};
> class D2 : public Base {};
>
> Base *pb = new Base;
> Base *pd = somecondition ? new D1 : new D2;
>
> Then what should typeof(pb) and typeof(pd), return? Probably they should
> all return Base*.  But isn't it possible that we might want typeof(pd)

Correct.

> to give us D1*.  Could we have syntax that might be like *typeof(pd)
> that will yield this info?

No - typeof() is meant to be a type, that can be used at compile time.
Unless I'm misunderstanding you, the operation you're asking for is
performed at run time. For that purpose, the standard already has
typeid(). It can't be used in quite the same way as typeof(), but then
nothing you do at run-time could cause the compile-time behavior that
typeof() is intended to have. I suspect that some combination of
typeid(), reinterpret_cast(), template argument deduction and virtual
functions can handle whatever problem you'd like to solve with a
run-time typeof(). Of course, that doesn't mean a run-time typeof()
wouldn't be more convenient, but I don't see offhand how it could be
implemented.

> And how can typeof be used?  Anywhere that I can specify a type?

Correct.

> Assuming that I want to clone what pd points to, maybe something like:
> typeof(pd) px = new *typeof(pd);

> Maybe I should ask what typeof will or should do? Or what people see as
> it's intended use.

Here's an example. Imagine that you're deep in template code, where a
and b are complicated types, which interact in a complicated fashion.
For instance, adding them might involve the use of expression templates.
Then it can be a great convenience to be able to write:

 typeof(a+b) c = a+b;

---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Sat, 5 May 2001 01:03:57 GMT
Raw View
"Niklas Matthies" <news/comp.std.c++@nmhq.net> wrote in message > You can
already do this, like
>
>    #if __cplusplus == 199711L
>       // compiling under C++98
>    #elif __cplusplus > 199711L
>       // compiling under C++ newer than C++98
>    #else
>       // compiling under pre-standard C++
>    #endif
>
> And compilers usually have their own pre-defined version macros.

But that is kludgy and it doesn't do anything.  As an example, lets say its
a few years ago and the forward compatibility pragma I am suggesting were
implemented.  I wrote a program with files that have something like
   #pragma version stdcpp 0.5  // just made up
   // .... bunch of code
   for (int i=0; ?; i++) ???;
   if (i > 99) dosomethingspecial();

I then compiled the program and distributed it.

Fastforward to today.  I need to fix a bug in that old program -- or add a
new feature for that matter.  I make the little change and recompile with a
newer version or even different brand of compiler.  Ideally, the compiler
would see the version the program was written for and compile to that
version.  At minimum, it would generate a warning message and proceed to
give me eleventy-thousand error messages telling me "i is undefined".

I would not propose that the ideal behavior be required except by the market
place.  If the ideal behavior is valued by the market place and Compiler B
has it while Compiler M doesn't then Compiler B might get a few customers
Compiler M doesn't.

This is desirable over non-standard solutions because it is known what the
standard is at the time the program is written.  It might be a desirable
feature of an IDE to generate the line for a new program.  What needs to be
done would not be apparent at a latter date.  Pre-defined version macros are
of limited use since you don't know what to put in the sections.  For the
example program, I could put in a pragma that sets a commandline parameter
that uses the old scoping rules; however, the switch didn't exist at the
time I wrote the program.  And I don't want to add the code to a hundred or
so files.

While compiler manufacturers are free to add this type of feature on their
on, anything that is not standard would not be portable.  This feature is
designed to aid in the long term maintenance of code.  That means being able
to compile todays code with a compiler that doesn't yet exist.

Such a feature would also help with future changes to the language.  Very
time a new keyword is added to the language, some code somewhere is likely
going to be broken.  Take for example the typeof operator a lot of us
desire.  If code written today tells the compiler that the code was written
to todays standard and it uses typeof as a variable, tomorrows compiler
would be able to accept the use of typeof as a variable.

Greg Brewer



---
[ 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: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sat, 5 May 2001 12:04:36 GMT
Raw View
Fri,  4 May 2001 21:24:56 GMT, Peter Dimov <pdimov@MailAndNews.com> pisze=
:

> std::for_each(vs.begin(), vs.end(), std::cout << _1 << '\n');

This syntax is ambiguous. Does
    f(g(_1))
mean
    lambda(x): f(g(x))
or
    f(lambda(x): g(x))
?

--=20
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZAST=CAPCZA
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.research.att.com/~austern/csc/faq.html                ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Sat, 5 May 2001 12:04:53 GMT
Raw View
dennis51@jps.net (Dennis Yelle) wrote (abridged):
> Decide what this program should print based on the quote above,
> and then try it:
> =======================================
> #include <iostream>
> using namespace std;
>
> int main()
> {
>   struct junk {
>     int x[2];
>     int y[2];
>   } stuff;
>   if ( stuff.x+2 == stuff.y)
>     cout << "same\n";
>   else
>     cout << "different\n";
>   return 0;
> }
> =======================================
>
> Both of my compilers print "same".
>
> I don't even see a way that any sane usable compiler could
> produce a program that would print "different".

To satisfy hardware alignment requirements.

Another reason is to provide better error detection. For example, a
compiler could add a word of padding between x and y, set it to some
known value like 0xcccc whenever an instance of junk is created, and
verify that it has the same value when the instance is destroyed. This
would help detect errors like:

    stuff.x[2] = 0;

at run time. (I forget whether this kind of thing is permitted when junk
is a POD, but I'm sure its allowed for non-PODs.)

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Sat, 5 May 2001 12:05:54 GMT
Raw View
Allow enums to be forward-declared. Eg:

    enum Color;

    Color proc( Color arg );

    enum Color { Red, Green, Blue };

Semantics would be analogous to forward declared classes. The advantage
is better dependency management; it avoids having to #include the header
which defines the enum.

Also it simplifies the language. Newcomers naturally expect enums to be
forward-declarable. "Why can't I do this?" is a common question in the
newsgroups, with no good answer.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: brangdon@cix.co.uk (Dave Harris)
Date: Sat, 5 May 2001 12:05:37 GMT
Raw View
Allow destructors to take arguments. Eg:

   struct Base {
   protected:
       ~Base( const char *name );
   };

   struct Derived {
       ~Derived() : ~Base( "On behalf of ~Derived" ) {}
   };

This removes an inconsistency from the language. Currently destructors
are the only user-defined functions which can not take arguments. Even
constructors can take arguments! There is no reason I can see to forbid
it.

It is useful because there is currently no other good way for a derived
destructor to communicate with a base destructor. We have to use either
base instance variables (which implies a per-instance overhead) or global
variables (which raises problems with re-entrancy). We can't use virtual
functions.

It would also be useful in some "pilfer" scenarios, where some of the
destructor's work has already been done before the destructor is called.
Eg:

    enum Pilfer { pilfer }; // Dummy marker argument.

    struct Pilferable {
        int *p;
        Pilferable() : p(new char) {
        }
        Pilferable( const Pilferable &rhs ) : p(new int(*rhs.p)) {
        }
        ~Pilferable() {
           delete p;
        }

        Pilferable( const Pilferable &rhs, Pilfer ) throw() : p(rhs.p) {
        }
        ~Pilferable( Pilfer ) throw() {
        }
    };

    void BlockMove( Pilferable *pDest, Pilferable *pSrc, int count )
            throw() {
       for (int i = 0; i != count; ++i) {
           new(pDest+i) Pilferable( pSrc[i], pilfer );
           pSrc[i]->Pilferable::~Pilferable( pilfer );
       }
    }

This is untested code, just to show the idea. The intent is to provide a
copy and destroy combination that avoids memory allocation/deallocation,
for efficiency and exception safety. It was discussed at some length in
the newsgroups a few months ago.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ 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: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Sat, 5 May 2001 12:08:50 GMT
Raw View
Dennis Yelle  wrote:
> Andrei Alexandrescu wrote:

>> Imagine C++ had a keyword
>> 'uninitialized' that you could use like so:
>>
>> void Fun()
>> {
>>     int i = uninitialized;
>>     int j; // initialized with zero
>>     ...
>> }
>>
>> There are multiple advantages to this approach - defaults to safe, and
>> allows you to optimize when you need.
>
> Yes, I think you are right.
> It is time to do this.

Since when   ? This morning   ? This month   ? This year   ?

  -- VB

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Thu, 3 May 2001 05:06:58 GMT
Raw View
We already have "explict" to indicate that a
conversion can only happen explicitly. How about
allowing "implicit" so that a conversion is treated at
the same level as other implicit conversions?

Having the built-in conversions on a level we can't
reach can be very awkward sometimes. It should be
possible for a user defined conversion to be treated
identically to the language defined conversions.

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 3 May 2001 12:44:52 GMT
Raw View
Michael Lee Finney wrote:
>
> We already have "explict" to indicate that a
> conversion can only happen explicitly. How about
> allowing "implicit" so that a conversion is treated at
> the same level as other implicit conversions?
>
> Having the built-in conversions on a level we can't
> reach can be very awkward sometimes. It should be
> possible for a user defined conversion to be treated
> identically to the language defined conversions.

User-defined conversion functions and converting constructors are
already treated almost the same as the built-in conversions. The main
difference is that an implicit conversion sequence cannot contain more
than one user-defined conversion. Is that the restriction you're asking
to have removed for functions declared "implicit"?

---
[ 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: Dima Volodin <dvv@dvv.org>
Date: Thu, 3 May 2001 12:45:52 GMT
Raw View
Francis Glassborow wrote:
>
> [...]
> make rules more general and uniform
> improve support for low level embedded programming (note BS explicitly
> does not want to see C++ become an exclusively high level language)

Finally eliminate register and volatile and introduce a generic mechanism to
indicate a class' or an object's location in an implementation specific storage
type and/or location.

> Francis Glassborow      ACCU

Dima
trying to be consistent

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 12:46:13 GMT
Raw View
In article <3AF08832.FF73BF7@jps.net>, Dennis Yelle <dennis51@jps.net>
writes
>A single zero sized object would have a sizeof 0.
>An array of zero sized objects would have a sizeof 0.

The problem is that, as the language is currently designed, objects have
to have addresses. Currently we can just get away with making subobjects
of different types share addresses.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 12:46:22 GMT
Raw View
In article <tf056gbbqn6t2d@corp.supernews.com>, Radoslav Getov
<nospam@mai.com> writes
>- did I mention 'typeof'?

Yes, and so did Bjarne Stroustrup in his talk:) so the message seems to
be getting through.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 12:46:39 GMT
Raw View
In article <3AF0767F.841D09E0@acm.org>, James Dennett <jdennett@acm.org>
writes
>That's a joke: I would like to see a Standard mechanism
>to allow evolution, such that a compiler which fails to
>support feature X can be detected at compile-time even if
>only by the fact that it aborts compilation with an
>"unsupported feature requested" message.

That might be useful. One thing Bjarne suggested is that C++ compilers
in transition from today to the future should be required to implement
new features in a specified order. IOWs if it supports feature X it is
required to support all features prior to X.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 12:47:47 GMT
Raw View
In article <remove.haberg-0205011158270001@du133-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>Amiss (even though mentioned below) in this general picture is support for
>distributed programming.
>
>Also amiss is support for dynamic programming, like support for the hooks
>that enables the efficient implementation of a conservative GC (like a way
>to get access to the root system.
>
>One will need some such additions in order to be able to build good libraries.
>
>As for the teaching aspect, I think this must be always secondary to the
>aspect of C++ as a language designed to get things done. To me, it is OK
>that C++ is a behemoth and an encyclopaedia one never bother learning in
>its completeness: When one needs a feature.

It is hard for even an experienced stenographer to record all that is
said at a meeting. What I wrote was by no way inclusive. My intention
was to relay to the community of csc++ (and clc++m) that we had
effectively fired the start gun and declared open season on looking to
future developments of C++.

I think that it would be in everyone's interests to make this a brain-
storming session where people avoid overly negative responses to the
ideas of others and adopt an inclusion rather than an exclusion model.
I, for one, will be noting the ideas that come forward and culling them.
Eventually my National Body (BSI) via its C++ panel will be promoting
those ideas that we have thrashed out and consider worth putting our
efforts behind. Where-ever you are, it would be worth while getting
yourselves actively involved in your own NB's C++ standard committee.
Remember that the best way to get a feature is by being willing to o
some of the work necessary to get it.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 12:46:57 GMT
Raw View
In article <3AF03BF7.CA94F1A3@acm.org>, James Dennett <jdennett@acm.org>
writes
>I spent several hours a couple of weeks ago tracking down an
>uninitialized pointer bug in some third-party code.  A waste
>of time, but it probably would have been no easier (maybe
>even less easy) if the pointer value was 0 rather than garbage.

But this could be a QoI issue. It would be nice to have a compiler that
issued a warning for defining pointers without initialisation.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: LR <lruss@superlink.net>
Date: Thu, 3 May 2001 12:48:32 GMT
Raw View

Radoslav Getov wrote:

> - did I mention 'typeof'?

Yes.  What do you think that typeof should return?

LR.

---
[ 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: "Andrea Ferro" <AndreaF@UrkaDVD.it>
Date: Thu, 3 May 2001 12:48:20 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AF041F4.32737E30@jps.net...
> Howard Gardner wrote:
> >
> > Markus Schaaf wrote:
> >
> > >>> For the love of humanity, define the value of a "default" constructed
builtin!
> > >>
> > >> If the Standard mandates safety, efficiency will be impossible.
> > >
> > > I'm not even sure, if what you would get is safety. If you've
> > > forgotten to initialize variables, why would zero be the _safe_
> > > choice?
> >
> > It doesn't make the program correct (unless 0 really was the right value),
it makes the resulting disaster easier to reproduce.  That, in turn, makes the
error easier to find.
> >
> > I can't count the hours I've spent tracking down uninitialized variable bugs
(sometimes even my own) of one form or another.
>
> What compiler are you using?
> Have you turned on all of the warnings?

Agreed. This kind of "problems" should not be addressed in the language
specification itself. Many compilers do warn you. And I'd even be extremist to
the point that "any coding problem that can be discovered with a good
global-code lint should not be a priority in the language design". I'm not
meaning that strong typing itself is not a language concern. I mean that it is
unless it violates the 0 overhead rule.

I'd rather like

int f()
{
    int i;
    return i;
}

"ill formed, no diagnostic required" in the language definition, than having the
overhead of zeroing the local.

--

Andrea Ferro

---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info http://www.brainbench.com/transcript.jsp?pid=2522556



---
[ 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: Gerhard Menzl <gerhard.menzl@sea.ericsson.se>
Date: Thu, 3 May 2001 13:52:13 GMT
Raw View
Ron Natalie wrote:

> > I'd prefer something like a Standard pragma (though historically
> > pragmas have been a pain) such as
> >
> > #pragram STDC++ always-initialize
>
> Only if it is REQUIRED to be impelemented is this useful.  If it's
> optional, the feature suddenly becomes VERY VERY DANGEROUS.   I
> suggest that if we're going to have compile standardized compile
> controls that they NOT be called PRAGMA.

Can you think of a name more suitable than:

   #dogma always-initialize

? <g>

Gerhard Menzl

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 13:52:27 GMT
Raw View
In article <zXTH6.143994$fs3.22936614@typhoon.tampabay.rr.com>, Scott
Robert Ladd <scott@coyotegulch.com> writes
>Fourth: While I understand how standards committees work, most programmers
>don't. The Standards process would do well to use the web actively in
>keeping the community well-informed as to its activities. If we're going to
>ask people to participate, they need to feel included, even if they can't
>afford to travel. That is the strength of the Internet -- bringing people
>together. Let's do it.


I cannot speak for other countries, but within the UK we try to run an
open system and have (through the auspices of ACCU) mechanisms for
including anyone with sufficient interest into electronic
consultation/contribution.

ACCU would happily promote such involvement elsewhere with other
National Bodies but that means that its members elsewhere must ask.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: "Stephen Howe" <SPAMstephen.howeGUARD@tnsofres.com>
Date: Thu, 3 May 2001 13:52:45 GMT
Raw View
Ron Natalie <ron@spamcop.net> wrote in message
news:3AF091B3.F6F5630D@spamcop.net...
>
>
> Dennis Yelle wrote:
> >
> > When you increment them, decrement them, or add (or subtract)
> > a size_t to (from) them, they do not change.
> >
> And the use of this nothingness is?

nothing :-)

Stephen Howe



---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Thu, 3 May 2001 13:52:50 GMT
Raw View
On Thu,  3 May 2001 12:46:57 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> In article <3AF03BF7.CA94F1A3@acm.org>, James Dennett <jdennett@acm.org>
> writes
> >I spent several hours a couple of weeks ago tracking down an
> >uninitialized pointer bug in some third-party code.  A waste
> >of time, but it probably would have been no easier (maybe
> >even less easy) if the pointer value was 0 rather than garbage.
>
> But this could be a QoI issue. It would be nice to have a compiler that
> issued a warning for defining pointers without initialisation.

Preferably, a compiler would have a mode where all accesses (that are
not predictable at compile time) are checked at runtime whether they
access uninitialized values (a flag or special value would have to be
added by the compiler for each object). This would be the best help in
debugging such faults, and it's a feature that more than a few
higher-level languages already have built-in.

-- Niklas Matthies

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 3 May 2001 13:52:38 GMT
Raw View
In article <CSWH6.7300$ks3.2617812@news1.mntp1.il.home.com>, Rene
<rene413@home.com> writes
>I don't mean to piss anybody off with this email; I just find it frustrating
>to see technology advancing so fast and C++ just crawling.

There is a fine line between stability and stagnation. Serious users
want stability, there is nothing to prevent compiler vendors providing
extensions, but it would be a mistake to require them to do so
(particularly when they are still struggling to deliver a fully
conforming implementation of the current standard)

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Thu, 3 May 2001 13:52:59 GMT
Raw View
On Wed,  2 May 2001 22:45:10 GMT, Dennis Yelle <dennis51@jps.net> wrote:
[=B7=B7=B7]
> A single zero sized object would have a sizeof 0.
> An array of zero sized objects would have a sizeof 0.
>=20
> Or to put it another way:
>=20
>   struct nothing {};
>   assert ( 0 =3D=3D sizeof(nothing) );
>   nothing junk[10000];
>   assert ( 0 =3D=3D sizeof( junk));
>  =20
> > and how would pointers to zero-sized objects behave?
>=20
> When you increment them, decrement them, or add (or subtract)
> a size_t to (from) them, they do not change.

Currently the Standard says: "Two pointers of the same type compare
equal if and only if they are both null, both point to the same object
or function, or both point one past the end of the same array". You mean
you would want to break this property?

And what would you want to use such objects for?

-- Niklas Matthies

---
[ 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: Alasdair.Grant@arm.com
Date: Thu, 3 May 2001 13:55:26 GMT
Raw View
>So, what do we want?

Here is my top 10.

1. First a challenge: write a class that behaves like 'int'.
   After all, wrapping base types is something a class-based
   language should be able to do without breaking sweat.  Use your
   class instead of int.  Then look at all the ways your programs
   breaks and fix C++ so that it doesn't.  For example:

   1(a):

     struct { int m_n; } typedef Int;
     Int n;
     volatile Int nv;
     void f() { n = nv; }

   This is legal in C but not C++.  That really ought to be
   fixed, ideally by a general rule about volatile, rather than
   by synthesis of extra copy constructors.  Perhaps have
   qualifier templates, as in the following function:

     template<quals Q> char Q * strchr(char Q *, char);

   Then the implicit copy constructor can be notionally defined
   in terms of qualifier templates.


   1(b):

   The union constructor problem.  It should be possible to say

     struct Int { int m_n; Int(_n): m_n(_n) {} };
     Int n = 2;
     union { Int n; float n; };

   The point here is that it should be possible to union a type
   that "behaves like a base type", i.e. can be initialised but
   has no (significant) default initialisation.  One should not
   have to do without initialisers (where optional) just to be
   able to put types in a union.  Unions are not deprecated yet,
   are they?


2. It would be useful, for safety, to be able to say that a member
   function must override (a non-pure function).  For example:

     struct A { virtual int f(char *); };
     struct B: A { virtual int f(char *) _Pragma(STDC OVERRIDE); };

   This protects (by generating a compiler warning or error)
   against changes to the interface of A::f - introducing 'const',
   say - which have the effect of losing the override in B.


3. friend class T

   where T is a template argument.  This appeared in drafts of
   the Standard (e.g. April 95), with example code.  It made it
   into at least one production compiler which tracked the drafts.
   Its prohibition by the Standard is mysterious and unhelpful.


4. Allow function-local classes to be used as template arguments,
   as in

     f()
     {
       struct S { int n; };
      std::list<S> l;
     }


5. Adopt the C99 'restrict' keyword, after defining its effects on
   function linkage and overloading.


6. Make exceptions an officially optional language feature (perhaps
   selected or deselected by a standard pragma).  There is an argument
   for doing this for RTTI, but not nearly as urgent.  C++ is already
   splitting into a language with exceptions and another language
   without exceptions, and a lot of people want the latter.  In many
   situations exceptions do not justify the overhead required to
   implement them.


7. Have a qualifier on pointer/reference function arguments that acts
   like Ada's OUT keyword, to improve liveness analysis.  I'm sure
   there is some keyword or keyword combination that can be used.
   (What about 'mutable'?)  It would be useful if this keyword could
   apply to (all) anonymous variadic parameters, as in scanf.


8. Standardise function qualifiers for pure and side-effect-free.
   For pureness you could use 'true', meaning that it is truly a
   function of its arguments.  I believe gcc already uses 'const'
   to mean pure (since they use 'pure' to mean 'side-effect-free'),
   though that might conflict with 'const' on member functions.
   If in doubt, standardise _Pragma.


9. When defining a class, especially a template, one sometimes wants
   to say

     IF IT IS MORE EFFICIENT TO REFER TO T THAN TO COPY IT THEN
       typedef T const &ArgT;
     ELSE
       typedef T ArgT;
     T operator +(ArgT a, ArgT b);

   The 'IF' typedef can be done with a template hack, but I can't see
   a way to do the test on which it depends, without language support.
   In general the test is architecture-dependent.


10.As 'struct' and 'class' use the same namespace, it should not be
   necessary to use the names consistently.  The programmer should be
   free to change a definition 'struct X' to 'class X', if that becomes
   more natural, without invalidating uses of 'struct X' elsewhere.
--
Al Grant


---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Thu, 3 May 2001 14:08:48 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AEF1353.87673842@jps.net...
> So, what do we want?
>
> Let's start a list:

I want null defined like true and false so that
void Foo(int);
void Foo(char *);
void Bar(void)
{
   Foo(0);
}

isn't ambiguous.

Greg Brewer



---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Thu, 3 May 2001 17:10:06 GMT
Raw View
James Dennett wrote:
[...]
> > > 4. Zero sized objects.
> > >    This would require lengthof() because the standard idiom would break:
> > >
> > >       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
> > >
> > >    On the other hand, who puts zero sized objects in an array?
> >
> > I think it would break far more than ad-hoc size macros.  Why do you need
> > zero sized objects.
>
> I can't see what this gains us either.
>
> > > 5. Require the "empty base class optimization".
> >
> > Why?
>
> How?  As in, how would you word this requirement?

I would say that it follows directly from point 4. above.
It is one of the reasons for having point 4. above.
Another way to look at it is like this:

#include <stuff> // Defines struct stuff;

struct nothing {};

struct something {
  stuff x;
  nothing y;
};

// ...
  assert( sizeof( nothing) == 0 );
  assert( sizeof( something) == sizeof( stuff));

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Thu, 3 May 2001 17:10:13 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3AF08832.FF73BF7@jps.net>, Dennis Yelle <dennis51@jps.net>
> writes
> >A single zero sized object would have a sizeof 0.
> >An array of zero sized objects would have a sizeof 0.
>
> The problem is that, as the language is currently designed, objects have
> to have addresses. Currently we can just get away with making subobjects
> of different types share addresses.
>
> Francis Glassborow      ACCU
> 64 Southfield Rd
> Oxford OX4 1PA          +44(0)1865 246490
> All opinions are mine and do not represent those of any organisation

We already have one "magic address":
  int* p = 0;
We could define another "magic address".
It could be 1 or 4 or 8 or 16 or whatever the
compiler writer decides works best on his platform.

The only breakage would be questionable code like this:

  struct nothing {};
  struct two_nothings {
    nothing x;
    nothing y;
  } tn;
  assert( &tn.x != &tn.y );  // this assert would fail.
  nothing* p1 = new nothing;
  nothing* p2 = new nothing;
  assert( p1 != p2);         // this assert would fail.

And, as you say above, we already have the case that an
empty object may have the same address as some other object.

If one needs distinct addresses one should not be using
empty objects to get them.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 3 May 2001 19:21:21 GMT
Raw View
In article <3AF0ECDC.9DEF4058@dvv.org>, Dima Volodin <dvv@dvv.org> wrote:

>Francis Glassborow wrote:
...
>> make rules more general and uniform
>> improve support for low level embedded programming (note BS explicitly
>> does not want to see C++ become an exclusively high level language)
...
>... introduce a generic mechanism to
>indicate a class' or an object's location in an implementation specific storage
>type and/or location.

This is also needed in the programming that goes "the other way", dynamic
and distributed programming.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Harvey Taylor <het@despam.autobahn.mb.ca>
Date: Thu, 3 May 2001 20:31:53 GMT
Raw View
In article <3AF184D9.E49CA183@jps.net>,
<dennis51@jps.net> Dennis Yelle wrote:
> James Dennett wrote:
> [...]
>>>> 4. Zero sized objects.
>>>>    This would require lengthof() because the standard idiom would break:
>>>>
>>>>       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
>>>>
>>>>    On the other hand, who puts zero sized objects in an array?
>>>
>>> I think it would break far more than ad-hoc size macros.  Why do you need
>>> zero sized objects.
>>
>> I can't see what this gains us either.
>>
>>>> 5. Require the "empty base class optimization".
>>>
>>> Why?
>>
>> How?  As in, how would you word this requirement?
>
> I would say that it follows directly from point 4. above.
> It is one of the reasons for having point 4. above.
> Another way to look at it is like this:
>
> #include <stuff> // Defines struct stuff;
>
> struct nothing {};
>
> struct something {
>   stuff x;
>   nothing y;
> };
>
> // ...
>   assert( sizeof( nothing) == 0 );
>   assert( sizeof( something) == sizeof( stuff));
>

 Hmmm.  And the reason I would want to do this is...?
 In your code, does 'y' have an address?
 ie. is &y valid &/ meaningful?

 I am reminded of the 'run past the end of a struct metaphor',
 but I doubt that is what you have in mind somehow.

<still curious>
-het


--
"Sacred cows make the best hamburger." -Abby Hoffman

Harvey Taylor  http://www.autobahn.mb.ca/~het/

---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Thu, 3 May 2001 20:33:19 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message >
That might be useful. One thing Bjarne suggested is that C++ compilers
> in transition from today to the future should be required to implement
> new features in a specified order. IOWs if it supports feature X it is
> required to support all features prior to X.

I like that idea.  One problem I would like to see addressed though is
forward compatability.  New language features often break existing code.
Wouldn't it be nice if there was a pragma that you could code at the start
of your source modules that declare the version -- either of the compiler or
of the standard.  Examples might be
#pragma version cppstd 1998 cstnd 2000 // c++ standard and c standard should
be required
#pragma version msc 2.42 // Microsoft specific information ignored by all
others
#pragma version bc 5.01 // Borland specific information ignored by all
others

The compiler would scan the version info and do something appropriate.  One
would expect that the programmer would code the version of the current
compiler.  Then 3 years from now when the compiler has been upgraded to the
latest and greatest, the compiler can either issue an error if it might not
be able to handle code for that version or adapt itself (ie turn off/on
switches necessary to support that version).  In cases where the version is
unknown (which might happen if you were recompiling for another platform,
etc) then it should issue a warning and proceed.

That is just a spur of the moment idea.  Even if this idea won't fly I would
like to see the standards committee take a look at forward compatability so
that code I write today will have a chance of compiling with a 2010 c++
compiler.

Greg Brewer



---
[ 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: Robert FISHER <rfisher@my-deja.com>
Date: Thu, 3 May 2001 20:35:38 GMT
Raw View
Dennis Yelle wrote:

> Robert FISHER wrote:
> [...]
>
>> Am I the only one that hates the standard library? The blatant, violent
>> abuse of operator overloading by the I/O streams has kept me from EVER
>> using them. I respect and admire the STL classes, but I hate using them
>> for reasons I haven't quite completely identified yet. Sure, it's too
>> late to make any radical changes, but I'd sure like to see an
>> "alternative standard library".
>
>
> What are you looking for?
> That is, how will you recognize it when you see it?
> Is it just that the STL is too large?
>

Like I said, I haven't completely identified why I don't like the STL. I
guess I was hoping someone else who with similar feelings might have
something to say that would help be identify my own problems with it.

Maybe it's just that, even after reading much about the STL and groking
at least the basics (which I think I have), I still don't find the
interface very intuitable. I just have to resolve to force myself to use
all the standard library more, so I can either learn to love it or form
better arguments against it. =)

In any case, I'll repeat a couple of my most wanted features for C++0x: =)

* A "finally" construct for exceptions, 'cause "multiparadigm" means I
shouldn't ALWAYS have to use "resource acquisition is initialization".

* A simple, efficient, safe way to tell whether a pointer was allocated
with new and can be safely deleted.
--
Robert FISHER
rfisher@my-deja.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                ]





Author: "Johan Ericsson" <livedog65@hotmail.com>
Date: Thu, 3 May 2001 20:35:13 GMT
Raw View
> The honorable Mr. Stroustrup has mentioned eliminating the default copy
> constructor and assignment operator for classes with destructors and
> making base classes with virtual member functions have a virtual
> destructor by default. These will be very welcome changes.

I heard Mr. Stroustrup say this in a recent speech, and I am a little bit
confused. It seems like this could break a good amount of good code.

Currently, a public base class is practically required to have a virtual
destructor (even if empty). These classes with empty destructors do have
proper compiler generated copy-ctors and assignment operators. Are we going
to start distinguishing between empty and non-empty destructors?

Granted the second suggestion (requiring virtual destructors for classes
with virtual functions) would remove the need for all of these empty
destructors.

Practically the only destructors needed in my current project are empty
virtual destructors. But I use the default compiler generated copy
constructor in these base classes.

If these suggestions were implemented, then I would need to go through and
remove all virtual destructors from all my base classes... except that if I
needed to compile with a "older" compiler, then I would need to re-add all
the virtual destructors or risk undefined behavior. I guess I would start
seeing a bunch of:
#ifdef OLDER_COMPILER
virtual ~MyClass() {}
#endif

Anyways, I think this is a great suggestion, but perhaps it needs to
distinguish between empty destructors and destructors with statements. But I
think this distinction may obscure its implementation.

Any thoughts?

Johan


---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Thu, 3 May 2001 20:36:45 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Wed,  2 May 2001 22:45:10 GMT, Dennis Yelle <dennis51@jps.net> wrote=
:
> [=B7=B7=B7]
> > A single zero sized object would have a sizeof 0.
> > An array of zero sized objects would have a sizeof 0.
> >
> > Or to put it another way:
> >
> >   struct nothing {};
> >   assert ( 0 =3D=3D sizeof(nothing) );
> >   nothing junk[10000];
> >   assert ( 0 =3D=3D sizeof( junk));
> >
> > > and how would pointers to zero-sized objects behave?
> >
> > When you increment them, decrement them, or add (or subtract)
> > a size_t to (from) them, they do not change.
>=20
> Currently the Standard says: "Two pointers of the same type compare
> equal if and only if they are both null, both point to the same object
> or function, or both point one past the end of the same array". You mea=
n
> you would want to break this property?

It is already broken.
Decide what this program should print based on the quote above,
and then try it:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
#include <iostream>
using namespace std;

int main()
{
  struct junk {
    int x[2];
    int y[2];
  } stuff;
  if ( stuff.x+2 =3D=3D stuff.y)
    cout << "same\n";
  else
    cout << "different\n";
  return 0;
}
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Both of my compilers print "same".

I don't even see a way that any sane usable compiler could
produce a program that would print "different".

Dennis Yelle
--=20
I am a computer programmer and I am looking for a job.
There is a link to my resume here: =20
http://table.jps.net/~vert/

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Thu, 3 May 2001 20:37:17 GMT
Raw View
In article <OFDF3B6195.46F31FB0-ON80256A41.004C557F@cambridge.arm.com>,
Alasdair.Grant@arm.com wrote:
>6. Make exceptions an officially optional language feature (perhaps
>   selected or deselected by a standard pragma).  There is an argument
>   for doing this for RTTI, but not nearly as urgent.  C++ is already
>   splitting into a language with exceptions and another language
>   without exceptions, and a lot of people want the latter.  In many
>   situations exceptions do not justify the overhead required to
>   implement them.

Exceptions are very pleasing, because a program that always throws
exceptions cannot break, except for non-termination.

Therefore, I expect that the exceptions feature will grow stronger as the
computers become more powerful, and one learns better how to implement it
in the language.

This will also be true for programs that now require small code.

So rather than looking for ways to merely exclude exceptions, I think one
should look for the prudent inclusion of exceptions.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: Harvey Taylor <het@despam.autobahn.mb.ca>
Date: Thu, 3 May 2001 20:38:01 GMT
Raw View
In article <3af13a91$0$15026$ed9e5944@reading.news.pipex.net>,
<SPAMstephen.howeGUARD@tnsofres.com> Stephen Howe wrote:
> Ron Natalie <ron@spamcop.net> wrote in message
> news:3AF091B3.F6F5630D@spamcop.net..
>> Dennis Yelle wrote:
>>>
>>> When you increment them, decrement them, or add (or subtract)
>>> a size_t to (from) them, they do not change.
>>>
>> And the use of this nothingness is?
>
> nothing :-)
>

 I don't know what Dennis has in mind [please do elucidate, Dennis]
 but somehow I can imagine some first millenium arithmetician
 saying the same of zero.
<curious>
-het



--
"Sacred cows make the best hamburger." -Abby Hoffman

Harvey Taylor mailto:het@spam.autobahn.mb.ca http://www.autobahn.mb.ca/~het/

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Thu, 3 May 2001 20:41:12 GMT
Raw View

Gerhard Menzl wrote:
>
> > controls that they NOT be called PRAGMA.
>
> Can you think of a name more suitable than:
>
>    #dogma always-initialize
>

I love it.

(How about coming up with some use for #karma).

---
[ 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: Ross Smith <ross.s@ihug.co.nz>
Date: Thu, 3 May 2001 22:29:57 GMT
Raw View
Ron Natalie wrote:
>
> Gerhard Menzl wrote:
> >
> > > controls that they NOT be called PRAGMA.
> >
> > Can you think of a name more suitable than:
> >
> >    #dogma always-initialize
> >
>
> I love it.
>
> (How about coming up with some use for #karma).

That's easy: it determines what happens to an object's storage after
it's been destroyed. "#karma bad" means that released memory should be
zeroed out, which will be useful in secure applications.

--
Ross Smith <ross.s@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
        "Hungarian notation is the tactical nuclear weapon of
         source code obfuscation techniques." -- Roedy Green

---
[ 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: James Dennett <jdennett@acm.org>
Date: Fri, 4 May 2001 00:23:38 GMT
Raw View
Alasdair.Grant@arm.com wrote:
>
> >So, what do we want?
>
> Here is my top 10.

[snip]

> 10.As 'struct' and 'class' use the same namespace, it should not be
>    necessary to use the names consistently.  The programmer should be
>    free to change a definition 'struct X' to 'class X', if that becomes
>    more natural, without invalidating uses of 'struct X' elsewhere.

Luckily number 10 made it into the 1998 Standard, though not
into MSVC++6.

It's quite legal to write:

struct X;

X* px;

class X {
};

even across translation units.  I've heard rumours that VC++
encodes struct/class different in mangled names, and so gets
this wrong, but the Standard says that the only differences
between class and struct are default access to members and
default access for inheritance.

-- James Dennett

---
[ 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: "Carl Daniel" <carl@pixami.com>
Date: Fri, 4 May 2001 00:24:02 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AEF1353.87673842@jps.net...
> So, what do we want?
>
> Let's start a list:

My $0.02 worth:

1. typeof

e.g.

std::map<std::string,std::vector<int> > MyMap;

for (typeof(MyMap)::iterator it...)
... many other uses

2. template typedef

e.g.

template <class ValueType> std::map<std::string,ValueType> PropsMap;

With classes like Andrei's smart pointer (from loki) kicking about with so
many template parameters, template typedef would be of great help (I've
heard rumors that template typdef is nearly a shoe-in - true?)

3. finally

Despite my love of the RAII idiom, I too would enjoy having finally.  As
someone else pointed out, C++ is and always has been a multi-paradigm
language.  Forcing the use of RAII seems anathematic to the principles of
C++.

4. std::hash_map, hash_set, slist, etc.

Duh.

5. Reflection/introspection

IMO, this must be optional - perhaps requested by a new class declaration
decoration  (along the lines of MSVC's __declspec() but not that ugly).

At the least, make type_info a bit beefier - the current type_info is pretty
useless except for determining if two classes are in fact the same.

6. Language/library support for abstract factory/virtual constructor.

This pretty much requires reflection, I believe - but the problem is soooooo
common that a standard solution would sure be nice.

7. Standard-sized int's

8. A stream I/O facility which guarantees portability of serialized objects
across platforms (probably requires reflection and standard-sized types).

9. Mssr. Glassborow's suggestion that there be a standard way to inform the
compiler of the language version you're intending to use.

-cd



---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 4 May 2001 00:30:49 GMT
Raw View
Dennis Yelle wrote:
>
> Niklas Matthies wrote:
...
> > Currently the Standard says: "Two pointers of the same type compare
> > equal if and only if they are both null, both point to the same object
> > or function, or both point one past the end of the same array". You mean
> > you would want to break this property?
>
> It is already broken.
> Decide what this program should print based on the quote above,
> and then try it:
> =======================================
> #include <iostream>
> using namespace std;
>
> int main()
> {
>   struct junk {
>     int x[2];
>     int y[2];
>   } stuff;
>   if ( stuff.x+2 == stuff.y)
>     cout << "same\n";
>   else
>     cout << "different\n";
>   return 0;
> }
> =======================================
>
> Both of my compilers print "same".
>
> I don't even see a way that any sane usable compiler could
> produce a program that would print "different".

How about one in which int has a size and alignement of 2 bytes, and
structure members are aligned on multiples of 16 bytes? The platform
would have to be somewhat peculiar, but I don't think exceedingly so, in
order to make that a reasonable implementation.

In any event, how does this constitute a break in the standard? On the
more conventional platforms you were imagining, stuff.x+2 and stuff.y
arguably (and there's been a GREAT deal of argument about it) point to
the same object, namely stuff.y. stuff.x+2 is based upon x, where I'm
using "based" in essentially the same sense as defined by 6.7.3.1 for
restrict-qualified pointers. stuff.x+2 is not based upon y. However, the
standard only refers to whether they point at the same object; it says
nothing about them being based on the same object.

What a pointer points at is defined by what happens when you dereference
the pointer. If an implementation allows you to dereference stuff.x+2
(as undefined behavior, of course), and doing so happens to be exactly
equivalent to dereferencing stuff.y, then I think that implementation
should let them compare equal, and would remain conforming if it did.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 01:57:55 GMT
Raw View
In article <3AF14C18.6D2A3A3A@wizard.net>,
kuyper@wizard.net says...
> > We already have "explict" to indicate that a
> > conversion can only happen explicitly. How about
> > allowing "implicit" so that a conversion is treated at
> > the same level as other implicit conversions?

> > Having the built-in conversions on a level we can't
> > reach can be very awkward sometimes. It should be
> > possible for a user defined conversion to be treated
> > identically to the language defined conversions.

> User-defined conversion functions and converting constructors are
> already treated almost the same as the built-in conversions. The main
> difference is that an implicit conversion sequence cannot contain more
> than one user-defined conversion. Is that the restriction you're asking
> to have removed for functions declared "implicit"?

The point here is directed towards what another poster
stated more explicitly -- the ability to define a
class which is indistinguishable from a "primitive"
object. One thing needed is "implicit" conversion
operators because that affects type conversion rules.

Another thing needed is the ability to define && and
|| as proper short-circuited operators. One way to do
that is to define the operands as "lazy" so that they
are conceptually passed as a thunk and only evaluated
when referenced. If inlined, the thunk could be
optimized away, resulting in short circuit operators.

Also, the ability to overload the ?: operator is
desirable. That could be done by defining two binary
operators, operator:() which takes two parameters
returning a structure containing two lazily evaluated
parameters, and then operator ? which takes a boolean
expression and the above structure and returns one
element of the structure. Those operators would, of
course, have to have just the right precedence to work
together without messing up anything else, but that
shouldn't be a problem. Again, lazy evaluation shows
up here again, in this case as elements of a
structure. And, again, inline optimization would
normally eliminate the structure and thunks involved
to give the same result as the built in operator.

I suggest that immediately preceding the name of a
element, in a parameter list or structure with an "@"
symbol should indicate that the element is lazily
evaluated, and conceptually, when assignment to such
an element occurs, a "thunk" is created which will
evaluate it in the proper context. There might need to
be rules to ensure that such an element is not passed
out of the execution stack context (so that a stack
can still be used to invoke functions). However, if an
implementation used an activation record allocated
from the heap (potentially just as efficient as stack
allocation) and some form of garbage collection is in
used, then such a constraint could be relaxed.

But then, you could declare functions like...

   inline Boolean operator&&(
      Boolean  lvalue,
      Boolean @rvalue)
      {
      if (lvalue)
            if (rvalue)
                  return true;
               else
                  return false;
         else
            return false;
      }

which would provide the same short circuited result
for user defined classes as for the built in types.
And with inlining the thunk overhead should be
optimized away so that exactly the same code can be
generated.

Another way to handle ?: is to explicitly recognize it
as an overloadable operator (much cleaner than trying
to break it into two peaces) which accepts three
parameters. Then you could define...

   inline Integer operator?:(
      Boolean   choice,
      Integer   @trueValue,
      Integer   @falseValue)
      {
      if (choice)
            return trueValue;
         else
            return falseValue;
      }

This approach also has the benefit that lazy
evaluation only needs to be allowed in function
parameters, and so the calling stack problem doesn't
arise.

So, three features

   implicit constructors
   lazy evaluation for function parameters
   overloadable operator?:()

gets us much closer to the ability to be able to
define a user class with exactly the same behaviour as
one of the built in types which I consider to be
extremely important.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 02:12:24 GMT
Raw View
I want to eliminate the problem of the right shift
operator being undefined for signed operands. It
should result in a logical right shift for unsigned
operands and in an arithmetic right right for signed
operands. Since it is currently undefined, but the way
that it is normally implemented, this only helps to
pin down the definition of the operator.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 02:12:02 GMT
Raw View
Another idea.

Consider allowing '$' as part of an identifier
(already the case by almost all compilers as a
compiler option), but restrict it to only being used
for private or protected members of a class or struct.
This would help eliminate the very message "_" or
"my_" prefix frequently used to separate the
namespace. It also has the advantage that the compiler
can enforce the private/protected restriction and that
there is no potential conflict with either existing
code.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 02:12:11 GMT
Raw View
Also, how about allowing a function to qualified by
"stable" in the same way it can be qualified as
"const". The meaning of "stable" would be that the
function has no side effects other than optional side
effects to mutable data elements, and that two calls
to the function with the same parameter values will
result in exactly the same result.

This could be very useful in assisting the compiler to
eliminate unnecessary function calls by allowing it to
cache the result when it knows that the function call
might be needed again. This can already be done if the
function can be inlined and the optimize can see both
function invocations, but without extensive analysis,
the compiler cannot do the same thing for non-inlined
functions.

Obviously, the use of the keyword would be optional,
but if a pointer to a function is "stable" then any
function assigned to the pointer would also have to be
stable.

---
[ 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: Michael Lee Finney <michael.finney@acm.org>
Date: Fri, 4 May 2001 02:12:19 GMT
Raw View
Another change which would help structured code would
be to allow the case where a label immediately
precedes a "while", "do", "for" or "switch" statement
to be referenced by the continue and break statements.
For example:

   label: while (exp)
      {
      // some code
      continue label;
      // some code
      break label;
      }

This would allow multi-level break and continue
without having to use the goto statement. It doesn't
break existing code because the label is already
legal, and the continue and break statement do not
currently allow anything before the semicolon. So
allowing an optional label, which must have been
immediately placed before the start of the control
structure, would allow break and continue to handle
the multi-level situations.

It is better than using the goto statement because
there you would need two labels, one for the continue
and one for the break, and the trailing label is messy
and not very readable. It also explicitly replaces the
most common use of the goto statement so that the goto
statement can be used even less often than it is now.

---
[ 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: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 1 May 2001 18:25:49 GMT
Raw View
I am writing this sitting in a room at the Danish Standards in
Copenhagen listening to an evening presentation by Bjarne Stroustrup
launching his view of the next stage in the ongoing development of C++.
We have had a number of years (three or more) of stability with an ISO
Standard for C++ and failure to consider change will tend to move from
stability (good for many reasons) to stagnation (put your own spin on
that)

BS has just suggested that we should focus on a few major topics while
considering minor changes that will increase language and standard
library consistency.

He is floating the idea that the overall goals should include making C++
a better language for systems programming and library building. A second
major goal should be to make it easier to teach and learn (aside from me
-- we would still have the problem of getting those teaching to actually
know what they are doing)


Directions:

Minimise incompatibilities with C++98 but we should face reality and
accept that some changes will break exiting code (like the move form C
to C++)

Keep the zero overhead principle
Maintain or increase type safety

Avoid major extensions to the language
make rules more general and uniform
improve support for low level embedded programming (note BS explicitly
does not want to see C++ become an exclusively high level language)

Increase library support for platform independence
support distributed programming (actually, programming for distributed
systems)

He says that if we are ambitious in library development (something he is
advocating) we need to accept that some developments will not be
supportable on all platforms.

At this stage he is beginning to explore specific ideas for library
development. I will leave the specifics for later contributors to add.
The intention of this posting is to alert the serious C++ community to
the fact that the C++ standards committees are now willing to listen
(after a long day of working on defects in the current standard) to the
originator of C++ make suggestions for ways in which we might move
forward. You should not get the idea that we are about to launch a
basket of changes and destabilise what we have. What we are sitting on
is a watershed when we move from purely correcting and clarifying what
we have already done to considering how we might make the good even
better.

I am sure that BS's current presentation will be heard and refined many
times over the next few years. If you are responsible for organising
meetings, conferences or write for journals and magazines take the
opportunity to invite BS to contribute his vision of the future of C++.
But remember that this should be a shared vision. The readers of this
posting (here and copied to clc++m) are those that should be adding
clarity to the vision. We each have our own pet ideas, but we should
listen as well as talk. Change should come from a consensus of the C++
programming community in the large rather than just that of the
Standards Committees. That consensus requires an investment of time, any
time you find yourself muttering 'someone ought to do something about
that' remember that you are someone.

This writer can see a danger in some enthusiasts being so determined to
get their pet item into C++0x that they will be blind to the larger
picture.

I think that is enough for now apart from drawing your attention to the
fact that you read this here first and it was ACCU that brought it to
you attention.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Tue, 1 May 2001 22:27:12 GMT
Raw View
So, what do we want?

Let's start a list:

1. typeof()

2. using Base;
   Example:

     class Derived : private Base {
       public:
       using Base;  // expose the entire public interface of Base.
       // ...
     };

3. explicit operator.
   Example:

     class My_class {
       public:
       // ...
       // allow int(My_class()), but not int i = My_class();
       explicit operator int();
     };

4. Zero sized objects.
   This would require lengthof() because the standard idiom would break:

      #define lengthof(x) (sizeof(x)/sizeof((x)[0]))

   On the other hand, who puts zero sized objects in an array?

5. Require the "empty base class optimization".

6. Abolish trigraphs,
   or at least depreciate trigraphs.

What else?

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Howard Gardner <usenet@hgardner.com>
Date: Wed, 2 May 2001 01:27:47 GMT
Raw View
Francis Glassborow wrote:

> I am writing this sitting in a room at the Danish Standards in
> Copenhagen listening to an evening presentation by Bjarne Stroustrup
> launching his view of the next stage in the ongoing development of C++.

> Keep the zero overhead principle

For the love of humanity, define the value of a "default" constructed builtin!

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 2 May 2001 03:52:06 GMT
Raw View
Howard Gardner wrote:
>
> Francis Glassborow wrote:
>
> > I am writing this sitting in a room at the Danish Standards in
> > Copenhagen listening to an evening presentation by Bjarne Stroustrup
> > launching his view of the next stage in the ongoing development of C++.
>
> > Keep the zero overhead principle
>
> For the love of humanity, define the value of a "default" constructed builtin!

Compilers are free to do so, if you choose the overhead.  Right
now they/you have the choice between safety and efficiency.  If
the Standard mandates safety, efficiency will be impossible.

-- James Dennett

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Wed, 2 May 2001 15:25:44 GMT
Raw View

Dennis Yelle wrote:

> 2. using Base;
>    Example:
>
>      class Derived : private Base {
>        public:
>        using Base;  // expose the entire public interface of Base.
>        // ...
>      };

This is really clunky.   "using" brings names forward which have no
bearing on access control.  I'm at a loss as to what this does that
just inheriting Base publically doesn't.

>
> 3. explicit operator.
>    Example:
>
>      class My_class {
>        public:
>        // ...
>        // allow int(My_class()), but not int i = My_class();
>        explicit operator int();
>      };

Ugh...why not just add an explicit method.


> 4. Zero sized objects.
>    This would require lengthof() because the standard idiom would break:
>
>       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
>
>    On the other hand, who puts zero sized objects in an array?

I think it would break far more than ad-hoc size macros.  Why do you need
zero sized objects.

> 5. Require the "empty base class optimization".

Why?

>
> 6. Abolish trigraphs,
>    or at least depreciate trigraphs.
>
Why?  (and the word is deprecate).

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 2 May 2001 15:56:48 GMT
Raw View
In article <AcrV7JAEbv76EwYK@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>...Bjarne Stroustrup
>launching his view of the next stage in the ongoing development of C++.
...
>BS has just suggested that we should focus on a few major topics while
>considering minor changes that will increase language and standard
>library consistency.
>
>He is floating the idea that the overall goals should include making C++
>a better language for systems programming and library building. A second
>major goal should be to make it easier to teach and learn (aside from me
>-- we would still have the problem of getting those teaching to actually
>know what they are doing)

Amiss (even though mentioned below) in this general picture is support for
distributed programming.

Also amiss is support for dynamic programming, like support for the hooks
that enables the efficient implementation of a conservative GC (like a way
to get access to the root system.

One will need some such additions in order to be able to build good libraries.

As for the teaching aspect, I think this must be always secondary to the
aspect of C++ as a language designed to get things done. To me, it is OK
that C++ is a behemoth and an encyclopaedia one never bother learning in
its completeness: When one needs a feature.

If I should compare with Haskell, the standardization into a language
Haskell 98 which will never change was in itself enough for providing the
educational aspect.

One should warn against that looking too much on this educational aspect
one complicate the language: For example, the class std::list did not get
operator plus, because it was felt that less experienced programmers one
use that. Real programmers should use a profiler to determine what and how
to optimize. So in this case, the educational aspect made the language
more complicated and less based on general principles, the latter which
C++ is in the need of more.

>Directions:
>
>Minimise incompatibilities with C++98 but we should face reality and
>accept that some changes will break exiting code (like the move form C
>to C++)
>
>Keep the zero overhead principle
>Maintain or increase type safety
>
>Avoid major extensions to the language
>make rules more general and uniform
>improve support for low level embedded programming (note BS explicitly
>does not want to see C++ become an exclusively high level language)
>
>Increase library support for platform independence
>support distributed programming (actually, programming for distributed
>systems)
>
>He says that if we are ambitious in library development (something he is
>advocating) we need to accept that some developments will not be
>supportable on all platforms.
>
>At this stage he is beginning to explore specific ideas for library
>development.

In this support for distributed programming, there is hidden a C/C++
principle that one must depart from, namely that they are written so that
one from compiler to compiler never can specify the underlying binary
model: Even a byte, even though nowadays always a standard 8 bit, one
cannot rely on.

This problem shows up in other contexts: For example, if one tries to a
functional language style boxed/unboxed elements, that is screwed up by
the fact that when deriving one can never get ensurance where on the
object the class pointer is. Therefore, in principle, self-mutation of
unboxed elements into another type in the same memory location may screw
up.

The support for low level embedded programming is good: I expect embedded
programmers to be transformed into what is now regular C++ programmers as
the computers become more powerful. When this discussed in the C++
newsgroups, there was this joke about the bread machine with its own
WWW-site. But there is a fact that there is a standard to connect
household appliances to the Internet via the electrical cord. And if
memory doubles every year, then a bread machine that a few years had 50 kB
in its memory 10 years later will have 50 MB, and yet ten years later 50
GB, at which point it will be cheaper to let it have its own WWW site than
building a electro-mechanical interface on it.

Also, I think there is a connection between dynamic programming and low
level programming: In order to take an easy example, if one wants to build
a multi-precision number library, one needs to do a lot of low level
optimizations. As matters now stand, such things must be implemented
platform to platform in assembler. The implementation of functional
languages really need such low level optimizations in order to be
competitive with more static languages.

The more static C++ programmers of today will surely gradually become more
dynamic programmers when computers become more powerful, as dynamic
programming is requires less programming time. So for that reason, it will
be important to start to incorporate such features at this point in time.

So it would be great if such things could be done more directly in C++.
Perhaps ideas form a language like C-- should be integrated into C++.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Markus Schaaf" <m.schaaf.exp-jun2001@gmx.de>
Date: Wed, 2 May 2001 16:05:01 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote:

> Howard Gardner wrote:
>>
>> For the love of humanity, define the value of a "default" constructed builtin!
>
> If the Standard mandates safety, efficiency will be impossible.

I'm not even sure, if what you would get is safety. If you've
forgotten to initialize variables, why would zero be the _safe_
choice?

Most often I became aware of failure to set variables, in release
builds, when the compiler had omitted zero-initialization, and all
my programme's output was rubbish. Unfortunally there is a difference
between plausibility and correctness.

Just my 2 cents.

---
[ 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: "Scott Robert Ladd" <scott@coyotegulch.com>
Date: Wed, 2 May 2001 16:06:24 GMT
Raw View
Thanks for bringing this up; you've touched on some excellent points. I'm
impressed with Bjarne's recent efforts.

A few preliminary thoughts...

First, we need to look at the current standard and refine it, *before*
adding new features. Certainly we need to address all defect reports -- but
we also need to consider inconsistencies. My recent topic about openmode is
an example: It should be possible to interrogate the state of that property
for a stream. Is that a defect? Probably not. Is such a feature simple and
useful, leading to more reliable code? Yes.

Second: The more hands we get into the process, the more difficult it will
be to find a consensus. I know, I've been part of standards processes
before... everyone has a pet feature they'd love to have in the language,
and we don't want to lose focus. C++ should *not* try to be everything to
everyone; that's Java's job :-). Instead of adding anything and everything
to the language, I'd rather see a few new, well-conceived features. I want
concurrency, for example -- but if we can't find a clean, logical way to
include it in C++, I'll live without it.

Third: I strongly urge that we move beyond a poorly-formatted rigid document
to a hyperlinked, well-formatted, easy-to-read publication. Contrast the C++
Standard with W3C documents, and you'll see what I mean. A lot of confusion
and frustration could be solved simply by organizing and formatting the
document better.

Fourth: While I understand how standards committees work, most programmers
don't. The Standards process would do well to use the web actively in
keeping the community well-informed as to its activities. If we're going to
ask people to participate, they need to feel included, even if they can't
afford to travel. That is the strength of the Internet -- bringing people
together. Let's do it.

As for *my* personal laundry list of goodies -- give me a day or two here...
:-)

--
Scott Robert Ladd
Master of Complexity, Destroyer of Order & Chaos
http://www.coyotegulch.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                ]





Author: Howard Gardner <usenet@hgardner.com>
Date: Wed, 2 May 2001 16:34:07 GMT
Raw View
Markus Schaaf wrote:

>>> For the love of humanity, define the value of a "default" constructed builtin!
>>
>> If the Standard mandates safety, efficiency will be impossible.
>
> I'm not even sure, if what you would get is safety. If you've
> forgotten to initialize variables, why would zero be the _safe_
> choice?

It doesn't make the program correct (unless 0 really was the right value), it makes the resulting disaster easier to reproduce.  That, in turn, makes the error easier to find.

I can't count the hours I've spent tracking down uninitialized variable bugs (sometimes even my own) of one form or another.

As for the choice between efficiency and safety, you could add syntax to say "don't initialize."

int a = uninitialized;

or

uninitialized int a;

So it's really a choice between adding syntax and unreproducible bugs.

The way it sits many of us are paying for a feature (efficiency) that we don't use.

I bet instructors would like to get rid of the whole topic too, for that matter.


---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 2 May 2001 11:49:16 CST
Raw View
Markus Schaaf wrote:
>
> "James Dennett" <jdennett@acm.org> wrote:
>
> > Howard Gardner wrote:
> >>
> >> For the love of humanity, define the value of a "default" constructed builtin!
> >
> > If the Standard mandates safety, efficiency will be impossible.
>
> I'm not even sure, if what you would get is safety. If you've
> forgotten to initialize variables, why would zero be the _safe_
> choice?

Safe as in reproducible, at least.  I'm not an advocate
of making this change globally, but I can understand those
who want something like it.

> Most often I became aware of failure to set variables, in release
> builds, when the compiler had omitted zero-initialization, and all
> my programme's output was rubbish. Unfortunally there is a difference
> between plausibility and correctness.
>
> Just my 2 cents.

You can have 2 of mine to go with them.  I don't want to
globally mandate that

{
  int i;
  // ...
}

has the run-time overhead of initializing i.

-- James Dennett

---
[ 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: Robert FISHER <rfisher@my-deja.com>
Date: Wed, 2 May 2001 16:50:54 GMT
Raw View
Dennis Yelle wrote:
 >

> So, what do we want?
>
> Let's start a list:
>
[...good suggestions edited for brevity...]

>
> What else?
>

Finally: I understand that some think that everyone everywhere should
always, without exception (pun intended), use "resource acquisition is
initialization". Personally, however, I like the fact that C++ is a
multiparadigm language, and there are times when I'd find a finally
block extremely useful.

How about being able to place some restrictions on a class that are
enforced by the compiler. Non-derivable classes. Classes that can't be
placed on the stack/heap. Etc. Sure, there are some idioms that allow
some of these things to be done within the existing language, but they
are often verbose, inelegant, or both. (I want to say what I mean,
rather than say something that coincidentally has the side effect of
what I mean.)

How about a way to say that all of a class's member functions (and all
of its subclasses' member functions) should be virtual by default.

How about a (good, simple, portable, safe, efficient) way to tell
whether an object was allocated with new and can be safely deleted? (In
other words, not one of the kludges that have been created using the
existing language.) Imagine objects that can actually tell whether it is
safe to delete themselves or not. This might be the one thing I'd most
like to see.

(Also, a way to tell whether you should use delete or delete[] might be
useful. How about a way to find the size of an array allocated by new[].
Presumably the runtime has to keep track of such information anyway so
that delete[] works properly.)

The honorable Mr. Stroustrup has mentioned eliminating the default copy
constructor and assignment operator for classes with destructors and
making base classes with virtual member functions have a virtual
destructor by default. These will be very welcome changes.

Any remaining fix necessary to ensure that smart pointers can be
completely safe needs to be made. (I know there used to be some issues
about this.)

I'd ask anyone who has implemented an automatic garbage collector for
C++ what could be done to make C++ more garbage collector friendly.
(Last I looked into it, there was an issue or two.) Even better, ensure
that the major automatic garbage collection techniques can be
implemented in pure, portable C++. (Of course, such garbage collectors
would only be expected to collect C++ objects.)

Am I the only one that hates the standard library? The blatant, violent
abuse of operator overloading by the I/O streams has kept me from EVER
using them. I respect and admire the STL classes, but I hate using them
for reasons I haven't quite completely identified yet. Sure, it's too
late to make any radical changes, but I'd sure like to see an
"alternative standard library".

I also applaud Mr. Stroustrup's thoughts that the standard library
should address such common modern issues as concurrency. (And any holes
in the language that might make addressing such issues difficult.)

--
Robert FISHER
rfisher@my-deja.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                ]





Author: Dennis Yelle <dennis51@jps.net>
Date: Wed, 2 May 2001 20:12:28 GMT
Raw View
Howard Gardner wrote:
>
> Markus Schaaf wrote:
>
> >>> For the love of humanity, define the value of a "default" constructed builtin!
> >>
> >> If the Standard mandates safety, efficiency will be impossible.
> >
> > I'm not even sure, if what you would get is safety. If you've
> > forgotten to initialize variables, why would zero be the _safe_
> > choice?
>
> It doesn't make the program correct (unless 0 really was the right value), it makes the resulting disaster easier to reproduce.  That, in turn, makes the error easier to find.
>
> I can't count the hours I've spent tracking down uninitialized variable bugs (sometimes even my own) of one form or another.

What compiler are you using?
Have you turned on all of the warnings?

For this program:
===================
int main()
{
  int i;
  return i;
}
=================
MSVC++ 6.0 says:
  test.cpp(4) : warning C4700: local variable 'i' used without having
  been initialized

and gcc version 2.95.3 20010315/djgpp (release) says:
  test.cpp:3: warning: `int i' might be used uninitialized in this
  function

If you are using a compiler that cannot produce a warning for this,
I think you should change to a better compiler.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 2 May 2001 20:12:13 GMT
Raw View
Howard Gardner wrote:
>
> Markus Schaaf wrote:
>
> >>> For the love of humanity, define the value of a "default" constructed builtin!
> >>
> >> If the Standard mandates safety, efficiency will be impossible.
> >
> > I'm not even sure, if what you would get is safety. If you've
> > forgotten to initialize variables, why would zero be the _safe_
> > choice?
>
> It doesn't make the program correct (unless 0 really was the
> right value), it makes the resulting disaster easier to reproduce.
> That, in turn, makes the error easier to find.

I agree with that.

>
> I can't count the hours I've spent tracking down uninitialized
> variable bugs (sometimes even my own) of one form or another.

I spent several hours a couple of weeks ago tracking down an
uninitialized pointer bug in some third-party code.  A waste
of time, but it probably would have been no easier (maybe
even less easy) if the pointer value was 0 rather than garbage.

>
> As for the choice between efficiency and safety, you
> could add syntax to say "don't initialize."
>
> int a = uninitialized;
>
> or
>
> uninitialized int a;
>
> So it's really a choice between adding syntax and unreproducible bugs.

That's a "quiet change" though, in the sense that

int a;

changes meaning to become less efficient, and so billions of
lines of existing code become less efficient.

I'd prefer something like a Standard pragma (though historically
pragmas have been a pain) such as

#pragram STDC++ always-initialize

> The way it sits many of us are paying for a feature (efficiency) that we don't use.

And many of us don't want to pay for a feature (possibly more
easily reproducible bugs) that we don't use at the expense of
code which runs more slowly.

> I bet instructors would like to get rid of the whole topic too, for that matter.

That may well be true.

-- James Dennett

---
[ 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: "Stephen Howe" <SPAMstephen.howeGUARD@tnsofres.com>
Date: Wed, 2 May 2001 20:22:10 GMT
Raw View
Dennis Yelle <dennis51@jps.net> wrote in message
news:3AEF1353.87673842@jps.net...

> 4. Zero sized objects.
>    This would require lengthof() because the standard idiom would break:
>       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
>    On the other hand, who puts zero sized objects in an array?

For what benefit? I could imagine that disadvantages of it breaking code
outweighs any benefits.

> 5. Require the "empty base class optimization".

Currently, I cannot find examples where "optimisations" are a requirement of
the standard. Another example might be the requirement for return value copy
constructor optimisations. I don't think the standard should set a precedent
for compiler vendors to meet "optimisations" however desireable they are.

Stephen Howe




---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Wed, 2 May 2001 20:21:54 GMT
Raw View

Dennis Yelle wrote:
>
> So, what do we want?
>

My favorites, but unlikely to be implemented:

1.  Make arrays real types.
2.  Prohibit freebie const lossage on string literals.
3.  Initialize POD's consistantly.

---
[ 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: news/comp.std.c++@nmhq.net (Niklas Matthies)
Date: Wed, 2 May 2001 20:21:59 GMT
Raw View
On Tue,  1 May 2001 22:27:12 GMT, Dennis Yelle <dennis51@jps.net> wrote:
> So, what do we want?
>=20
> Let's start a list:
[=B7=B7=B7]
> 4. Zero sized objects.
>    This would require lengthof() because the standard idiom would break=
:
>=20
>       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
>=20
>    On the other hand, who puts zero sized objects in an array?

Could you elaborate how exactly you think that zero-sized objects should
be implemented? In particular, what layout would an array of zero-sized
objects have, and how would pointers to zero-sized objects behave?

-- Niklas Matthies

---
[ 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: "Radoslav Getov" <nospam@mai.com>
Date: Wed, 2 May 2001 20:22:06 GMT
Raw View
"Dennis Yelle" <dennis51@jps.net> wrote in message
news:3AEF1353.87673842@jps.net...
> So, what do we want?
>
> Let's start a list:
>
> 1. typeof()
>
> 2. using Base;
>    Example:
>
>      class Derived : private Base {
>        public:
>        using Base;  // expose the entire public interface of Base.
>        // ...
>      };
>
> 3. explicit operator.
>    Example:
>
>      class My_class {
>        public:
>        // ...
>        // allow int(My_class()), but not int i = My_class();
>        explicit operator int();
>      };
>
> 4. Zero sized objects.
>    This would require lengthof() because the standard idiom would break:
>
>       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
>
>    On the other hand, who puts zero sized objects in an array?
>
> 5. Require the "empty base class optimization".
>
> 6. Abolish trigraphs,
>    or at least depreciate trigraphs.
>
> What else?
>

- typeof

- some multithreading support (more order of evaluation garanties)

- final (disabling farther overriding of a virtual function)

- sized (int8 etc) or templated std::int<128> integers

- did I mention 'typeof'?

Radoslav Getov




---
[ 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: Daniel Frey <daniel.frey@aixigo.de>
Date: Wed, 2 May 2001 20:25:33 GMT
Raw View
Ron Natalie wrote:
>=20
> Dennis Yelle wrote:
>=20
> > 3. explicit operator.
> >    Example:
> >
> >      class My_class {
> >        public:
> >        // ...
> >        // allow int(My_class()), but not int i =3D My_class();
> >        explicit operator int();
> >      };
>=20
> Ugh...why not just add an explicit method.

No. An explicit method has a name like asXyz, toXyt, convertToXyZ,
conv2Xyz, as_xyz, to_xyz, convert_xyz and whatever comes to peoples
crazy minds. When working with templates, this is completely useless.
Also, asString() could return std::string, char*, RWCString or whatever
people think is *their* standard. We need explicit operators to allow
templates to use these functions. OTOH you cannot use cast-operators
without explicit because it's far too dangerous for most cases.

While we are at it, this could be used for other parameters too: void
hello( explicit const std::string& s ) could means: Don't convert
anything to string by creating a temporary object to call this function.
explicit for an operator is just like the explicit here but for '*this'.
Hope you get the idea, I'm not very good in expressing myself clearly in
english :)

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Wed, 2 May 2001 20:25:47 GMT
Raw View
Robert FISHER wrote:
[...]
> Am I the only one that hates the standard library? The blatant, violent
> abuse of operator overloading by the I/O streams has kept me from EVER
> using them. I respect and admire the STL classes, but I hate using them
> for reasons I haven't quite completely identified yet. Sure, it's too
> late to make any radical changes, but I'd sure like to see an
> "alternative standard library".

What are you looking for?
That is, how will you recognize it when you see it?
Is it just that the STL is too large?

The STL definitely has some warts.
Like, why does vector have all of:
size(), resize(), reserve(), and capacity()?

we could instead have:
  size_t size();
  void size( size_t);
  size_t capacity();
  void capacity( size_t);

And, to me, this would be easier to explain, learn, and remember.

But, I am not sure that it is worth changing at this stage.
But, then again, maybe it is.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 2 May 2001 20:26:03 GMT
Raw View
In article <zXTH6.143994$fs3.22936614@typhoon.tampabay.rr.com>, "Scott
Robert Ladd" <scott@coyotegulch.com> wrote:
> Instead of adding anything and everything
>to the language, I'd rather see a few new, well-conceived features. I want
>concurrency, for example -- but if we can't find a clean, logical way to
>include it in C++, I'll live without it.

This is also one thing that I think should be named in the general
picture: Concurrency support, not only for locks, but also for atomic
code.

But perhaps, if one adds support for distributed programming, concurrency
support must be a part of that.

>Third: I strongly urge that we move beyond a poorly-formatted rigid document
>to a hyperlinked, well-formatted, easy-to-read publication.

Actually, when I bought my copy I suggested the ANSI people just that. I
g   figure that this has something to do with the obsolete software used by
the ISO/ANSI staff, because hyperlinks ought to be automatic with the
right kind of authoring software.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Wed, 2 May 2001 20:29:19 GMT
Raw View
"James Dennett" <jdennett@acm.org> wrote in message
news:3AEF68FD.D09C520A@acm.org...
> Howard Gardner wrote:
> > For the love of humanity, define the value of a "default" constructed
builtin!
>
> Compilers are free to do so, if you choose the overhead.  Right
> now they/you have the choice between safety and efficiency.  If
> the Standard mandates safety, efficiency will be impossible.

Efficiency is not always the enemy of safety. Imagine C++ had a keyword
'uninitialized' that you could use like so:

void Fun()
{
    int i = uninitialized;
    int j; // initialized with zero
    ...
}

There are multiple advantages to this approach - defaults to safe, and
allows you to optimize when you need.


Andrei


---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Wed, 2 May 2001 20:29:34 GMT
Raw View

James Dennett wrote:
>
> I'd prefer something like a Standard pragma (though historically
> pragmas have been a pain) such as
>
> #pragram STDC++ always-initialize

Only if it is REQUIRED to be impelemented is this useful.  If it's
optional, the feature suddenly becomes VERY VERY DANGEROUS.   I suggest
that if we're going to have compile standardized compile controls that
they NOT be called PRAGMA.

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Wed, 2 May 2001 20:32:00 GMT
Raw View

Dennis Yelle wrote:
>
> Howard Gardner wrote:
> >
> > Markus Schaaf wrote:
> >
> > >>> For the love of humanity, define the value of a "default" constructed builtin!
> > >>
> > >> If the Standard mandates safety, efficiency will be impossible.
> > >
> > > I'm not even sure, if what you would get is safety. If you've
> > > forgotten to initialize variables, why would zero be the _safe_
> > > choice?
> >
> > It doesn't make the program correct (unless 0 really was the right value), it makes the resulting disaster easier to reproduce.  That, in turn, makes the error easier to find.
> >
> > I can't count the hours I've spent tracking down uninitialized variable bugs (sometimes even my own) of one form or another.
>
> What compiler are you using?
> Have you turned on all of the warnings?
>
> For this program:
> ===================
> int main()
> {
>   int i;
>   return i;
> }
> =================
\
Because this is a trivial instantiation of the problem.

How about

 int* i = new i;

and

 struct x {
  int i;
 };

The compiler will warn you of neither of these, typically.

---
[ 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: "Rene" <rene413@home.com>
Date: Wed, 2 May 2001 21:00:52 GMT
Raw View
What I don't understand is why it takes 6 years to make a change to a
programming language!! I am new to C++ so I don't want to open my mouth too
much, but as far as I know its been 3 years since the language settled, and
it looks like it will take 3 more to make changes. Then after the changes
had been decide on, we have to wait another year for the compiler people to
do their part and make it stable. In the mean time there are other
programming languages being created that are very innovating.

I don't mean to piss anybody off with this email; I just find it frustrating
to see technology advancing so fast and C++ just crawling.

Thank you.

---
[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: Wed, 2 May 2001 21:00:39 GMT
Raw View
On Wed,  2 May 2001 20:25:33 GMT, Daniel Frey <daniel.frey@aixigo.de>
wrote:

> No. An explicit method has a name like asXyz, toXyt, convertToXyZ,
> conv2Xyz, as_xyz, to_xyz, convert_xyz and whatever comes to peoples
> crazy minds. When working with templates, this is completely useless.
> Also, asString() could return std::string, char*, RWCString or whatever
> people think is *their* standard. We need explicit operators to allow
> templates to use these functions. OTOH you cannot use cast-operators
> without explicit because it's far too dangerous for most cases.

Writing templates is no problem.  Note that the standard library did
not write an explicit cast in copy to allow conversions.  It wrote
transform to accept a named conversion.

Can you give a concrete example to support your claim?

John

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 2 May 2001 21:19:48 GMT
Raw View
Ron Natalie wrote:
>
> James Dennett wrote:
> >
> > I'd prefer something like a Standard pragma (though historically
> > pragmas have been a pain) such as
> >
> > #pragram STDC++ always-initialize

(Oops, I see that can't type pragma.  Lack of practice.)

>
> Only if it is REQUIRED to be impelemented is this useful.

Absolutely.  (And that's a good reason not to call it pragma.)

> If it's
> optional, the feature suddenly becomes VERY VERY DANGEROUS.   I suggest
> that if we're going to have compile standardized compile controls that
> they NOT be called PRAGMA.

Well, as we like over-using existing keyword, how about
"auto intialize;" at namespace scope?

That's a joke: I would like to see a Standard mechanism
to allow evolution, such that a compiler which fails to
support feature X can be detected at compile-time even if
only by the fact that it aborts compilation with an
"unsupported feature requested" message.

-- James Dennett

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Wed, 2 May 2001 22:35:50 GMT
Raw View
Andrei Alexandrescu wrote:
>
> "James Dennett" <jdennett@acm.org> wrote in message
> news:3AEF68FD.D09C520A@acm.org...
> > Howard Gardner wrote:
> > > For the love of humanity, define the value of a "default" constructed
> builtin!
> >
> > Compilers are free to do so, if you choose the overhead.  Right
> > now they/you have the choice between safety and efficiency.  If
> > the Standard mandates safety, efficiency will be impossible.
>
> Efficiency is not always the enemy of safety. Imagine C++ had a keyword
> 'uninitialized' that you could use like so:
>
> void Fun()
> {
>     int i = uninitialized;
>     int j; // initialized with zero
>     ...
> }
>
> There are multiple advantages to this approach - defaults to safe, and
> allows you to optimize when you need.

Yes, I think you are right.
It is time to do this.
Compilers are already doing the analysis to determine that
most variables are already initialized before being used.
The only time that this would add runtime overhead is when
that compile time analysis fails, which is fairly rare.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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: Dennis Yelle <dennis51@jps.net>
Date: Wed, 2 May 2001 22:45:10 GMT
Raw View
Niklas Matthies wrote:
>=20
> On Tue,  1 May 2001 22:27:12 GMT, Dennis Yelle <dennis51@jps.net> wrote=
:
> > So, what do we want?
> >
> > Let's start a list:
> [=B7=B7=B7]
> > 4. Zero sized objects.
> >    This would require lengthof() because the standard idiom would bre=
ak:
> >
> >       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
> >
> >    On the other hand, who puts zero sized objects in an array?
>=20
> Could you elaborate how exactly you think that zero-sized objects shoul=
d
> be implemented? In particular, what layout would an array of zero-sized
> objects have,

A single zero sized object would have a sizeof 0.
An array of zero sized objects would have a sizeof 0.

Or to put it another way:

  struct nothing {};
  assert ( 0 =3D=3D sizeof(nothing) );
  nothing junk[10000];
  assert ( 0 =3D=3D sizeof( junk));
 =20
> and how would pointers to zero-sized objects behave?

When you increment them, decrement them, or add (or subtract)
a size_t to (from) them, they do not change.

Dennis Yelle
--=20
I am a computer programmer and I am looking for a job.
There is a link to my resume here: =20
http://table.jps.net/~vert/

---
[ 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: Ron Natalie <ron@spamcop.net>
Date: Wed, 2 May 2001 23:05:10 GMT
Raw View

Dennis Yelle wrote:
>
> When you increment them, decrement them, or add (or subtract)
> a size_t to (from) them, they do not change.
>
And the use of this nothingness is?

---
[ 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: James Dennett <jdennett@acm.org>
Date: Wed, 2 May 2001 23:40:31 GMT
Raw View
Ron Natalie wrote:
>
> Dennis Yelle wrote:
>
> > 2. using Base;
> >    Example:
> >
> >      class Derived : private Base {
> >        public:
> >        using Base;  // expose the entire public interface of Base.
> >        // ...
> >      };
>
> This is really clunky.   "using" brings names forward which have no
> bearing on access control.  I'm at a loss as to what this does that
> just inheriting Base publically doesn't.

It disallows most conversions from Derived to Base, hence
avoiding problems (e.g.) with non-virtual destructors.

> > 3. explicit operator.
> >    Example:
> >
> >      class My_class {
> >        public:
> >        // ...
> >        // allow int(My_class()), but not int i = My_class();
> >        explicit operator int();
> >      };
>
> Ugh...why not just add an explicit method.

Generic programming can't reasonably know the name of the explicit
method, whereas various casts are almost univerally usable for
conversions.

> > 4. Zero sized objects.
> >    This would require lengthof() because the standard idiom would break:
> >
> >       #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
> >
> >    On the other hand, who puts zero sized objects in an array?
>
> I think it would break far more than ad-hoc size macros.  Why do you need
> zero sized objects.

I can't see what this gains us either.

> > 5. Require the "empty base class optimization".
>
> Why?

How?  As in, how would you word this requirement?

-- James Dennett

---
[ 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                ]