Topic: Where next for Standard C++?


Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/11/25
Raw View
Colin Rafferty <craffert@ml.com> wrote:

>If you are arguing that post-constructor would be handy, I wouldn't
>disagree with you.  Of course, I would argue that it shouldn't be a part
>of C++ since it makes the language more complicated for a minor
>convenience.
>
[ much deleted ]
>
>This could be a neat extension, but I just think that it will complicate
>things needlessly.

At first I liked the idea, but now I think I agree with Colin. Here is a
way to get the effect of a post-constructor without a language
extension. Notice that this is not "fun" the way language extensions are
"fun," but it gets the job done. I agree with others who say that in
*most* (but not all) cases, the need for a post-constructor points out a
design deficiency. I think the technique below should suffice for the
remaining few cases where it is not a design deficiency or where it is
too late to fix the overall design.

class Base
{
  public:
    Base(arg1 a1, arg2 a2, bool isMostDerived = true)
    {
      // ... Do stuff here ...

      // Now the post-constructor:
      if (isMostderived)
        postConstruct();
    }

  protected:
    // Make this pure-virtual if you want an abstract base class:
    virtual void postConstruct();
};

class Derived : public Base
{
  public:
    Derived(arg1 a1, arg2 a2, arg3 a3, bool isMostDerived = true)
      : Base(a1, a2, false)  // ***** NOTE: pass false to base *****
    {
      // ... Do stuff here ...

      // Now the post-constructor:
      if (isMostderived)
        postConstruct();
    }

  protected:
    // Optionally override postConstruct:
    // virtual void postConstruct();
};

In the above case, an extra boolean parameter added to each constructor
argument list. By default it is true, meaning that this is the
most-derived class and that the post-constructor should be called. The
derived classes always pass false to their base-class constructors so
that the base class doesn't call the post-constructor. At the end of the
derived-class constructor, it calls the post-constructor (if it is the
most-derived class).

This technique requires discipline and documentation, but is not so
complicated that a language extension is needed.

Destructors are slightly more difficult, since we don't have function
aruments to use for booleans:

class Base
{
    // ...
  protected:
    bool preDtorCalled;
    virtual void preDestructor();
  public:
    ~Base()
    {
       if (! preDtorCalled)
       {
         preDestructor();
         preDtorCalled = true;
       }

       // ... Other stuff here ...
    }
};

The derived class has basically the identical mechanism except it does
not re-declare preDtorCalled.

-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Sergei Organov <osv@javad.ru>
Date: 1997/11/27
Raw View
Pablo Halpern wrote:
> At first I liked the idea, but now I think I agree with Colin. Here is a
> way to get the effect of a post-constructor without a language
> extension. Notice that this is not "fun" the way language extensions are
> "fun," but it gets the job done.
> [...skip...]

Unfortunately the solution you suggest doesn't solve the initial problem.
Post-constructors were proposed to don't _force_ user of class (including
derived class designer) to _know_ that some routine should be called after
the end of construction. For me it still seems to be impossible without
language extensions.

BR,
Sergei
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jodle@bix.com (jodle)
Date: 1997/11/22
Raw View
I would like to see compile-time exceptions added to the language.  This
is a feature that I've been pondering for some time.  Consider the
following commmon practice:

  class SomeObjects {
    SomeObjects(); SomeObjects( const SomeObjects & );
    pubic:
    SomeObjects(int in);
    };

This is the time-honored (dare I call it the) Myers' Defense against
accidental construction.  It defends against users calling these
constructors but not prevent the member functions themselves from
performing the implicit conversions.

The language already provides 'explicit' as a means of defending against
implicit use of a function, but not explicit use.  A function must be both
private and explicit for that.  One feature that might come closer to the
kind of support I'd like would be a keyword like 'illegal'.  Witness:

  ...
  SomeObjects() explicit;
  SomeObjects( const SomeObjects & ) illegal;
  ...

Instead of the message "function X is not accessible" the compiler could
better indicate "the class has declared your call to function X to
be patently illegal."  That's the tip of this feature's iceberg.  Further
witness use of a sizeof-style 'illegal' operator.

  ...
  SomeObjects() illegal("what, you expect maybe I should initialize to '0'?");
  SomeObjects( const SomeObjects & ) illegal("you've got to be kidding...");
  SomeObjects( void* ) illegal("try a different constructor");
  ...

where use of the functions could result in messages like "simon sez: try a
different constructor."

Now the strawman.  I have not fully examined this notion and offer it as a
sacrifice to a superior idea, should anyone have one.  I desire support
for examining some kind of compile-time conditional coupled with this
'illegal' feature.  This, of course, may predicated on the replacement of
the C preprocessor that Stroustrup et al have relegated to the doghouse
for years but never actually superceded with a better offering.  I like
what Eiffel does with preconditions but I believe Eiffel's examination of
preconditions is performed at runtime and is nonsymbolic in nature.
Witnesseth:

  ...
  int Start() postcondition( STARTED );
  int Procede() precondition( STARTED ), postcodition( PROCEDING );
  int Stop() postcondition( !STARTED, !PROCEDING);
  int IllegalStat() precondition
    ( STARTED ||
    illegal("see <A HREF=\"http://docs/reuse/someobjects.htm"></A>") );
  ...

First, let me call to attention the way 'illegal' is used as a side-effect
in the evaluation of the apparent condition of the object.  I apologize
to all the Perl fans for borrowing this style.  This is the best example
I can think of to illustrate the role of 'illegal' in medium and
large-scale development.  It allows developers to codify the
relationship between specific structures in the software and other
resources in a project.  It allows the developer of a component to
convey specific error metadata to a user.

 The precondition/postcondition feature can be viewed as either a
compile-time only or compile-and-runtime supported feature.  I think the
former is more in keeping with the spirit of C++, but exception
handling provides the basic structure needed for runtime support.  The
feature allows the compiler to prevent the following use of SomeObjects:

  SomeObjects().Procede() // ERROR! It's obvious that we've not STARTED

The obvious weakness lies in contexts where it may not be clear that the
condition of the object has changed:

  void DoThingsTo( SomeObjects & ) { ... }

  ...
  SomeObjects s;
  DoThingsTo( s );
  s.Procede();      //  ...and what is the condition of s exactly?

Furthermore, a single block could confuse the issue even further.

  SomeObjects s;

  if( someConditionUndeterminableAtCompilation )
    s.Start();

  s.Procede();

Now the condition of 's' is variant.  What do we want from the compiler?
Is the program ill-formed?  Does the compiler complain that s MAY NOT be
started (after all, we don't want to procede in an unstarted condition...)
and produce object code?  What does that object code look like?  The
compiler has enough information (if not enough inteligence)
to generate code equivalent to:

  SomeObjects s;

  if( some_Condition_Undeterminable_During_Compilation )
    {
    s.Start();
    s.Procede();
    }
  else
    throw BadCondition( s, STARTED );

...which with respect to the condition of S is rigidly invariant.

I hope I've effectively described what I'm after: some support from the
compiler in expressing a framework of formal, SYMBOLIC (as opposed to
value-oriented) conditions that reduce the introduction of faults into a
program.  It's the sort of feature that would benefit me in my current
work and a large number of large-scale developers that develop code in
aeronatics, astronautics and telecommunications.

What do we all think?
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1997/11/25
Raw View
--Multipart_Mon_Nov_24_14:02:56_1997-1
Content-Type: text/plain; charset=US-ASCII

jodle@bix.com (jodle) writes:

>
> The language already provides 'explicit' as a means of defending against
> implicit use of a function, but not explicit use.  A function must be both
> private and explicit for that.  One feature that might come closer to the
> kind of support I'd like would be a keyword like 'illegal'.  Witness:
>
>   ...
>   SomeObjects() explicit;
>   SomeObjects( const SomeObjects & ) illegal;
>   ...
>
> Instead of the message "function X is not accessible" the compiler could
> better indicate "the class has declared your call to function X to
> be patently illegal."  That's the tip of this feature's iceberg.  Further
> witness use of a sizeof-style 'illegal' operator.
>
>   ...
>   SomeObjects() illegal("what, you expect maybe I should initialize to '0'?");
>   SomeObjects( const SomeObjects & ) illegal("you've got to be kidding...");
>   SomeObjects( void* ) illegal("try a different constructor");
>   ...
>
> where use of the functions could result in messages like "simon sez: try a
> different constructor."
>

How about:

   SomeObjects( void* ) warning("SomeObjects is obsolete, use"
    " FancyObjects for new code.");

Yes, I know that the standard *currently* only talks about
"diagnostics", with no difference between warnings and errors.  This
could be changed.



--Multipart_Mon_Nov_24_14:02:56_1997-1
Content-Type: text/plain; charset=US-ASCII

 __  __  _
 _ ) ___ _\
 __) __    \  Enterprise Middleware Solutions Darron J. Shaffer
              BEA Systems Inc.   Sr. Software Engineer
              17101 Preston Rd   darron.shaffer@beasys.com
              LB# 115, Ste 260    Voice: (972) 738-6137
              Dallas, TX 75248    Fax:   (972) 738-6111
       http://www.beasys.com

--Multipart_Mon_Nov_24_14:02:56_1997-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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/21
Raw View
On 19 Nov 97 10:13:21 GMT, "Stephen C. Gilardi"
<squeegee@spambegone.usa.net> wrote:

>In article <34730657.105067724@engnews1.eng> Steve Clamage,
>stephen.clamage_nospam@eng.sun.com writes:
> >You can do this:
> >
> >class T {
> > int h, w, d;
> >public:
> > T& height(int i = default_height) { h = i; }
> > T& width(int i = default_width) { w = i; }
> > T& depth(int i = default_depth) { d = i; }
> > void doSomething(); // uses h,w,d instead of parameters
> >};
> >
> >Now you can write things like these for some T object t:
> >
> >t.height().width(11).depth(12).doSomething(); // default height
> >t.width(12).depth(12).height(19).doSomething(); // arbitrary order
>
>Doesn't each inline function definition need to end with "return *this"?
>
>Like:
>
> > T& height(int i = default_height) { h = i; return *this; }

Oops. Yes, of course.

I also should have pointed out some limitations of the code I posted.
It won't work properly if doSomething gets called recursively or
reentrantly on the same object.

A more flexible approach would be a function object for doSomething,
so that every call would involve a unique object.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Stephen C. Gilardi" <squeegee@spambegone.usa.net>
Date: 1997/11/19
Raw View
In article <34730657.105067724@engnews1.eng> Steve Clamage,
stephen.clamage_nospam@eng.sun.com writes:
 >You can do this:
 >
 >class T {
 > int h, w, d;
 >public:
 > T& height(int i = default_height) { h = i; }
 > T& width(int i = default_width) { w = i; }
 > T& depth(int i = default_depth) { d = i; }
 > void doSomething(); // uses h,w,d instead of parameters
 >};
 >
 >Now you can write things like these for some T object t:
 >
 >t.height().width(11).depth(12).doSomething(); // default height
 >t.width(12).depth(12).height(19).doSomething(); // arbitrary order

Doesn't each inline function definition need to end with "return *this"?

Like:

 > T& height(int i = default_height) { h = i; return *this; }

--Steve

Stephen C. Gilardi
SQ Software
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: skaller@zip.com.au (John (Max) Skaller)
Date: 1997/11/09
Raw View
On 07 Nov 97 19:16:52 GMT, Christopher Eltschka
<celtschk@physik.tu-muenchen.de> wrote:

>>         template<class T1, class T2> T3 add(T1 t1, T2 t2) {
>>                 return t1 + t2;
>>         }
>>
>> which even "typeof" cannot solve.

>Oh yes, it can:
>
>template<class T1, class T2>
> typeof( *(T1*)0 + *(T2*)0 ) add(T1 t1, T2 t2)
>{
>  return t1+t2;
>}

 I take it all back!! Thanks!

John Max Skaller                ph:61-2-96600850
mailto:skaller@zip.com.au       10/1 Toxteth Rd
http://www.zip.com.au/~skaller  Glebe 2037 NSW AUSTRALIA
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: John Aldridge <jpsa@jjdash.demon.co.uk>
Date: 1997/11/09
Raw View
In article <34601667.A2163422@ix.netcom.com>, "Paul D. DeRocco"
<pderocco@ix.netcom.com> writes
>The situation that occasionally arises that makes me
>wish for nested functions is the situation I described in my
>earlier post, where I have a rather large function that includes
>a particular bit of code over and over again within it.
  :
>If I try to break the
>repeated code off into a separate function, I wind up having to
>pass a whole bunch of parameters (or at best, one pointer to an
>artificially concocted struct containing the necessary
>parameters) to the separate function, thus sacrificing much of
>the potential efficiency.

I've been through this cycle a few times converting Ada (which has
nested functions) to C++.  What seems often to happen is that I start
out inventing a struct containing the necessary parameters and passing
it around.  It then seems natural to make the function in question a
member function of that struct.  Then I notice that many of the other
functions in the source file naturally become member functions, too.
Then I can make the variables private, and turn the struct into a proper
class (often called ParseContext, or something like that).  In the end,
I find that the class I've ended up with is not at all artificial, and
that the new code is a better design than the old.

I'm not claiming that this will always be the case, but in most of the
cases I've encountered, it has been.
--
Cheers,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 1997/11/09
Raw View
Pablo Halpern wrote:
>
> James Kuyper <kuyper@wizard.net> wrote:
>
> >If they had thought about it adequately, they should at least have named
> >it _longlong, rather than 'long long'. I would have preferred them to
> >call their 64 bit type 'long', but I can understand that they needed to
> >cater to a large body of non-conforming code.
>
> Ah, yes, they could call it 'long', but then we might want a term for
> the 32-bit type.  How about 'medium' or 'short long' %-/

And why shouldn't it be called 'int'?  I've seen this question come up
before; either I can't count correctly, or there are several other
people who can't count correctly; I'm biased in favor of the second
option.

There are 4 widely popular integral type sizes on 8-bit machines: 8 bit,
16 bit, 32 bit, and 64 bit. There are 4 standard signed integral types
in C89: signed char, short, int, and long. The number of available types
is an argument for 'long long' only if you insist on redundantly
assigning
two of the standard types to the same length. Many people do so insist,
in order to protect the large body of code that has made un-portable
assumptions about type sizes. I reluctantly concede the practical
necessity of catering to such poorly written code. However, I'm getting
tired of people implying that 4 standard types are insufficient to
represent 4 different type sizes.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
Colin Rafferty wrote:
>
> Christopher Eltschka writes:
> > Colin Rafferty wrote:
> >> Sergei Organov writes:
> >> > Mirek Fidler wrote:
>
> >> >> > How about, let's call them, 'post-constructors' and 'pre-destructors'?
>
> >> >> > The idea is to allow one to declare member function in base class to be
> >> >> > called automatically after the most derived constructor returns ('post-
> >> >> > constructor'); or before the most derived destructor is called
> >> >> > ('pre-destructor'). Because unlike constructors and destructors these
> >> >> > functions are invoked on fully constructed objects, the dynamic binding
> >> >> > could safely be used for virtual function calls.
>
> >> >> I am afraid this violates constructors/destructor idea in its bases.
> >> >> Thus said, if you need these, there is possibly something wrong with
> >> >> your class hierarchies ;-)
>
> >> I couldn't have said it better myself :-).
>
> >> > I thought this idea has nothing to do with "constructor/destructor idea
> >> > in its bases". The idea behind const/dest is left unchanged, I think.
>
> >> The problem is inherent in the following two facts.  The first is the
> >> way C++ currently works (and must continue to work).  The second is the
> >> way that C++ will work with the post-constructor.
>
> >> 1. The constructor of a derived class may use its base class.
>
> >> 2. An object that has not had its post-constructor called is not
> >> completely constructed (in a logical sense).  If it were, it wouldn't
> >> have needed a post-constructor.
>
> >> Therefore, a partially-constructed object could be manipulated by an
> >> instance of its derived part.
>
> >> For example, imagine a hierarchy that includes the following definition:
>
> >> class Derived : public Base { /* ... */ };
>
> >> Imagine also that class Base has a post-constructor.
>
> >> If the `Derived' constructor tries to use the `Base' part of itself, the
> >> results will be erroneous, because Base::post_constructor() has not yet
> >> been called.
>
> >> If the results could not be erroneous, then the post-constructor is
> >> unnecessary.
>
> > What you are missing is that objects are no standalone entities, but
> > stand in relation to other objects in the program.
>
> I am not missing it at all, thank you.  I simply chose to argue that, in
> general, post-constructor solves absolutely nothing.
>
> In my previous post (see above), I described a general problem that
> post-constructor introduces.  Below your description of a particular
> problem, and how post-constructor seems to solve it, I will demonstrate
> how it does not really do this.
>
> > For example, an
> > object could provide a service. Now there might be another object that
> > informs which objects can give you which sort of service. This other
> > object needs to be notified about the new object, but of course only
> > when the object is fully constructed (else someone would possibly try
> > to contact the half-constructed object).
>
> > Thus you can characterize the different stages as the following:
>
> > 1. The constructor (completely) constructs the object.
> > 2. The post-constructor puts the newly constructed object in relation
> >    to the rest of the program (f.ex. registering it)
> > 3. The pre-destructor disconnects the object from the rest of the program
> > 4. The destructor destructs the object.
>
> Picture the same class hierarchy as above (Derived derived from Base).
> We say that Base needs to register itself in its post-constructor.
>
> Now imagine that the implementor of Derived wanted to use the same
> post-constructor trick in order to finish logically constructing itself.
> If it has its virtual function `f' called on it before it is
> post-constructed, the result will be undefined.
>
> 1. Base::ctor() called on object X.
> 2. Derived::ctor() called on object X.
> 3. Base::post-ctor() called on object X.  Base registers itself in the
>    global registry.
> 4. In another thread, something gets X out of the registry, calls
>    virtual function `f'.
> 5. Derived::post_ctor() called on object X.
>
> You can see that the result of Step 4 is undefined.
>
> We have not solved the problem for real.  We have simply deferred it to
> the post-constructor.
>
> So what is the solution to the registry/thread problem?  I don't know, I
> haven't done enough thread programming to answer this.  However, it
> seems
>
> Maybe the problem is that you should rethink how you are managing your
> objects in the first place.  Maybe the regsitry should be creating them
> itself, rather than having them scattered about.

Well, the registry is for *other* objects reaching the object,
*not* for the object itself being functional. That is, after
construction, the object itself works properly, but is not
"reachable" from the rest of the program. The post-construction
then sets up the way other programs can reach it.
In the current C++, the assigning return value of new could be
seen as "post-construction": It makes the newly created object
usable by the rest of the program, not by changing it, but by
changing something outside the object (the variable). Similar,
the post-constructor of an object would make the object accessible
f.ex. by changing a registry.
I'd say that after construction, the object should in any case
fulfil its invariants (that is, already now all the methods may be
called without harm), and after post-construction, it should also
be completely reachable (that is, other parts of the program are
*able* to call its methods, because they are in some way notified
about its existence - f.ex. by putting in a registry, or by starting
a thread and creating a message queue).

Given this interpretation, I'd also say that const objects should
already be const when the post-constructor is entered.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
Fergus Henderson wrote:

[...]

> Of course, that fact that it is possible does not necessarily mean
> that it is a good idea.  I still think that nested functions are a
> good idea, and that pointers to nested functions are very useful,
> but C++ is already a quite complex language, and at the moment
> implementors seem to be struggling to keep up with the draft...
> it might be better for them to spend their efforts on improving
> existing features (better warnings, more efficient code generation,
> etc.) rather than adding new features that may be complicated to implement,
> even if those features are simply removal of restrictions (which might
> in fact _reduce_ language complexity from a user's perspective).

Well, as this thread is about what should be considered at the *next*
standardisation round (which is quite a few years in the future),
I really hope that until then the implementors are up with 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
J. Kanze wrote:
>
> micha@aishdas.org writes:
> > On 30 Oct 97 08:07:58 GMT, Mark Zeren <zeren@pobox.com> wrote:
> > : I'm not sure why overriding the dot operator should be so ridiculous.
> >
> > How then would you ever refer to the real member b of object a? At least
> > if pa->b is overloaded I can fall back on (*pa).b. Perhaps "(&a)->b" if
> > not overloaded?
> >
> > It would seem that you are hiding all non-operator members from any context
> > outside the object defintion.
>
> It would seem as if you answered your own question: "(&a)->b" would do
> the trick.  Now of course, if you overloaded (unary) operator& as
> well...
>

If the class were considered to mimic real references, you would
overload operator&. Indeed, *every* operator would need to be
overloaded, if the target class has it.

> Note that within member functions, referring to a member without using
> explicit this-> always accesses the member, regardless of what
> overloadings might be present.  Similarly, operator overloading would
> still get member functions -- this is important, for example, in the
> case of operator= (as well as, obviously, the new operator.:-).  The
> "normal" use for operator. would be to create a smart reference (in the
> same way as you use operator-> to create a smart pointer) -- in such
> cases, you would never want to access a member outside of a member
> function anyway.

The interesting part would be the copy constructor:

SmartRef::SmartRef(const SmartRef& other):
  referent(other.referent),
  counter(other.counter)
  // use of other.operator.() *not* intended...
{
  (*counter)++;
}

Maybe, explicit qualification would be a solution:

SmartRef x;

x.f();  // calls x.operator().f()
x.SmartRef::f(); // calls x.f()
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
Mirek Fidler wrote:
>
> > Another thing I think is inexcusable is that C++ doesn't allow
> > nested functions.
>
>    Actually, I think this is an advantage of C++ for both run time
> efficiency (you would need much more complicated stack frames for that)
> and design. Most of need of nested functions was removed by introducing
> private class methods.
>
> Mirek

Global functions wouldn't need to change their stack frame at all,
and local functions would need just one extra parameter (the
stack frame of their parent function) - which should not be less
efficient than the hidden this pointer. Yes, nesting _more_ than
one level would be more costly - but this will be needed very
seldom - if ever -, so the cost here doesn't hurt much (and, in
addition, this extra cost can be limited to the case where variables
of the "grand parent" function or above in the nesting are
accessed - see f.ex. the Borland Pascal implementation for nested
functions).
So, the cost of a typical local function would be the same as for
a member function. But some cost of function objects (notably
copying of local vars or pointers/references to them into the
class) could be avoided.
Pointers to local functions are another subject.
BTW, *if* a compiler implements "normal" pointers to local
functions, I'd also like to have the following: Given a class,
and a member function pointer to that class, produce a normal
function pointer for this particular member of the particular
class (that would work the same way as with local function
pointers, with the frame pointer replaced by the object pointer).
This could f.ex. be achieved with an operator.&:

class A
{
public:
  double f(double);
  double operator()(double);
};

typedef double(*fp)(double);

A a;
fp fp1=a.&f;
fp fp2=a.&operator();

extern "C" integrate(double(*f)(double), double start, double fin);

int main()
{
  fp1(x);                  // equivalent to a.f();
  integrate(fp2, 0.5, 3);  // fn object called by C function!
  return 0;
}

It would be a good idea to have operator->& as counterpart.
Also, operator.& and operator->& should work for ordinary members
as well; there they would work like the following:
class A
{
public:
  int ai;
};

A a;
A* pa=&a;

int* i=a.&ai;   // equivalent to &(a.ai)
int* j=pa->&ai; // equivalent to &(a->ai)

As easily seen, for member vars it doesn't introduce something new,
but it should be defined anyway, for consistency.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
micha@aishdas.org wrote:
>
> On 28 Oct 97 17:03:55 GMT, Darron Shaffer <darron.shaffer@beasys.com> wrote:
> :   2)  Add some tokens for new NON DEFINED operators.
>
> How do you define precedence and associativity for these things?

The simplest choice would be *no* precedence and associativity.
That is, you explicitly have to use brackets every time you use them:

X operator @op(X, X);
X operator+(X, X);

X b,c,d;
b @op c;          // ok
b @op c @op d;    // error: @op has no associativity
(B @op c) @op d;  // ok
b @op (c @op d);  // ok
b + c @op d;      // error: @op has no precedence
(b + c) @op d;    // ok
b + (c @op d);    // ok

This way, you could allow arbitrary operators of the form
@<identifier>, without giving any confusion about precedence
or associativity.

Of course, this would be merely syntactic sugar, but I think
very useful one. Consider f.ex.:

class Vector;

Vector operator @cross(const Vector&, const Vector&);
double operator @dot(const Vector&, const Vector&);

or:

class Range {...};
class String {...};

Range operator @to(int, int);
Range operator @size(int, int);

String s1="Hello world";
String s2=s1(2 @to 4);   // "llo"
String s3=s1(4 @size 5); // "o wor"

One problem would still remain: How to decide if an unary operator
is prefix or postfix? IMHO, there should be a new keyword postfix,
and unary operators without this should be prefix. This could
also replace the unintuitive dummy int for postfix operator++/--
(of course it would still be allowed for compatibility).

There should also be the possibility to define unary operators
with the same name as binary ones, f.ex.:

Range operator @to(int); // prefix
Range postfix operator @to(int); // postfix

String s4=s1(@to 4);  // "Hello"
String s5=s1(6 @to);  // "world"

That it is possible is proven by the std C/C++ itself, for related
operators like unary minus/binary minus, as well as for unrelated
ones like pointer dereference (unary *)/multiplication (binary *).
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: boukanov@sentef1.fi.uib.no (Igor Boukanov)
Date: 1997/11/11
Raw View
Christopher Eltschka (celtschk@physik.tu-muenchen.de) wrote:
> BTW, *if* a compiler implements "normal" pointers to local
> functions, I'd also like to have the following: Given a class,
> and a member function pointer to that class, produce a normal
> function pointer for this particular member of the particular
> class (that would work the same way as with local function
> pointers, with the frame pointer replaced by the object pointer).

But that can be in principle implemented without language extensions with
a help of the on-fly code generation. I.e. I do not think it is very hard
to write a class that would produce from a pointer to a function with
one argument a pointer to a function without arguments. For example,
a convertion "void (*)(T*) -> void (*)()" on many platforms can be done
via:


typedef void (*out_pointer)();

template<class T> class pointer_converter
{
   unsigned char buffer_for_on_fly_generated_code[...];
   public:
      typedef void (*in_pointert)(T*);
   public:
      pointer_converter(in_pointer f, T* additional_argument) {
        put to buffer code that would call f with additional_argument
      }

      out_pointer get_out_pointer() {
         return (out_pointer)buffer_for_on_fly_generated_code;
      }
}

The usage is simple:

void enumerate(void (*callback)());

void my_callback(T* t);

...
{
  T t;
  pointer_converter<T> converter(my_callback, &t);
  enumerate(converter.get_out_pointer());
  // to call my_callback with argument &t
}


The point is simple here - an implementation of such class would
be totally different for diffrent platforms that is why wrappers
like that for different situations (pointers to member function etc.)
should be in standard libraries.

BTW, given the choice: nested function or such wrappers in C++ I would prefer
the second option...

--
Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/07
Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:

|>  J. Kanze wrote:
|>  >
|>  > Actually, the CLASSICAL alternative is:-):
|>  >
|>  >     void
|>  >     foo()
|>  >     {
|>  >         char buffer[ 256 ] ;
|>  >         int xbuf = 0 ;
|>  >     #define append( c ) \
|>  >         (bufx >= sizeof( buffer ) \
|>  >         ? throw buffer_overflow()  \
|>  >         : buf[ bufx ++ ] = (c))
|>  >
|>  >         // ...
|>  >     #undef append
|>  >     }
|>  >
|>  > Of course, any real C++ programmer will use vector<char>.push_back for
|>  > append today, and the problem disappears.
|>
|>  Sure, if you don't mind heavyweight code. I still appreciate
|>  efficiency, though, since my field is primarily embedded code.
|>  If I've got a long function that's going to have dozens of calls
|>  to "append" as described above, what I'd really like, for
|>  efficiency's sake, is an actual subroutine call, but to a
|>  function that still has access to its caller's scope.

(I should have put a smiley on the "any real C++ programmer".  I'm well
aware that there are cases where the general solution isn't appropriate.
Although I'm not convinced that with a good implementation of vector,
push_back will be that much more expensive than the above.)

The above is easily simulated in C++ with a nested class.  With proper
expansion of the inline functions, performance will be the same as with
the macro.  Where the nested function might have some advantage is where
you need to access the function arguments as well -- there is no way of
packing them into a nested class, other than declaring a reference, and
passing them to the constructor.

|>  It's easy
|>  to express in a HLL like C++ simply by nesting the function
|>  definitions. What's more, it's easy enough to implement (the
|>  multi-level ENTER instruction on the x86 CPU is designed for
|>  this purpose). In fact, as long as the nested function doesn't
|>  recurse, it doesn't even need a stack frame of its own.

I thought that you wanted them for performance reasons:-).  Have you
looked at the speed of ENTER?  (Again, in practice, it shouldn't make a
significant difference.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: skaller@zip.com.au (John (Max) Skaller)
Date: 1997/11/07
Raw View
On 21 Oct 97 11:35:43 GMT, Esa Pulkkinen <esap@cs.tut.fi> wrote:

>skaller@zip.com.au (John (Max) Skaller) writes:

>>  dcl x = expr;

>Hmm... Since you brought this issue up - how would the dcl syntax
>support const and references?

 dcl const x = expr; // means "typeof(expr) const x = expr"
 dcl const &x = expr; // means "typeof(expr) const &x = expr"

>Now I would assume this dcl syntax would always use non-cv-qualified
>non-reference version of the type, i.e. always copy the object.  I would
>also assume same for the typeof() construct.

 Yes.

>This is because that would
>cause least surprise for the users (or would it? Really, I don't know).
>Consider an innocent example:
>
>vector<int> myVector;
>dcl myValue = myVector[10];
>if (myValue != 10)
>  myValue = 10; // Now how did the programmer mean to change myVector,
>                // or change a copy of the 11th item stored in myValue?

 A copy of the 11'th item.

>vector<bool> myBoolVector;
>dcl myValue2 = myBoolVector[2]; // Hmm.. myValue2 isn't bool for sure.
>                               // myValue2 is a proxy object referencing
>                               // myBoolVector.
>myValue2 = true; // still modifies myBoolVector?

 Yes, if the actual type is a copyable proxy.

>But still, this doesn't solve the problem with vector<bool>,

 There's no problem with vector bool: the effect
is the same as:

 template<class T> void scope(T t) {
  T tt = t;;
 }

except that there's no way to get at the "T" in the body
of the code for a type which you don't know the
name of _other_ than CALLING a template function.
Doing that lets you name the type "T".

STL uses this abominable hack. and several others:
it grossly perverts the structure of code, and it isn't
always possible.

John Max Skaller                ph:61-2-96600850
mailto:skaller@zip.com.au       10/1 Toxteth Rd
http://www.zip.com.au/~skaller  Glebe 2037 NSW AUSTRALIA
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: skaller@zip.com.au (John (Max) Skaller)
Date: 1997/11/07
Raw View
On 21 Oct 97 11:23:37 GMT, jbuck@synopsys.com (Joe Buck) wrote:

>Jean-Louis Leroy <jll@skynet.be>:

>    typeof(a) b;

>For nested types, of course (STL).  So that you can write, say
>
> typeof(a)::iterator a_iter = a.begin();
>
>instead of, say
>
> map<some_big_type, some_other_type, complex_comparison>::iterator ...

I wouldn't DARE propose something unnecessary! :-)

Typeof -- or something better, like a proper type calculus --
is MANDATORY, it isn't just a useful shorthand.
Consider:

 template<class F> void f(F *f) {
  T tmp = f();
  tmp.muddle();
  return tmp;
 }

This kind of template CANNOT be written without typeof. There's no way
to discover the return type of the function F. Here's a simpler
example:

 template<class T1, class T2> T3 add(T1 t1, T2 t2) {
  return t1 + t2;
 }

which even "typeof" cannot solve. You CAN discover the type T3,
but not where you need it:

 template<class T> T id (T t) { return t; }

will give you a name of any (copyable) expression.
John Max Skaller                ph:61-2-96600850
mailto:skaller@zip.com.au       10/1 Toxteth Rd
http://www.zip.com.au/~skaller  Glebe 2037 NSW AUSTRALIA
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/11/07
Raw View
James Kuyper <kuyper@wizard.net> wrote:

>If they had thought about it adequately, they should at least have named
>it _longlong, rather than 'long long'. I would have preferred them to
>call their 64 bit type 'long', but I can understand that they needed to
>cater to a large body of non-conforming code.

Ah, yes, they could call it 'long', but then we might want a term for
the 32-bit type.  How about 'medium' or 'short long' %-/
Seriously, this does fix the backward-compatability problem. If 'long'
is reserved for the largest integral type and 'medium' is added as an
additional size which is <= 'long' and >= 'int', with the following
reqirements:

 char >= 8 bits
 short >= 16 bits
 int >= short
 medium >= 32 bits
 long >= Yikes!

We're stuck here. If long is required to be at least 64 bits, then the
change in the standard is rather drastic and a lot of existing code will
suddenly become less efficient in memory and possibly also in time. On
the other hand, not requiring long to be at least 64 bits does not
address the reason people want 'long long' in the first place. So much
for simple solutions to complex problems :-(

-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1997/11/07
Raw View
Valentin Bonnard <bonnardv@pratique.fr> wrote:

>Brian Parker wrote:
>>
>> On 30 Oct 97 21:15:24 GMT, David Cogen <cogen@ll.mit.edu> wrote:
>> >...
>> >This way I can write my own control constructs, and do other advanced things
>> >that are impossible with the current preprocessor.
>
>like std::for_each ?
>
>It isn't as cute, but it works. Extending macros seems a bad
>idea to me, I think it's best to extend either templates or
>local functions.

One type of extention I would like to see is the ability to included
certain language constructs in conditional compilation expressions that
are currently not evaluable at the "preprocessing" phase. Basically, it
would require that the compiler implementors do parsing and conditional
compilation in the same pass. That would allow us to use things like
sizeof and typeid for conditional compilation, especially in templates:

template <class T> class X
{
 ...
  // y is a synonym for T unless T is char, in which case y is uchar
#if typeid(T) == typeid(char)
  typedef unsigned char y;
#else
  typedef T y;
#endif

  // declare a buffer large enough for T, but not smaller than a double
#if sizeof(T) < sizeof(double)
  char buff[sizeof(double)];
#else
  char buff[sizeof(T)];
#endif
};

const bool debug = true;
#if debug // Note that debug is a variable, not a pre-processing macro
...
#endif


Going just a little further with this idea, it would be nice if a few
more "preprocessing" functions were allowed. (Currently defined(ident)
is the only proprocessing function.) Examples of useful preprocessing
functions are:

 declared(ident)   The identifier has been declared
 declared<function>(ident) The identifier is a function
 declared<class>(ident)  The identifier is a class/struct
 declared<enum>(ident)  The identifier is an enum
 declared<typedef>(ident) The identifier is a typedef
 declared<builtin>(ident) The identifier is a builtin type
 declared<integral>(ident) The identifier is intergral
 etc.

Finally, it would be useful to add scope to preprocessor macros. This is
more difficult to do while keeping backward compatability, but I'm sure
an extra keyword here or there could make it work ;-)

-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com

I am self-employed. Therefore, my opinions *do* represent
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/07
Raw View
John (Max) Skaller wrote:
>
> On 21 Oct 97 11:23:37 GMT, jbuck@synopsys.com (Joe Buck) wrote:
>
> >Jean-Louis Leroy <jll@skynet.be>:
>
> >    typeof(a) b;
>
> >For nested types, of course (STL).  So that you can write, say
> >
> >       typeof(a)::iterator a_iter = a.begin();
> >
> >instead of, say
> >
> >       map<some_big_type, some_other_type, complex_comparison>::iterator ...
>
> I wouldn't DARE propose something unnecessary! :-)
>
> Typeof -- or something better, like a proper type calculus --
> is MANDATORY, it isn't just a useful shorthand.
> Consider:
>
>         template<class F> void f(F *f) {
>                 T tmp = f();
>                 tmp.muddle();
>                 return tmp;
>         }
>
> This kind of template CANNOT be written without typeof. There's no way
> to discover the return type of the function F. Here's a simpler
> example:
>
>         template<class T1, class T2> T3 add(T1 t1, T2 t2) {
>                 return t1 + t2;
>         }
>
> which even "typeof" cannot solve. You CAN discover the type T3,

Oh yes, it can:

template<class T1, class T2>
 typeof( *(T1*)0 + *(T2*)0 ) add(T1 t1, T2 t2)
{
  return t1+t2;
}

If you restrict your function to default-constructible types, you
can do the following as well:

template<class T1, class T2>
 typeof( T1()+T2() ) add(T1 t1, T2 t2)
{
  return t1+t2;
}

An useful example for typeof would be the value type of an iterator:

template<class Iterator1, class Iterator2> class PairIterator
{
  Iterator1 iterator1;
  Iterator2 iterator2;
  ...
public:
  pair<typeof(*iterator1), typeof(*iterator2)> operator*()
    { return make_pair(*iterator1, *iterator2); }
  ...
};

Besides, of course, all the arithmetic classes that have to work
with unknown 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Scott Johnson <sj_nospam@nospam.aracnet.com>
Date: 1997/11/04
Raw View
Mirek Fidler wrote:
>
> Scott Johnson wrote:

[snip]


>  > 2)  Require explicit unblocking/resumption of the thread in a function
>  >
>  > called after the constructor returns.  This guarantees that the object
>  >
>  > is fully constructed, but is a pain in the ass.  (Java essentially
>  > does
>  > this with Thread objects...you have to explicitly call their start()
>  > member.)
>
>     Yes. This is approach I would suggest. I think that starting the
> thread in constructor would prove a weak design later...


It certainly is the least bothersome of the alternatives.  And in many
cases, it is the best solution--if the class client is going to operate
on the created thread (which is the case with Java Thread objects),
starting and stopping the thread is an important part.



OTOH, to me at least, it sorta smacks of the days before exceptions,
when a call to an "is_valid" member function (after the constructor
returned) was required to see if the constructor completed or failed.
If creating and starting a thread is part of the objects behavior, and
this multithreadedness is intended to be transparent to the client,
having to  call a start() method is certainly a violation of that
expectation.


Whether this particular bit o' object oriented purity justifies the
addition of a language feature, I dunno.  I can certainly think of
language features which would be more useful....overloading . comes to
mind.


Scott
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "lg" <lg@mail.ndirect.co.uk>
Date: 1997/11/04
Raw View
Petteri Ollila wrote in message <3457fce2.1041925328@news.clinet.fi>...
>A more widely useful feature would be the closure contruct
>of Borland C++. It allows callbacks to any member function
>with compatible signature in any class. I have not found a
>way to do this neatly in standard C++.

I would have thought a template callback wrapper object would suffice.
Basically one needs to store both the pointer to member function and the
instance of the object as data members of the wrapper.
I think that the extensions in Borland C++ builder are a worrying trend.
They seem to add unnecessary proprietorial extensions and keywords to the
language (as opposed to a library) which are not always necessary or just
add syntactic sugar. In the case of Borland C++ Builder, this was mainly
AFAIKS to provide for (binary?) compatibility with their Delphi dialect of
Pascal, which is more understandable. In any case, given Borland's presence
in the market, it is not likely that a whole host of other compilers will
jump up to support their language changes.
I have a feeling that the arrival of Standard C++ will signal the start of a
range of proprietorial extensions to the core language as language
"architects" no longer channel their efforts into the stardards procedure.
I do not know if anyone has read the article in Nov 1997 Microsoft System
Journal on COM+, Microsoft's forthcoming solution to language neutral system
wide distributed, (sort-of :->) OOP. They seem to be about to introduce a
whole host of extensions to C++. The worrying thing is that other compiler
writers in the PC market at least will follow suit to ensure compatibility
with Microsoft VC++. I find nothing particularly objectionable per se in the
extensions themselves other than that they add to the about to be
standardized C++ language. I have no doubt that Microsoft is full of great
and worthy programmers. It is just that I find many of the design tradeoffs
and the code in Microsoft Foundation Classes library suspect IMHO. I used to

think that perhaps all the C++ programmers at Redmond should be give a copy
of Design and Evolution of C++ to read.
The article in MSJ 11/97 kept saying that the compiler will take care of
that for you, without specifyng details. I find that just a teeny little bit
alarming. (Examples include automatic translation of assignment and
examination of properties into function calls if I have not misread the
text). I believe that if possible, at the language level, operations should
be as explicit as possible. This is after all the difference between BASIC
and C++.
LG
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Sergei Organov <osv@javad.ru>
Date: 1997/11/04
Raw View
Mirek Fidler wrote:
>
> Sergei Organov wrote:
>
> > It's easy. Post-constructor has access to the object itself and to any
> >
> > argument
> > passed to constructor as well.
>
>    To which constructor's arguments in the hierarchy ? The last one
> (most derived) or the first one ?
>

Those one the post-constructor is declared to be used with:

class Base {
public:
  Base(int i, int j) = foo(i); // this means foo(int) should be
                               // called with value of 'i' passed
                               // to it as argument.
private:
  void foo(int);
};

class Derived: public Base {
public:
  Derived(int k): Base(k, 10) {}
};

// Now,
Derived d(20);

// Should invoke:
//   Base(20, 10)
//   Derived body(20)
//   foo(20)

BR,
Sergei Organov.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: chelly@eden.com (Chelly Green)
Date: 1997/11/04
Raw View
In article <345EAF64.617E@nospam.aracnet.com>, sj_nospam@nospam.aracnet.com
wrote:

> Mirek Fidler wrote:
...
> Whether this particular bit o' object oriented purity justifies the
> addition of a language feature, I dunno.  I can certainly think of
> language features which would be more useful....overloading . comes to
> mind.

Why hasn't anyone mentioned a template wrapper class that calls a post
constructor (and pre destructor)?

--

#include <iostream.h>

template<class Base>
class ObjHook : public Base {
public:
    ObjHook()  { post_construct(); }
    ~ObjHook() { pre_destruct(); }

    // for ctor params (but my compiler doesn't support member templates yet)

    // template<class A1>
    // ObjHook( A1 a1 ) : Base( a1 ) { post_construct(); }

    // template<class A1,class A2>
    // ObjHook( A1 a1, A2 a2 ) : Base( a1, a2 ) { post_construct(); }

    // etc...
};

// system thread class

class Thread {
public:
    Thread() { }
    virtual void run() = 0;
    virtual void stop() { }
protected:
    void post_construct() { run(); }
    void pre_destruct() { stop(); }
};

// user thread class

class MyThread_ : public Thread {
public:
    MyThread_() { }
    virtual void run()  { cout << "MyThread::run()\n"; }
    virtual void stop() { cout << "MyThread::stop()\n"; }
};

typedef ObjHook<MyThread_> MyThread; // required typedef for user class

// test program

int main()
{
    MyThread thread;

    cout << "\ninside main()\n\n";

    return 0;
}

--

output:

MyThread::run()

inside main()

MyThread::stop()

--

This doesn't seem like much of a burden on the user. Just as long as
someone doesn't derive from the MyThread typedef :-)

--
Chelly Green | chelly@eden.com | C++ - http://www.eden.com/~chelly
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/05
Raw View
J. Kanze wrote:
>
> Actually, the CLASSICAL alternative is:-):
>
>     void
>     foo()
>     {
>         char buffer[ 256 ] ;
>         int xbuf = 0 ;
>     #define append( c ) \
>         (bufx >= sizeof( buffer ) \
>         ? throw buffer_overflow()  \
>         : buf[ bufx ++ ] = (c))
>
>         // ...
>     #undef append
>     }
>
> Of course, any real C++ programmer will use vector<char>.push_back for
> append today, and the problem disappears.

Sure, if you don't mind heavyweight code. I still appreciate
efficiency, though, since my field is primarily embedded code.
If I've got a long function that's going to have dozens of calls
to "append" as described above, what I'd really like, for
efficiency's sake, is an actual subroutine call, but to a
function that still has access to its caller's scope. It's easy
to express in a HLL like C++ simply by nesting the function
definitions. What's more, it's easy enough to implement (the
multi-level ENTER instruction on the x86 CPU is designed for
this purpose). In fact, as long as the nested function doesn't
recurse, it doesn't even need a stack frame of its own.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/05
Raw View
Mirek Fidler wrote:
>
>     Well, what about to create help class (struct) to store these
> parameters ? I think that could be even more run-time efficient than
> accessing nested stack frames... Eg:
>
>     struct {
>         type1 var1;
>         type2 var2;
>         .....
>         part1();
>         partN();
>     };

As long as a nested function doesn't recurse, it doesn't even
need its own stack frame--it can use the outer function's stack
frame, just like any other nested block of code containing
declarations. The benefit of nesting the function is simply that
the duplicated code is collected into one place and invoked with
a subroutine call.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/05
Raw View
J. Kanze wrote:
>
> Of course, this use can easily be simulated using a macro:-).  It is
> precisely when pointer to function is required that they are the most
> useful.

Not to me. The situation that occasionally arises that makes me
wish for nested functions is the situation I described in my
earlier post, where I have a rather large function that includes
a particular bit of code over and over again within it. If I
simply write the code over and over (or use a macro to automate
it) I wind up with large numbers of copies of the compiled code,
where a subroutine would do nicely. If I try to break the
repeated code off into a separate function, I wind up having to
pass a whole bunch of parameters (or at best, one pointer to an
artificially concocted struct containing the necessary
parameters) to the separate function, thus sacrificing much of
the potential efficiency.

To someone like myself who has spent half a lifetime writing
assembly language, the solution seems obvious: write a
subroutine that operates within its caller's scope. And this is
easy to express in C or C++, merely by nesting the function
definition. I can just _see_ the nice, efficient resulting
compiled code: it has no stack frame of its own (which is
possible as long as it doesn't recurse), and is just a bunch of
instructions invoked by CALL and ending in RET. But in C++, I
can't _say_ that, and I feel stymied.

That said, I can _also_ see the utility of pointers to nested
functions that carry scope along with them. But this is the sort
of thing that one desires for reasons other than efficiency.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <cxl@usa.net>
Date: 1997/11/01
Raw View
Sergei Organov wrote:

> Mirek Fidler wrote:
> >
> >     Besides, have you consider how to tell to post-constructor where
> he
> > has to register ?
> >
>
> It's easy. Post-constructor has access to the object itself and to any
>
> argument
> passed to constructor as well.

   To which constructor's arguments in the hierarchy ? The last one
(most derived) or the first one ?

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Colin Rafferty <craffert@ml.com>
Date: 1997/11/01
Raw View
Paul D DeRocco writes:
> Colin Rafferty wrote:

>> Picture the same class hierarchy as above (Derived derived from Base).
>> We say that Base needs to register itself in its post-constructor.

>> Now imagine that the implementor of Derived wanted to use the same
>> post-constructor trick in order to finish logically constructing itself.
>> If it has its virtual function `f' called on it before it is
>> post-constructed, the result will be undefined.

>> 1. Base::ctor() called on object X.
>> 2. Derived::ctor() called on object X.
>> 3. Base::post-ctor() called on object X.  Base registers itself in the
>>    global registry.
>> 4. In another thread, something gets X out of the registry, calls
>>    virtual function `f'.
>> 5. Derived::post_ctor() called on object X.

>> You can see that the result of Step 4 is undefined.

> Obviously, if Derived::post_ctor() is attempting to make some
> sort of change to whatever was done by Base::post_ctor(), then
> there's a problem.  But if they are both trying to do the same
> sort of thing, and the desire is to let Derived override what
> Base does, the solution is to put the behavior into a virtual
> function that is invoked from Base::post_ctor(), and redefine
> _that_ in the derived class instead. I think trying to use a
> post-constructor in this manner would simply be wrong.

However, this is not what my example is showing.  I am demonstrating how
post-constructor does not solve the multi-threading registry problem.

> On the other hand, if Derived::post_ctor() is using the same
> technique to do something completely different, and that doesn't
> even have any meaning yet at the Base class level, then there
> really is no conflict or problem at all.

Yes there is.  Here is one of my assertions about Derived:

>> If it has its virtual function `f' called on it before it is
>> post-constructed, the result will be undefined.

As you can see, Derived::f() is being called in step 4, but Derived's
post-constructor has not yet been called.

My assertion is that a language-level post-constructor does not solve
the real problems that reside in multithreading and registration in the
constructor.  Instead of solving the problems, it pushes them down a
level.

--
Colin
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <cxl@usa.net>
Date: 1997/11/01
Raw View
> > > Another thing I think is inexcusable is that C++ doesn't allow
> > > nested functions.
>
> >    Actually, I think this is an advantage of C++ for both run time
> > efficiency (you would need much more complicated stack frames for
> that)
> > and design. Most of need of nested functions was removed by
> introducing
> > private class methods.
>
> Suppose you have a complicated method that you want to split and
> suppose
> that each part needs to access to several function arguments and local
>
> variables and also to a private class members.
> Then with private class methods you would have to add quite ugly
> declaration to your header like
> void part1 (type1 var1, type2 var2, type3 var3 ... type7 var7);
> ...
> void partN (type1 var1, type2 var2, type3 var3 ... type7 var7);
> that would only pollute your class declarations by unnecessary
> implementation details.
> I tried to use that approch during an implementation
> of several numerical algorithms and at the end I gave up and wrote
> those endless methods...

    Well, what about to create help class (struct) to store these
parameters ? I think that could be even more run-time efficient than
accessing nested stack frames... Eg:

    struct {
        type1 var1;
        type2 var2;
        .....
        part1();
        partN();
    };

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Colin Rafferty <craffert@ml.com>
Date: 1997/11/01
Raw View
Paul D DeRocco writes:
> Colin Rafferty wrote:

>> The problem is inherent in the following two facts.  The first is the
>> way C++ currently works (and must continue to work).  The second is the
>> way that C++ will work with the post-constructor.

>> 1. The constructor of a derived class may use its base class.

>> 2. An object that has not had its post-constructor called is not
>>    completely constructed (in a logical sense).  If it were, it wouldn't
>>    have needed a post-constructor.

>> Therefore, a partially-constructed object could be manipulated by an
>> instance of its derived part.

>> For example, imagine a hierarchy that includes the following definition:

>> class Derived : public Base { /* ... */ };

>> Imagine also that class Base has a post-constructor.

>> If the `Derived' constructor tries to use the `Base' part of itself, the
>> results will be erroneous, because Base::post_constructor() has not yet
>> been called.

>> If the results could not be erroneous, then the post-constructor is
>> unnecessary.

> But a post-constructor is something that is called _after_ the
> object is constructed. In other words, you are wrong when you
> say that "an object that has not had its post-constructor called
> is not completely constructed".

When I used the term "constructed", I meant "logically constructed".
This means that the object is not yet useful until its post-constructor
has been called.

> The purpose of the
> post-constructor is to provide a handy hook that is invoked once
> an object is fully constructed.

If you are arguing that post-constructor would be handy, I wouldn't
disagree with you.  Of course, I would argue that it shouldn't be a part
of C++ since it makes the language more complicated for a minor
convenience.

The original posting about post-constructors was describing how it
solved a language problem.  My postings (including the one you replied
to above) are about how it fails to do this.

> For instance, one might define a post-constructor in a base
> thread class that starts the thread. This would allow one to
> write a derived thread class that adds to the thread object, but
> still doesn't get started until after the derived thread is
> fully constructed.

This could be done separately, and much more cleanly.  For example,
Java's base thread class has a "run" function that is called after the
object is created.  This allows you to create a list of threads first,
and then run them all at once.

> This all works fine, as long as the programmer doesn't fall into
> the trap of thinking of the post-constructor as a constructor,
> and leaving it to do something that is required before the
> object is to be considered valid.

This is what I am arguing.

> I like the idea.

I don't, but I disagree with you only because I generally don't like the
language extended.

This could be a neat extension, but I just think that it will complicate
things needlessly.

--
Colin
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Scott Johnson <sj_nospam@nospam.aracnet.com>
Date: 1997/11/02
Raw View
Mirek Fidler wrote:
>
> >  > >> I am afraid this violates constructors/destructor idea in its
> > bases.
> >  > >> Thus said, if you need these, there is possibly something wrong
> > with
> >  > >> your class hierarchies ;-)
> >  >
> >  > I couldn't have said it better myself :-).
>
> > What you are missing is that objects are no standalone entities, but
> > stand in relation to other objects in the program. For example, an
> > object could provide a service. Now there might be another object that
> >
> > informs which objects can give you which sort of service. This other
> > object needs to be notified about the new object, but of course only
> > when the object is fully constructed (else someone would possibly try
> > to contact the half-constructed object).
> >
> > Thus you can characterize the different stages as the following:
> >
> > 1. The constructor (completely) constructs the object.
> > 2. The post-constructor puts the newly constructed object in relation
> >    to the rest of the program (f.ex. registering it)
> > 3. The pre-destructor disconnects the object from the rest of the
> > program
> > 4. The destructor destructs the object.
>
>     I am sure, that you often need this behaviour. But please consider
> difference between words 'constructing' and 'conecting', 'registering'
> and so on.
>
>     I think that construction and destruction generally should not
> place object in relation with any other objects than (possibly) its
> members.  Anything else is not construction (destruction).

I can think of at least one use of postconstructors and predestructors
which I don't know of any clean way of doing without them--objects
which create and/or manage threads.

If an object creates a thread in the base class, and is/can be
overloaded, there is the nasty synchronization problem of ensuring that
the object gets constructed before the created thread gets to run.  (The
constructor derived class constructors run in the context of the calling
thread, not the created thread.)  As a result, some sort of
suspend/blocking semantics must typically be employed to keep the
created thread from running until the object is ready for it to run.

Having the base class constructor wake up the thread isn't very useful,
as the thread may get woken up before the derived class constructors get
to run.

There are three solutions:

1)  Prohibit derivation.  This works well enough when the class is not
intended to be extendable, but many classes are made to be extended.

2)  Require explicit unblocking/resumption of the thread in a function
called after the constructor returns.  This guarantees that the object
is fully constructed, but is a pain in the ass.  (Java essentially does
this with Thread objects...you have to explicitly call their start()
member.)

3)  Have some way for the created thread to determine if the object has
    been created or not...this is not easily maintainable, and is also a
    pain in the ass.  (It is also a variation on the theme of technique
    #2.)

An analogous problem exists with destroying such objects--you need to
make sure that the thread is no longer running before you start calling
destructors, lest the thread manage to touch a partially destroyed (or
completely destroyed) object.

With postconstructors and predestructors, this problem is solved.  The
postconstructor is responsible for starting the thread, the
predestructor is responsible for stopping it.  No other contortions in
the application code (or in the derived object code) is necessary.



Scott
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <cxl@usa.net>
Date: 1997/11/03
Raw View
Scott Johnson wrote:

 > Mirek Fidler wrote:
 > >     I am sure, that you often need this behaviour. But please
 > consider
 > > difference between words 'constructing' and 'conecting',
 > 'registering'
 > > and so on.
 > >
 > >     I think that construction and destruction generally should not
 > > place object in relation with any other objects than (possibly) its
 > > members.  Anything else is not construction (destruction).
 >

 > 2)  Require explicit unblocking/resumption of the thread in a function
 >
 > called after the constructor returns.  This guarantees that the object
 >
 > is fully constructed, but is a pain in the ass.  (Java essentially
 > does
 > this with Thread objects...you have to explicitly call their start()
 > member.)

    Yes. This is approach I would suggest. I think that starting the
thread in constructor would prove a weak design later...

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/04
Raw View
micha@aishdas.org writes:
> On 30 Oct 97 08:07:58 GMT, Mark Zeren <zeren@pobox.com> wrote:
> : I'm not sure why overriding the dot operator should be so ridiculous.
>
> How then would you ever refer to the real member b of object a? At least
> if pa->b is overloaded I can fall back on (*pa).b. Perhaps "(&a)->b" if
> not overloaded?
>
> It would seem that you are hiding all non-operator members from any context
> outside the object defintion.

It would seem as if you answered your own question: "(&a)->b" would do
the trick.  Now of course, if you overloaded (unary) operator& as
well...

Note that within member functions, referring to a member without using
explicit this-> always accesses the member, regardless of what
overloadings might be present.  Similarly, operator overloading would
still get member functions -- this is important, for example, in the
case of operator= (as well as, obviously, the new operator.:-).  The
"normal" use for operator. would be to create a smart reference (in the
same way as you use operator-> to create a smart pointer) -- in such
cases, you would never want to access a member outside of a member
function anyway.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/04
Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:

|>  Another thing I think is inexcusable is that C++ doesn't allow
|>  nested functions. They'd have to have access to the enclosing
|>  function's scope, which would make pointers to nested functions
|>  difficult (since they'd have to carry pointers to that scope
|>  potentially outside that scope), but I'd be perfectly happy if
|>  pointers to nested functions were simply disallowed. I've
|>  frequently wanted to use it in situations like this:
|>
|>  void foo() {
|>      char buf[256];
|>      int bufx = 0;
|>
|>      void append(char c) {
|>          if (bufx == sizeof(buf)) throw buffer_overflow();
|>          buf[bufx++] = c;
|>          }
|>
|>      ...
|>      append('X'); // lots of these scattered throughout
|>      ...
|>      }

Of course, this use can easily be simulated using a macro:-).  It is
precisely when pointer to function is required that they are the most
useful.

Consider the standard Unix function ftw.  This function takes a pointer
to function, which is called for each object in the tree.  Now, if the
called function needs access to local state, you're in trouble.
Traditionally, this has been solved by putting the local state in static
variables, and having the function access it.  Traditionally, however,
there were no such things as threads -- static variables and threads are
known to not mix very well.

Of course, this is a C problem, more than a C++ problem.  Were ftw a C++
function, it would almost certainly take a pointer or reference to a
functional object as argument, rather than a pointer to a function.  And
the functional object could have additional state -- with my suggestion
of a predefine __local_context class, it could even have direct access
to the outer functions arguments.  IMHO: this is a more C++-like
solution.  (But it doesn't solve the problem for functions like ftw,
which are doubtlessly declared extern "C", and will still take a pointer
to function.)

Given that the problem is more urgent in C, my suggestion would be to
leave it in the hands of the C standards committee.  (FWIW: it was
suggested, but not adopted, in C9x.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/04
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

|>  > Which is just the behaviour you want for objects behaving as smart
|>  > references.
|>
|>  But a reference isn't an object, so smart references don't
|>  makes sens; you can only have smart pseudo references, with
|>  some definition (limitation) of pseudo.

Well, a smart pointer isn't really a pointer either -- in particular,
implicit conversions don't generally work correctly with it.

In practice, it would be very useful if container classes could return a
smart reference for operator[].

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/04
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

|>  Paul D. DeRocco wrote:
|>  >
|>  > Another thing I think is inexcusable is that C++ doesn't allow
|>  > nested functions. They'd have to have access to the enclosing
|>  > function's scope, which would make pointers to nested functions
|>  > difficult (since they'd have to carry pointers to that scope
|>  > potentially outside that scope), but I'd be perfectly happy if
|>  > pointers to nested functions were simply disallowed. I've
|>  > frequently wanted to use it in situations like this:
|>  >
|>  > void foo() {
|>  >     char buf[256];
|>  >     int bufx = 0;
|>  >
|>  >     void append(char c) {
|>  >         if (bufx == sizeof(buf)) throw buffer_overflow();
|>  >         buf[bufx++] = c;
|>  >         }
|>  >
|>  >     ...
|>  >     append('X'); // lots of these scattered throughout
|>  >     ...
|>  >     }
|>
|>  Well, the classical alternative is:
|>
|>  void foo() {
|>      struct buffer {
|>          char buf[256];
|>          int bufx;
|>
|>          buffer () : bufx (0) {}
|>          void append(char c) {
|>              if (bufx == sizeof(buf)) throw buffer_overflow();
|>              buf[bufx++] = c;
|>          }
|>      } b;
|>      ...
|>      b.append('X'); // lots of these scattered throughout
|>      ...
|>      }
|>
|>  But it's a little longer.

Actually, the CLASSICAL alternative is:-):

    void
    foo()
    {
        char buffer[ 256 ] ;
        int xbuf = 0 ;
    #define append( c ) \
        (bufx >= sizeof( buffer ) \
        ? throw buffer_overflow()  \
        : buf[ bufx ++ ] = (c))

        // ...
    #undef append
    }

Of course, any real C++ programmer will use vector<char>.push_back for
append today, and the problem disappears.  (FWIW: I've actually used the
technique involving local macros on more than one occasion in C.  In
C++, in the rare cases where it would have been useful, I've used
Valentin's suggestion, with a local class.)

(None of which really argues for or against local functions, see my
other posting on the subject.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/31
Raw View
On 30 Oct 97 21:13:58 GMT, micha@aishdas.org wrote:

>On 30 Oct 97 08:07:58 GMT, Mark Zeren <zeren@pobox.com> wrote:
>: I'm not sure why overriding the dot operator should be so ridiculous.
>
>How then would you ever refer to the real member b of object a? At least
>if pa->b is overloaded I can fall back on (*pa).b. Perhaps "(&a)->b" if
>not overloaded?

You could derive object 'a' from a base class C with the needed
members and use static_cast<C*>(&a)->b().

>
>It would seem that you are hiding all non-operator members from any context
>outside the object defintion.

Which is just the behaviour you want for objects behaving as smart
references.

,Brian Parker.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/31
Raw View
Colin Rafferty wrote:
>
> Picture the same class hierarchy as above (Derived derived from Base).
> We say that Base needs to register itself in its post-constructor.
>
> Now imagine that the implementor of Derived wanted to use the same
> post-constructor trick in order to finish logically constructing itself.
> If it has its virtual function `f' called on it before it is
> post-constructed, the result will be undefined.
>
> 1. Base::ctor() called on object X.
> 2. Derived::ctor() called on object X.
> 3. Base::post-ctor() called on object X.  Base registers itself in the
>    global registry.
> 4. In another thread, something gets X out of the registry, calls
>    virtual function `f'.
> 5. Derived::post_ctor() called on object X.
>
> You can see that the result of Step 4 is undefined.

Obviously, if Derived::post_ctor() is attempting to make some
sort of change to whatever was done by Base::post_ctor(), then
there's a problem. But if they are both trying to do the same
sort of thing, and the desire is to let Derived override what
Base does, the solution is to put the behavior into a virtual
function that is invoked from Base::post_ctor(), and redefine
_that_ in the derived class instead. I think trying to use a
post-constructor in this manner would simply be wrong.

On the other hand, if Derived::post_ctor() is using the same
technique to do something completely different, and that doesn't
even have any meaning yet at the Base class level, then there
really is no conflict or problem at all.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/31
Raw View
Colin Rafferty wrote:
>
> The problem is inherent in the following two facts.  The first is the
> way C++ currently works (and must continue to work).  The second is the
> way that C++ will work with the post-constructor.
>
> 1. The constructor of a derived class may use its base class.
>
> 2. An object that has not had its post-constructor called is not
>    completely constructed (in a logical sense).  If it were, it wouldn't
>    have needed a post-constructor.
>
> Therefore, a partially-constructed object could be manipulated by an
> instance of its derived part.
>
> For example, imagine a hierarchy that includes the following definition:
>
>     class Derived : public Base { /* ... */ };
>
> Imagine also that class Base has a post-constructor.
>
> If the `Derived' constructor tries to use the `Base' part of itself, the
> results will be erroneous, because Base::post_constructor() has not yet
> been called.
>
> If the results could not be erroneous, then the post-constructor is
> unnecessary.

But a post-constructor is something that is called _after_ the
object is constructed. In other words, you are wrong when you
say that "an object that has not had its post-constructor called
is not completely constructed". The purpose of the
post-constructor is to provide a handy hook that is invoked once
an object is fully constructed. It does so in a manner that
allows the post-constructor to be defined in the base class, so
that it doesn't need to be repeated in every derived class. In
addition, virtual functions invoked from within the
post-constructor (and pre-destructor) would vector to the
appropriate derived methods.

For instance, one might define a post-constructor in a base
thread class that starts the thread. This would allow one to
write a derived thread class that adds to the thread object, but
still doesn't get started until after the derived thread is
fully constructed.

This all works fine, as long as the programmer doesn't fall into
the trap of thinking of the post-constructor as a constructor,
and leaving it to do something that is required before the
object is to be considered valid.

I like the idea.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/31
Raw View
Mirek Fidler wrote:
>
>     Besides, have you consider how to tell to post-constructor where he
> has to register ?

This is a _very_ interesting question. Here are some
possibilities:

1) Allow a second set of parameters to be passed, e.g.:

 foo a(x, y, z)(1, 2, 3);
 foo* y = new foo(x, y, z)(1, 2, 3);

That's almost unspeakably ugly.

2) Pass the same parameters to the post-constructor as to the
constructor. Unfortunately, that requires writing a version of
the post-constructor to match each constructor. Yuck.

3) Prohibit parameters to the post-constructor entirely,
requiring instead that it get all its parameters through the
constructed object. Ahhh, that's better.

In other words, if you're using a post-constructor to register
an object in some list, then pass the list as a parameter to the
constructor, and have the base class constructor store it in the
object for the benefit of the post-constructor.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: boukanov@sentef1.fi.uib.no (Igor Boukanov)
Date: 1997/10/31
Raw View
Paul D. DeRocco (pderocco@ix.netcom.com) wrote:
> Another thing I think is inexcusable is that C++ doesn't allow
> nested functions. They'd have to have access to the enclosing
> function's scope, which would make pointers to nested functions
> difficult (since they'd have to carry pointers to that scope
> potentially outside that scope), but I'd be perfectly happy if
> pointers to nested functions were simply disallowed. I've
> frequently wanted to use it in situations like this:

But gcc C compiler support nested functions and pointers to them that are
interchangeable with ordinary function pointers, and it done for a wide
range of platforms (all that gcc supports?).
The trick is to generate code to setup scope pointers on fly.

Regards, Igor Boukanov.
http://www.fi.uib.no/~boukanov/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <cxl@usa.net>
Date: 1997/10/31
Raw View
> Another thing I think is inexcusable is that C++ doesn't allow
> nested functions.

   Actually, I think this is an advantage of C++ for both run time
efficiency (you would need much more complicated stack frames for that)
and design. Most of need of nested functions was removed by introducing
private class methods.

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/31
Raw View
Paul D. DeRocco wrote:
>
> Another thing I think is inexcusable is that C++ doesn't allow
> nested functions. They'd have to have access to the enclosing
> function's scope, which would make pointers to nested functions
> difficult (since they'd have to carry pointers to that scope
> potentially outside that scope), but I'd be perfectly happy if
> pointers to nested functions were simply disallowed. I've
> frequently wanted to use it in situations like this:
>
> void foo() {
>     char buf[256];
>     int bufx = 0;
>
>     void append(char c) {
>         if (bufx == sizeof(buf)) throw buffer_overflow();
>         buf[bufx++] = c;
>         }
>
>     ...
>     append('X'); // lots of these scattered throughout
>     ...
>     }

Well, the classical alternative is:

void foo() {
    struct buffer {
        char buf[256];
        int bufx;

        buffer () : bufx (0) {}
        void append(char c) {
            if (bufx == sizeof(buf)) throw buffer_overflow();
            buf[bufx++] = c;
        }
    } b;
    ...
    b.append('X'); // lots of these scattered throughout
    ...
    }

But it's a little longer.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/31
Raw View
Igor Boukanov wrote:
> But gcc C compiler support nested functions and pointers to them that are
> interchangeable with ordinary function pointers, and it done for a wide
> range of platforms (all that gcc supports?).
> The trick is to generate code to setup scope pointers on fly.

I don't want to force on the fly code generation on each
platform where there can be a C++ compiler (opposed to
each 32 bit platform where there is the gcc compiler).

BTW, this is not even implemented in g++.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Sergei Organov <osv@javad.ru>
Date: 1997/10/31
Raw View
Paul D. DeRocco wrote:
> Mirek Fidler wrote:
> >
> >     Besides, have you consider how to tell to post-constructor where he
> > has to register ?
> >
>
> This is a _very_ interesting question. Here are some
> possibilities:
>
[...]
>

I'd like to comment a little bit about this.

My initial thought about post-constructors was a little bit
different. I didn't think about them as some kind of special
function. Instead, constructor declaration itself may contain
function call (or list of calls) as its part:

class Foo {
public:
  Foo(int i, int j) = foo(i); // foo(int) is called after cons.
                              // with value of 'i' passed to it.
private:
  void foo(int i);
};

This approach allows different post-constructors to be specified for
different constructors and doesn't require unnecessary storage of
constructor parameter(s) in the object.

As for pre-destructors, any member function that could be called
without arguments is allowed to be used as pre-destructor, I think.

BR,
Sergei Organov
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: boukanov@sentef1.fi.uib.no (Igor Boukanov)
Date: 1997/10/31
Raw View
Mirek Fidler (cxl@usa.net) wrote:
> > Another thing I think is inexcusable is that C++ doesn't allow
> > nested functions.

>    Actually, I think this is an advantage of C++ for both run time
> efficiency (you would need much more complicated stack frames for that)
> and design. Most of need of nested functions was removed by introducing
> private class methods.

Suppose you have a complicated method that you want to split and suppose
that each part needs to access to several function arguments and local
variables and also to a private class members.
Then with private class methods you would have to add quite ugly
declaration to your header like
void part1 (type1 var1, type2 var2, type3 var3 ... type7 var7);
...
void partN (type1 var1, type2 var2, type3 var3 ... type7 var7);
that would only pollute your class declarations by unnecessary
implementation details.
I tried to use that approch during an implementation
of several numerical algorithms and at the end I gave up and wrote
those endless methods...

The nested function support complicates stack frames only for functions that
use them and does not hurt the rest of code.

--
Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/31
Raw View
Another thing I think is inexcusable is that C++ doesn't allow
nested functions. They'd have to have access to the enclosing
function's scope, which would make pointers to nested functions
difficult (since they'd have to carry pointers to that scope
potentially outside that scope), but I'd be perfectly happy if
pointers to nested functions were simply disallowed. I've
frequently wanted to use it in situations like this:

void foo() {
    char buf[256];
    int bufx = 0;

    void append(char c) {
        if (bufx == sizeof(buf)) throw buffer_overflow();
        buf[bufx++] = c;
        }

    ...
    append('X'); // lots of these scattered throughout
    ...
    }

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/31
Raw View
Brian Parker wrote:
>
> On 30 Oct 97 21:13:58 GMT, micha@aishdas.org wrote:
>
> >On 30 Oct 97 08:07:58 GMT, Mark Zeren <zeren@pobox.com> wrote:
> >: I'm not sure why overriding the dot operator should be so ridiculous.
> >
> >How then would you ever refer to the real member b of object a? At least
> >if pa->b is overloaded I can fall back on (*pa).b. Perhaps "(&a)->b" if
> >not overloaded?
>
> You could derive object 'a' from a base class C with the needed
> members and use static_cast<C*>(&a)->b().

But & is certainly overloaded to return a smart pointer so this
should be (&a).b () or static_cast<C&> (a).b ()

> >It would seem that you are hiding all non-operator members from any context
> >outside the object defintion.
>
> Which is just the behaviour you want for objects behaving as smart
> references.

But a reference isn't an object, so smart references don't
makes sens; you can only have smart pseudo references, with
some definition (limitation) of pseudo.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/31
Raw View
Brian Parker wrote:
>
> On 30 Oct 97 21:15:24 GMT, David Cogen <cogen@ll.mit.edu> wrote:
> >...
> >This way I can write my own control constructs, and do other advanced things
> >that are impossible with the current preprocessor.

like std::for_each ?

It isn't as cute, but it works. Extending macros seems a bad
idea to me, I think it's best to extend either templates or
local functions.

> >For a quick example, I could define a "loop_over_x_y" iterator, which would be
> >used to step two variables: one for loop inside the other.
> >
> >
> >loop_over_x_y would be used like this:
> >
> >  loop_over_x_y (i i_count) (j j_count) {
> >    stat1 ();
> >    stat2 ();
> >  }
> >...
>
> I think that you can already do something similar to this using
> templates (though not as flexibly as with your suggestion).
>
> template<void Body( )>
> void loop_over_x_y(int i, int j)

Actually it should be:

template <class Func>
void loop_over_x_y(int i, int j, Func Body)

> {
>         for (int c=0; c < j; c++) {
>                 for(int r=0; r < i; r++){
>                         Body( );
>                 }
>         }
> }
>
> inline void Body( )
> {
>         stat1( );
>         stat2( );
> }
>
> loop_over_x_y<Body>(3, 4);

Should be:

loop_over_x_y (3, 4, Body);

I am sure most compiler handle that.

This way you can pass a function pointer, but also
any functor (possibly with a closure). This is more
powerfull.

Extending local function syntax would give:

loop_over_x_y (3, 4, (fun () { stat1 (); stat2 (); } ));

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Hyman Rosen <uunet!jyacc!hymie@ncar.UCAR.EDU>
Date: 1997/10/31
Raw View
micha@aishdas.org writes:
> On 30 Oct 97 08:07:58 GMT, Mark Zeren <zeren@pobox.com> wrote:
> : I'm not sure why overriding the dot operator should be so ridiculous.
>
> How then would you ever refer to the real member b of object a? At least
> if pa->b is overloaded I can fall back on (*pa).b. Perhaps "(&a)->b" if
> not overloaded?
>
> It would seem that you are hiding all non-operator members from any context
> outside the object defintion.

By Jove, I think he's got it! You do not ever refer to non-operator members
of object a from outside a. Such an object represents a "smart reference",
where every attempt to get at its insides actually gets you the object that
it's referencing.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Sergei Organov <osv@javad.ru>
Date: 1997/10/31
Raw View
Mirek Fidler wrote:
>
>     Besides, have you consider how to tell to post-constructor where he
> has to register ?
>

It's easy. Post-constructor has access to the object itself and to any
argument
passed to constructor as well.

Sergei Organov.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/31
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

>Igor Boukanov wrote:
>> But gcc C compiler support nested functions and pointers to them that are
>> interchangeable with ordinary function pointers, and it done for a wide
>> range of platforms (all that gcc supports?).
>> The trick is to generate code to setup scope pointers on fly.
>
>I don't want to force on the fly code generation on each
>platform where there can be a C++ compiler (opposed to
>each 32 bit platform where there is the gcc compiler).

It would be possible to implement pointers to nested function
that are interchangeable with ordinary function pointers without
using on the fly code generation.

I have given some hints on how to do this in previous posts on this
newsgroup...
Normally I'd just refer people to DejaNews, but it was more than three
years ago, so I don't think the DejaNews archives go back that far ;-)
My personal archives do, however.

 | From fjh Mon Mar  7 21:32:27 1994
 | Newsgroups: comp.std.c++
 | Subject: Re: vendor extensions (was: ctor/dtor behaviour ...)
[...]
 | There is an alternative implementation that maintains compatibility
 | with C function pointers and yet doesn't require creating code at
 | runtime.  (It helps if your OS allows you to map the same page of
 | read-only code to multiple pages in the address space, but even
 | this is not essential.)

 | From fjh Wed Mar 16 21:20:38 1994
 | Newsgroups: comp.std.c++
 | Subject: Re: vendor extensions (was: ctor/dtor behaviour ...)
 | [...]
 | I repeat, *doesn't require creating code at runtime*.
 | The alternative implementation to which I was referring _can_ be
 | implemented on all architectures, as far as I am aware.
 |
 | The only limitation is that with operating systems that are
 | extremely uncooperative, you need to use a trampoline stack
 | whose size must be determined at compile time.  However, many C
 | implementations for operating systems such as DOS require that
 | the size of the normal function call stack be determined at
 | compile time, and users have been able to cope with this, so
 | it doesn't seem like a crippling restriction.

 | From fjh Sun Mar 20 05:12:07 1994
 | Newsgroups: comp.std.c++
 | Subject: Re: vendor extensions (was: ctor/dtor behaviour ...)
 |
 | daniels@biles.com (Brad Daniels) writes:
[...]
 | >in applications which
 | >use trampolines extensively for declaring callbacks (which tend to exist
 | >for most of the program's lifetime), the pool could get to be unpleasantly
 | >large.
 |
 | Sure, and for highly recursive programs, a fixed-size call stack would be
 | equally unpleasant.  Yet we seem to have been able to put up with fixed-size
 | call stacks on DOS.  It's a quality of implementation issue.
 |
 | Remember the fixed size trampoline heap limit would only need to apply if
 | all of the following conditions hold:
 |
 |  1.  The operating system doesn't support mapping the same
 |      code page into multiple parts of the address space.
 | AND
 |  2.  The operating system doesn't support dynamic link libraries
 | AND
 |  3.  The operating system doesn't support dynamic code generation.
 |
 | Can anyone name a single platform for which all of those conditions
 | hold?  I can't.
 |
 | >Don't get me wrong;  I'd really like to see some kind of bound function
 | >pointers, but I'm not convinced a static pool of pregenerated trampolines
 | >is the right answer, and I don't know how many platforms would support
 | >dynamic code generation at all, let alone efficiently.
 |
 | Every platform that GNU C runs on except for ULTRIX supports dynamic
 | code generation, or so I've heard.
 |
 | If the platform supports dynamic code generation, but doesn't do it
 | efficiently, then as you suggested we can use a trampoline heap and do
 | the dynamic code generation only when we need to allocate another page
 | of trampolines.
 |
 | >I'm still not sure that would cover all environments, though.
 |
 | For say 99% of environments, there is a solution that would work just
 | fine, with reasonable efficiency and no fixed limits.  For the
 | remaining 1% of environments where you have a really uncooperative
 | operating system, we have to put up with a slightly unpleasant fixed
 | limit.  Big deal!
 |
 | --
 | Fergus Henderson - fjh@munta.cs.mu.oz.au

Of course, that fact that it is possible does not necessarily mean
that it is a good idea.  I still think that nested functions are a
good idea, and that pointers to nested functions are very useful,
but C++ is already a quite complex language, and at the moment
implementors seem to be struggling to keep up with the draft...
it might be better for them to spend their efforts on improving
existing features (better warnings, more efficient code generation,
etc.) rather than adding new features that may be complicated to implement,
even if those features are simply removal of restrictions (which might
in fact _reduce_ language complexity from a user's perspective).

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/31
Raw View
jodle wrote:
>
> Valentin Bonnard (bonnardv@pratique.fr) wrote:

> : typeof is a way to know the declared type of an object; it's
> : usable as a type name.
>
> You're missing the key trait that is a departure from the current C++
> paradigm and features proposed for typeof thus far.  The previously
> proposed typeof does not allow anything at all like:
>
>   typeof(&a) p = new typeof(a);
>
> That is, it neither provides bindings to allow its use with the new
> operator, nor the ability to allocate pointer-type objects for storing the
> resulting pointer.

No I am not missing that. You are missing the fact that typeof
is a compile time query about the declared type of an object,
and if you want a run-time query about the complete type you
should use typeid not typeof.

Also typeid returns a typeinfo so you should declare p of
type typeinfo or derived from typeinfo or something like that.

And yes it would be a departure from the current power of
typeid/typeinfo.

Please don't speel that typeof in your future posting/proposals.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/10/31
Raw View
On 31 Oct 97 16:47:19 GMT, Valentin Bonnard <bonnardv@pratique.fr>
wrote:
>..
>
>But & is certainly overloaded to return a smart pointer so this
>should be (&a).b () or static_cast<C&> (a).b ()

Yes, that's better.

>> Which is just the behaviour you want for objects behaving as smart
>> references.
>
>But a reference isn't an object, so smart references don't
>makes sens; you can only have smart pseudo references, with
>some definition (limitation) of pseudo.

True, I was thinking particularly of a Java-like reference class
(use-counted). A better example would be a value-semantics polymorphic
smart pointer class.

,Brian Parker.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/31
Raw View
Joe Buck wrote:
>
> claus@faerber.muc.de writes:
> >The Gnu C/C++ are two different compilers too. They only have a common
> >user interface program gcc, which calls the preprocessor, and the C or
> >C++ or Obj.-C compiler dependent on the type of input file.
>
> Incorrect.  It is true that there are separate executables cc1, cc1plus,
> and cc1obj, but more than 80% of the object code in these programs is the
> same (for C and Objective-C it's probably 97% the same).  The structure is
> that there is a language-dependent front end and a language-independent
> back end, and all three executables share the same back end.

Which raise the question: which language changes have to change
the back-end ? Exceptions is obvious, also long long might be a
candidate (not sure, I don't know the RTL), variable size arrays
might be in the front end (implemented as alloca), or in the
back end.

Still, the point is that C and C++ compilers are separated, so
adding something to C isn't the same as adding it to C++.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/10/29
Raw View
Colin Rafferty wrote:
 >
 > Sergei Organov writes:
 > > Mirek Fidler wrote:
 >
 > >> > How about, let's call them, 'post-constructors' and 'pre-destructors'?
 >
 > >> > The idea is to allow one to declare member function in base class to be
 > >> > called automatically after the most derived constructor returns ('post-
 > >> > constructor'); or before the most derived destructor is called
 > >> > ('pre-destructor'). Because unlike constructors and destructors these
 > >> > functions are invoked on fully constructed objects, the dynamic binding
 > >> > could safely be used for virtual function calls.
 >
 > >> I am afraid this violates constructors/destructor idea in its bases.
 > >> Thus said, if you need these, there is possibly something wrong with
 > >> your class hierarchies ;-)
 >
 > I couldn't have said it better myself :-).
 >
 > > I thought this idea has nothing to do with "constructor/destructor idea
 > > in its bases". The idea behind const/dest is left unchanged, I think.
 >
 > The problem is inherent in the following two facts.  The first is the
 > way C++ currently works (and must continue to work).  The second is the
 > way that C++ will work with the post-constructor.
 >
 > 1. The constructor of a derived class may use its base class.
 >
 > 2. An object that has not had its post-constructor called is not
 >    completely constructed (in a logical sense).  If it were, it wouldn't
 >    have needed a post-constructor.
 >
 > Therefore, a partially-constructed object could be manipulated by an
 > instance of its derived part.
 >
 > For example, imagine a hierarchy that includes the following definition:
 >
 >     class Derived : public Base { /* ... */ };
 >
 > Imagine also that class Base has a post-constructor.
 >
 > If the `Derived' constructor tries to use the `Base' part of itself, the
 > results will be erroneous, because Base::post_constructor() has not yet
 > been called.
 >
 > If the results could not be erroneous, then the post-constructor is
 > unnecessary.

What you are missing is that objects are no standalone entities, but
stand in relation to other objects in the program. For example, an
object could provide a service. Now there might be another object that
informs which objects can give you which sort of service. This other
object needs to be notified about the new object, but of course only
when the object is fully constructed (else someone would possibly try
to contact the half-constructed object).

Thus you can characterize the different stages as the following:

1. The constructor (completely) constructs the object.
2. The post-constructor puts the newly constructed object in relation
   to the rest of the program (f.ex. registering it)
3. The pre-destructor disconnects the object from the rest of the program
4. The destructor destructs the object.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/30
Raw View
No, no, no !

We want to avoid #define because they are ugly. We can avoid
them often in C++. I say that in my web pages and applies that
in everyday programming.

But there are a few cases where I really want a macro. I don't
think we must ban them; just use them in one file out of 20
(include gards not counted).

Please do not replace macros with something _more_ ugly.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Mark Zeren" <zeren@pobox.com>
Date: 1997/10/30
Raw View
jodle wrote in message <630vmt$lh9@lotho.delphi.com>...
>Mark Zeren (zeren@pobox.com) wrote:
>: How about the ability to override operator.()?
>
>Why stop there?  I want to be able to overload the whitespace operator.
>Consider:

I'm not sure why overriding the dot operator should be so ridiculous. If you
want to have an object act as a proxy for a reference (in the same way that
auto_ptr is a proxy for a ptr) then you need to be able to override op.().

mjz
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: miker3@ix.netcom.com (Michael Rubenstein)
Date: 1997/10/30
Raw View
On 29 Oct 97 06:35:36 GMT, claus@faerber.muc.de (Claus Andr=E9 F=E4rber)
wrote:

><mfinney@lynchburg.net> schrieb:
>> In <34536ded.1997962@nntp.ix.netcom.com>, miker3@ix.netcom.com (Michae=
l Rubenstein) writes:
>> >Today just about every C++ compiler program is also a C compiler
>> >(read: every one I've seen).  Is this going to change?
>>
>> I thought so also, until last week. ...
>
>The Gnu C/C++ are two different compilers too. They only have a common =20
>user interface program gcc, which calls the preprocessor, and the C or =20
>C++ or Obj.-C compiler dependent on the type of input file.

This is, to say the least, misleading.  The C compiler and the C++
compiler have a great deal of code in common.  From the makefile
templates:
=09
Language-specific object files for C++:
 call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o
 class.o decl2.o error.o gc.o lex.o parse.o ptree.o
 spew.o typeck.o cvt.o edsel.o except.o init.o
 method.o search.o tree.o xref.o repo.o
=09
Language-specific object files for C:
 c-parse.o c-lang.o c-lex.o c-pragma.o
 c-decl.o c-typeck.o c-convert.o c-aux-info.o
 c-common.o c-iterate.o
=09
Language-specific object files for Objective C:
 objc-parse.o objc-act.o c-lex.o c-pragma.o
 c-decl.o c-typeck.o c-convert.o c-aux-info.o
 c-common.o c-iterate.o
=09
Language-independent object files:
 toplev.o version.o tree.o print-tree.o
 stor-layout.o fold-const.o function.o stmt.o
 expr.o calls.o expmed.o explow.o optabs.o varasm.o
 rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o
 dbxout.o sdbout.o dwarfout.o xcoffout.o
 integrate.o jump.o cse.o loop.o unroll.o flow.o
 stupid.o combine.o regclass.o local-alloc.o
 global.o reload.o reload1.o caller-save.o
 insn-peep.o reorg.o sched.o final.o recog.o
 reg-stack.o insn-opinit.o insn-recog.o
 insn-extract.o insn-output.o insn-emit.o
 insn-attrtab.o $(out_object_file) getpwd.o convert.o

There are a lot of ways of thinking about programs and sometimes it is
not appropriate to consider a program to be the same as an executable.

My point was not that the same executable is used for both C and C++
compilation.  That's really not very important.  I'd guess that just
about every C/C++ compiler has code at or before the end of
preprocessing that looks something like:

 if (cplusplus)
   compile_cplusplus();
 else
   compile_c();

The code that does the work of compiling the different languages may
be linked in or it may be a separate executable (or an overlay, or a
DLL, or ...).  That's a packaging question which has nothing to do
with my point.

But, like gcc/g++, my guess is that a lot of code is shared between
the C and C++ compilers.

My point is valid if

 1. After adding variable arrays to the C compiler, it is easy=20
    to add them to the C++ compiler.

 2. Politically it is desirable to do so.

In most cases, it should be very easy once it's been done for C.  The
question is whether it is desirable.  My bet is that virtually all
implementors will decide yes; of course, here gnu isn't a question --
they've already added variable length arrays to both C and C++ as an
extension.

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jbuck@synopsys.com (Joe Buck)
Date: 1997/10/30
Raw View
claus@faerber.muc.de writes:
>The Gnu C/C++ are two different compilers too. They only have a common
>user interface program gcc, which calls the preprocessor, and the C or
>C++ or Obj.-C compiler dependent on the type of input file.

Incorrect.  It is true that there are separate executables cc1, cc1plus,
and cc1obj, but more than 80% of the object code in these programs is the
same (for C and Objective-C it's probably 97% the same).  The structure is
that there is a language-dependent front end and a language-independent
back end, and all three executables share the same back end.


--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
 If you thought flashing ads on Web sites were annoying, wait till the Web
 and your operating system are "seamlessly integrated" and watch the
 pulsating promotional crud spill out over your desktop.  -- Scott Rosenburg
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Josh Stern <jstern@citilink.com>
Date: 1997/10/30
Raw View
I don't think that what I proposed is more "ugly" than
macros.  I should probably give some more fleshed out examples
to show elegant use (also note that I did not say anything
about banning macros and I'm sure that would not happen for
compatibility reasons if nothing else).   Really though,
it is the safety of argument binding that is most important
I think, with aesthetics coming only second.

- Josh
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David Cogen <cogen@ll.mit.edu>
Date: 1997/10/30
Raw View
> An aside: actually, in the larger scheme of things, I am not as
> much against the concept of macros as, say, Bjarne Stroustrup is,
> however I agree that cpp is a very poor macro facility and
> arbitrary text replacement is a poor macro functionality.
> Given something like the functionality of macros in Common Lisp
> the picture changes.

Exactly. I want to be able to evaluate C++ code at compile time, using an
improved macro preprocessor. The macro will be defined in terms of a template
of strings. The C++ code will evaluate to a string, to be
substituted for the macro call.

This way I can write my own control constructs, and do other advanced things
that are impossible with the current preprocessor.

For a quick example, I could define a "loop_over_x_y" iterator, which would be
used to step two variables: one for loop inside the other.


loop_over_x_y would be used like this:

  loop_over_x_y (i i_count) (j j_count) {
    stat1 ();
    stat2 ();
  }


which would macro-expand into:

  for (i = 0; i < i_count; ++ i) {
    for (j = 0; j < j_count; ++ j_count) {
      stat1 ();
      stat2 ();
    }
  }


And the macro could be defined something like this:

macro loop_over_x_y ((first_var_name first_var_count_expr)
                     (second_var_name second_var_count_expr)
                     ,@ body)
{
  string_stream result;

  // Format the first for line.
  result << "for (" << first_var_name << " = 0; " << first_var_name << " < "
    << first_var_count_expr << "; ++ " << first_var_name << ") {\n";

  // Format the second for line.
  result << "for (" << second_var_name << " = 0; " << second_var_name << " < "
    << second_var_count_expr << "; ++ " << second_var_name << ") {\n";

  // Format the body and closing braces.
  result << body << "\n}\n}\n" << ends;

  return result.str ();
}


Why must C++ be 30 years behind Lisp?

-- David
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: micha@aishdas.org
Date: 1997/10/30
Raw View
On 30 Oct 97 08:07:58 GMT, Mark Zeren <zeren@pobox.com> wrote:
: I'm not sure why overriding the dot operator should be so ridiculous.

How then would you ever refer to the real member b of object a? At least
if pa->b is overloaded I can fall back on (*pa).b. Perhaps "(&a)->b" if
not overloaded?

It would seem that you are hiding all non-operator members from any context
outside the object defintion.

-mi

--
Micha Berger (973) 916-0287      Help free Ron Arad, held by Syria 3953 days!
micha@aishdas.org                         (16-Oct-86 - 30-Oct-97)
For a mitzvah is a candle, and the Torah its light.
http://aishdas.org -- Orthodox Judaism: Torah, Avodah, Chessed
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1997/10/30
Raw View
--Multipart_Wed_Oct_29_10:42:17_1997-1
Content-Type: text/plain; charset=US-ASCII

micha@aishdas.org writes:

> On 28 Oct 97 17:03:55 GMT, Darron Shaffer <darron.shaffer@beasys.com> wrote:
> :   2)  Add some tokens for new NON DEFINED operators.
>
> How do you define precedence and associativity for these things?
>

You perhaps say:

  1) All infix free operators associate left to right, and have a
     precedence between the additive operators and the shift
     operators.

  2) All prefix/postfix free operators have the same
     precedence/associativity as ++.


These may not be the exact rules used, but the point is that these
issues are decided once and for all ahead of time.  This makes coding
the parser for a compiler no more difficult than it already is.



--Multipart_Wed_Oct_29_10:42:17_1997-1
Content-Type: text/plain; charset=US-ASCII

 __  __  _
 _ ) ___ _\
 __) __    \  Enterprise Middleware Solutions Darron J. Shaffer
              BEA Systems Inc.   Sr. Software Engineer
              17101 Preston Rd   darron.shaffer@beasys.com
              LB# 115, Ste 260    Voice: (972) 738-6137
              Dallas, TX 75248    Fax:   (972) 738-6111
       http://www.beasys.com

--Multipart_Wed_Oct_29_10:42:17_1997-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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jodle@bix.com (jodle)
Date: 1997/10/30
Raw View
Paul D. DeRocco (pderocco@ix.netcom.com) wrote:
: jodle wrote:
: >
: > This would work with builtin types as well.  Dare I mention support for
: > kinds?  This, of course, is more relevant to dynamic type and has broader
: > implications for the language.  Consider:
: >
: > void f(Base* a)
: >     {
: >     kind type = typeof(a);
: >     type o = a;
: >     type* p = new type;
: >     // ...
: >     }
: >
: > This is radically different from the C++ we know today.  For example, the
: > size and type of o is unknown until type's initializer is evaluated at
: > runtime.  We fare a little better where p is concerned, but its
: > initializer becomes a major problem: the call to new cannot be bound until
: > runtime.  So, suddenly, we find ourselves supporting dynamic binding
: > without the aid of a convenient object pointer.

: The proper place for a pointer to the "operator new" for a type
: is, I suppose, in its typeinfo object. But it wouldn't be
: practical unless it was restricted, say, to two versions, one
: using the default constructor and the other using the copy

You haven't convinced me that these are the only kinds of constructors
that are practical.

: By the way, why call it a "kind"? Why not just call it a "type"?

Prior art refers to a type that refers to types as a "kind."  See Luca
Cardelli's paper on typeful programming.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: boukanov@sentef1.fi.uib.no (Igor Boukanov)
Date: 1997/10/30
Raw View
Petteri Ollila (petteri.ollila@tietogroup.com) wrote:  > How about const
contructors:

> class A
> {
> public:
>  A() ;
>  A() const ;
> ...
> } ;

I think a better idea would be to introduce say true local
variables, i.e. variables that address can not be assigned
to a pointer / refference with lifetime potentially greater
than that of the variable itself.
Here is an example of how one can and can not use them:

int* x1;
const int* x2;

void f(local int z, local int *t) {
   local int* y1 = &z; // correct because the lifetime of y1 <= z
   local int* y2 = t;  // also correct
   x = t;  // error - it is possible that lifetime of x > lifetime *t
   x2 = t; // also error
   int* x3 = t; // error - x3 can be potentially assigned to x1 for example
}

struct S;
....

struct test {
   S* s;
   void foo(local S* another) {
       s = another; // error
       s = new S(another); // ok
   }
}


Also with the definition like
struct A {
   A() local;
}

the code "const A a;"
would introduce the const object for sure because from the declaration
of A it is known that the constructor would not be able to assign "this"
to some global pointer, i.e. the code like
A* non_const_pointer;
A::A() local {
   non_const_pointer = this;
}
would be illegal.

Even more, given the declaration
void foo2(local A*);

the compiler would be able to replace code like

local A* p = new A();
foo2(p);
delete p;

by
{
  A tmp;
  local A* p = &tmp;
  foo2(p);
}

Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <cxl@usa.net>
Date: 1997/10/30
Raw View
>  > >> I am afraid this violates constructors/destructor idea in its
> bases.
>  > >> Thus said, if you need these, there is possibly something wrong
> with
>  > >> your class hierarchies ;-)
>  >
>  > I couldn't have said it better myself :-).

> What you are missing is that objects are no standalone entities, but
> stand in relation to other objects in the program. For example, an
> object could provide a service. Now there might be another object that
>
> informs which objects can give you which sort of service. This other
> object needs to be notified about the new object, but of course only
> when the object is fully constructed (else someone would possibly try
> to contact the half-constructed object).
>
> Thus you can characterize the different stages as the following:
>
> 1. The constructor (completely) constructs the object.
> 2. The post-constructor puts the newly constructed object in relation
>    to the rest of the program (f.ex. registering it)
> 3. The pre-destructor disconnects the object from the rest of the
> program
> 4. The destructor destructs the object.

    I am sure, that you often need this behaviour. But please consider
difference between words 'constructing' and 'conecting', 'registering'
and so on.

    I think that construction and destruction generally should not place
object in relation with any other objects than (possibly) its members.
Anything else is not construction (destruction).

    What I wrote just now is not a momental idea I got right now but
conclusion of long term experience. When I started using C++ I usually
left my constructors to do as much as possible. But very often that led
to design disastres...

    Besides, have you consider how to tell to post-constructor where he
has to register ?

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jodle@bix.com (jodle)
Date: 1997/10/30
Raw View
Valentin Bonnard (bonnardv@pratique.fr) wrote:
: jodle wrote:
: >  Consider:
: >
: > void f(Base* a)
: >     {
: >     kind type = typeof(a);
: >     type o = a;
: >     type* p = new type;
: >     // ...
: >     }
: >
: > This is radically different from the C++ we know today.

: typeof is a way to know the declared type of an object; it's
: usable as a type name.

You're missing the key trait that is a departure from the current C++
paradigm and features proposed for typeof thus far.  The previously
proposed typeof does not allow anything at all like:

  typeof(&a) p = new typeof(a);

That is, it neither provides bindings to allow its use with the new
operator, nor the ability to allocate pointer-type objects for storing the
resulting 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Colin Rafferty <craffert@ml.com>
Date: 1997/10/30
Raw View
Christopher Eltschka writes:
> Colin Rafferty wrote:
>> Sergei Organov writes:
>> > Mirek Fidler wrote:

>> >> > How about, let's call them, 'post-constructors' and 'pre-destructors'?

>> >> > The idea is to allow one to declare member function in base class to be
>> >> > called automatically after the most derived constructor returns ('post-
>> >> > constructor'); or before the most derived destructor is called
>> >> > ('pre-destructor'). Because unlike constructors and destructors these
>> >> > functions are invoked on fully constructed objects, the dynamic binding
>> >> > could safely be used for virtual function calls.

>> >> I am afraid this violates constructors/destructor idea in its bases.
>> >> Thus said, if you need these, there is possibly something wrong with
>> >> your class hierarchies ;-)

>> I couldn't have said it better myself :-).

>> > I thought this idea has nothing to do with "constructor/destructor idea
>> > in its bases". The idea behind const/dest is left unchanged, I think.

>> The problem is inherent in the following two facts.  The first is the
>> way C++ currently works (and must continue to work).  The second is the
>> way that C++ will work with the post-constructor.

>> 1. The constructor of a derived class may use its base class.

>> 2. An object that has not had its post-constructor called is not
>> completely constructed (in a logical sense).  If it were, it wouldn't
>> have needed a post-constructor.

>> Therefore, a partially-constructed object could be manipulated by an
>> instance of its derived part.

>> For example, imagine a hierarchy that includes the following definition:

>> class Derived : public Base { /* ... */ };

>> Imagine also that class Base has a post-constructor.

>> If the `Derived' constructor tries to use the `Base' part of itself, the
>> results will be erroneous, because Base::post_constructor() has not yet
>> been called.

>> If the results could not be erroneous, then the post-constructor is
>> unnecessary.

> What you are missing is that objects are no standalone entities, but
> stand in relation to other objects in the program.

I am not missing it at all, thank you.  I simply chose to argue that, in
general, post-constructor solves absolutely nothing.

In my previous post (see above), I described a general problem that
post-constructor introduces.  Below your description of a particular
problem, and how post-constructor seems to solve it, I will demonstrate
how it does not really do this.

> For example, an
> object could provide a service. Now there might be another object that
> informs which objects can give you which sort of service. This other
> object needs to be notified about the new object, but of course only
> when the object is fully constructed (else someone would possibly try
> to contact the half-constructed object).

> Thus you can characterize the different stages as the following:

> 1. The constructor (completely) constructs the object.
> 2. The post-constructor puts the newly constructed object in relation
>    to the rest of the program (f.ex. registering it)
> 3. The pre-destructor disconnects the object from the rest of the program
> 4. The destructor destructs the object.

Picture the same class hierarchy as above (Derived derived from Base).
We say that Base needs to register itself in its post-constructor.

Now imagine that the implementor of Derived wanted to use the same
post-constructor trick in order to finish logically constructing itself.
If it has its virtual function `f' called on it before it is
post-constructed, the result will be undefined.

1. Base::ctor() called on object X.
2. Derived::ctor() called on object X.
3. Base::post-ctor() called on object X.  Base registers itself in the
   global registry.
4. In another thread, something gets X out of the registry, calls
   virtual function `f'.
5. Derived::post_ctor() called on object X.

You can see that the result of Step 4 is undefined.

We have not solved the problem for real.  We have simply deferred it to
the post-constructor.

So what is the solution to the registry/thread problem?  I don't know, I
haven't done enough thread programming to answer this.  However, it
seems

Maybe the problem is that you should rethink how you are managing your
objects in the first place.  Maybe the regsitry should be creating them
itself, rather than having them scattered about.

--
Colin
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jodle@bix.com (jodle)
Date: 1997/10/30
Raw View
Gary Powell (gary.powell@nospam.sierra.com) wrote:

: I have longed for being able to overload operator.() because I wanted to
: write a really smart pointer class, one I could use for debugging and turn
: off for release code.

What does an overloaded operator.() have to do with pointer semantics?  I
thought you used -> with pointers.  That operator has been overloadable
for some time.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jstern@citilink.com (Josh Stern)
Date: 1997/10/30
Raw View
Valentin Bonnard  <bonnardv@pratique.fr> wrote:
>No, no, no !
>
>We want to avoid #define because they are ugly. We can avoid
>them often in C++. I say that in my web pages and applies that
>in everyday programming.

I think mainly we want to avoid #define because they are
unsafe and can generate unpredictable results that depend on
their context of application.  They also make things hard for
use of source-level debuggers.

>But there are a few cases where I really want a macro. I don't
>think we must ban them;

Whoa, I didn't say anything about banning macros.  I'm sure that
they would not be banned for compatibility reasons alone.
My suggestions were just in line (excuse the pun) with the
project of providing better, safer, alternatives for common
examples of macro usage.

An aside: actually, in the larger scheme of things, I am not as
much against the concept of macros as, say, Bjarne Stroustrup is,
however I agree that cpp is a very poor macro facility and
arbitrary text replacement is a poor macro functionality.
Given something like the functionality of macros in Common Lisp
the picture changes.


>just use them in one file out of 20
>(include gards not counted).

>Please do not replace macros with something _more_ ugly.

I'll agree to provide some more fleshed out examples of
elegant use of what I proposed if you point me in the
direction of what you think was "ugly" about it.
Syntactically, my proposal of using 'noscope' would
look just like using inline.  Are you worried about
extra name clashes because of the noscope operation?
My assumption is that it would be easy for a compiler
to always warn about such clashes.


- Josh
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/28
Raw View
jodle wrote:
>
> This would work with builtin types as well.  Dare I mention support for
> kinds?  This, of course, is more relevant to dynamic type and has broader
> implications for the language.  Consider:
>
> void f(Base* a)
>     {
>     kind type = typeof(a);
>     type o = a;
>     type* p = new type;
>     // ...
>     }
>
> This is radically different from the C++ we know today.  For example, the
> size and type of o is unknown until type's initializer is evaluated at
> runtime.  We fare a little better where p is concerned, but its
> initializer becomes a major problem: the call to new cannot be bound until
> runtime.  So, suddenly, we find ourselves supporting dynamic binding
> without the aid of a convenient object pointer.

The proper place for a pointer to the "operator new" for a type
is, I suppose, in its typeinfo object. But it wouldn't be
practical unless it was restricted, say, to two versions, one
using the default constructor and the other using the copy
constructor. A type that failed to supply one or the other would
have that slot in the typeinfo pointed to an error handler, in
case it was ever invoked. This would allow you to write

 type* p = new type;

or

 type* q = new type(*p);

but not

 type* r = new type(foo, 100, (2 * x) - 1);

since that isn't a set of parameters that we would expect to be
meaningful for any type.

By the way, why call it a "kind"? Why not just call it a "type"?

void f(Base* a) {
    type T = typeof(a);
    T o = a;
    T* p = new T;
    }

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1997/10/28
Raw View
--Multipart_Tue_Oct_28_09:25:03_1997-1
Content-Type: text/plain; charset=US-ASCII

fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
> jodle@bix.com (jodle) writes:
>
> >Mark Zeren (zeren@pobox.com) wrote:
> >: How about the ability to override operator.()?
> >
> >Why stop there?  I want to be able to overload the whitespace operator.
>
> C++ doesn't have a whitespace operator.
> (It _does_ have a `.' operator.)
>
> >I further propose that an operator should be able to change its own
> >precedence and direction of binding at runtime.
>
> Mildly amusing parody, but I think you are straying from the issue.
> Changing precedence at runtime is meaningless, since in C++ parsing
> is done at compile time, not at runtime.  Allowing user-defined
> precedence at all would be a significant increase in complexity
> for dubious gain.  Overloading operator `.', however, would be no
> more complex than overloading operator `->'.
>

However, a pair of reasonable suggestions regarding operator
overloading:

  1)  Add 3 new keywords and allow:

 T & prefix ++(T &);
 T posfix ++(T &);
 T & infix +(const T &, const T &);

 Or, the phrase could be "prefix operator ++".

  2)  Add some tokens for new NON DEFINED operators.  These would have
      to be known to the lexical analyzer ahead of time, but have to
      defined meaning for built in types.  They would probably also
      have to be assigned a fixed precedence.

      There aren't many possibilites, since C++ uses nearly every
      character it can get its hands on already, but how about:

 1) @ or $ followed by any number of ~@!$%^&*/-_=+|<>?.A-Za-z0-9

    For example:

  class Matrix;
  Matrix infix @dotProd(const Matrix &, const Matrix &);

  Matrix a, b, c;

  c = a @dotProd b;

        OR

  c = a @+/* b;


I freely admit stealing both of these ideas from Eiffel.



--Multipart_Tue_Oct_28_09:25:03_1997-1
Content-Type: text/plain; charset=US-ASCII

 __  __  _
 _ ) ___ _\
 __) __    \  Enterprise Middleware Solutions Darron J. Shaffer
              BEA Systems Inc.   Sr. Software Engineer
              17101 Preston Rd   darron.shaffer@beasys.com
              LB# 115, Ste 260    Voice: (972) 738-6137
              Dallas, TX 75248    Fax:   (972) 738-6111
       http://www.beasys.com

--Multipart_Tue_Oct_28_09:25:03_1997-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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/10/29
Raw View
On 24 Oct 97 16:20:13 GMT, Theodore Papadopoulo
<Theodore.Papadopoulo@sophia.inria.fr> wrote:

>I would really like to be able to do arrays of references.
>I realize that those are not allowed on purpose (pbs with
>array initialisation ?) but I hope that the problems to
>overcome to have this feature are not unsolvable.

The way references are specified in C++ makes them completely
incompatible with C-style arrays. A fundamental property of an array
is that the Nth element is located N*sizeof(element-type) bytes from
the beginning of the array. That property does not hold for
references. The interchangability of pointers and arrays in
expressions would also be a problem for arrays of references.

To have arrays of references you must either change the C++
specification of what a reference type is, or do violence to the
fundamental properties of arrays and the meaning of operations on
arrays. By deliberate design decision, C++ does not allow arrays of
references nor pointers to references.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: micha@aishdas.org
Date: 1997/10/29
Raw View
On 28 Oct 97 17:03:55 GMT, Darron Shaffer <darron.shaffer@beasys.com> wrote:
:   2)  Add some tokens for new NON DEFINED operators.

How do you define precedence and associativity for these things?

Whay I'd like to see, and was provided in ABC a C++ extension, is the
ability to overload groups of operators. This comes in handy in implementing
x[2][3] without helper classes, as well as optimizing matrix mathematics.

The replacement would be post-parsing, so that both
 (a * x) + b
 a * x + b
invoke operator *+ (aka operator (*)+ and not to be confused with
operator*(+) ).

I'd also like more "class object" power given to type_info. But that may just
be my Java experience talking.

-mi

--
Micha Berger (973) 916-0287      Help free Ron Arad, held by Syria 3951 days!
micha@aishdas.org                         (16-Oct-86 - 28-Oct-97)
For a mitzvah is a candle, and the Torah its light.
http://aishdas.org -- Orthodox Judaism: Torah, Avodah, Chessed
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Colin Rafferty <craffert@ml.com>
Date: 1997/10/29
Raw View
Sergei Organov writes:
> Mirek Fidler wrote:

>> > How about, let's call them, 'post-constructors' and 'pre-destructors'?

>> > The idea is to allow one to declare member function in base class to be
>> > called automatically after the most derived constructor returns ('post-
>> > constructor'); or before the most derived destructor is called
>> > ('pre-destructor'). Because unlike constructors and destructors these
>> > functions are invoked on fully constructed objects, the dynamic binding
>> > could safely be used for virtual function calls.

>> I am afraid this violates constructors/destructor idea in its bases.
>> Thus said, if you need these, there is possibly something wrong with
>> your class hierarchies ;-)

I couldn't have said it better myself :-).

> I thought this idea has nothing to do with "constructor/destructor idea
> in its bases". The idea behind const/dest is left unchanged, I think.

The problem is inherent in the following two facts.  The first is the
way C++ currently works (and must continue to work).  The second is the
way that C++ will work with the post-constructor.

1. The constructor of a derived class may use its base class.

2. An object that has not had its post-constructor called is not
   completely constructed (in a logical sense).  If it were, it wouldn't
   have needed a post-constructor.

Therefore, a partially-constructed object could be manipulated by an
instance of its derived part.

For example, imagine a hierarchy that includes the following definition:

    class Derived : public Base { /* ... */ };

Imagine also that class Base has a post-constructor.

If the `Derived' constructor tries to use the `Base' part of itself, the
results will be erroneous, because Base::post_constructor() has not yet
been called.

If the results could not be erroneous, then the post-constructor is
unnecessary.

--
export-a-crypto-system, see: http://www.dcs.ex.ac.uk/~aba/rsa/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: claus@faerber.muc.de (=?ISO-8859-1?Q?Claus_Andr=E9_F=E4rber?=)
Date: 1997/10/29
Raw View
<mfinney@lynchburg.net> schrieb:
> In <34536ded.1997962@nntp.ix.netcom.com>, miker3@ix.netcom.com (Michael=
 Rubenstein) writes:
> >Today just about every C++ compiler program is also a C compiler
> >(read: every one I've seen).  Is this going to change?
>
> I thought so also, until last week. ...

The Gnu C/C++ are two different compilers too. They only have a common =20
user interface program gcc, which calls the preprocessor, and the C or =20
C++ or Obj.-C compiler dependent on the type of input file.

--=20
Claus Andr=E9 F=E4rber <http://www.muc.de/~cfaerber/> Fax: +49-8061-3361
PGP: ID=3D1024/527CADCD FP=3D12 20 49 F3 E1 04 9E 9E 25 56 69 A5 C6 A0 C9=
 DC
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: petteri.ollila@tietogroup.com (Petteri Ollila)
Date: 1997/10/29
Raw View
How about const contructors:

class A
{
public:
 A() ;
 A() const ;
...
} ;

I have only needed this once when writing a wrapper for
a database api, to open the database in readonly mode
for performance reasons but I was almost surprised that
it would not compile ;-)

A more widely useful feature would be the closure contruct
of Borland C++. It allows callbacks to any member function
with compatible signature in any class. I have not found a
way to do this neatly in standard C++.

__
Petteri Ollila
Tieto 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Tero Pulkkinen <terop@assari.cc.tut.fi>
Date: 1997/10/29
Raw View
[snipped out const constructors issue]

petteri.ollila@tietogroup.com (Petteri Ollila) writes:
> A more widely useful feature would be the closure contruct
> of Borland C++. It allows callbacks to any member function
> with compatible signature in any class. I have not found a
> way to do this neatly in standard C++.

This is not needed - It would be a convinience, but this can be provided by
a library. (The library implementation becomes somewhat ugly, but use of
it is typesafe and as straightforward as it would be with builtin feature
inside the language)

Check http://www.cs.tut.fi/~p150650/sigslot.html for an example of
such library.

Even though this style of programming can be supported by a library,
it might be good to have some support to ease the implementation of
that library - currently the implementation needs some hacks to get
over the limitations of C++'s templates. What would be needed is some
compile time support for variable amount of template parameters and
ways to use those in various places like in function's parameter lists
or for declaring variables.

I mean, there could be way to generate the following functions
from one function implementation:

   void foo();
   template<class T> void foo(T, T*);
   template<class T,class K> void foo(T, T*, K, K*);
   template<class T,class K, class M> void foo(T, T*, K, K*, M, M*);
   etc...

This can currently be implemented by cut/pasting library
implementation (with preprocessor), but it becomes kinda bad
maintainance problem in design of such systems.

But IMHO, we dont need explicit support for borland-style closures, better
have more general way for people to build such systems.

--
-- Tero Pulkkinen -- terop@modeemi.cs.tut.fi --
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/29
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

|>  Overloading operator `.', however, would be no
|>  more complex than overloading operator `->'.

Not quite, although it wouldn't be significantly more complex (IMHO).
There is the problem that operator. is already defined for class types,
which would have to be addressed.  (E.g. does it inherit, like
operator&, or not, like operator=?)  But it is certainly doable, and
(again, IMHO) worth the effort.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jstern@citilink.com (Josh Stern)
Date: 1997/10/29
Raw View
The goal of eliminating much of the need for preprocessor macros
in the C++ language is well known, as is the fact that one of the
C++ language mechanisms most commonly used for this purpose is
the 'inline' function.

One way in which the inline function fails as a replacement for
a macro however is that it introduces its own function scope.
This prevents some examples where one wants to use a macro
group a set of related statements together, but where the
The added context of the inline function call gets in the
way of this goal.

The following sort of convenience  macros are problematic
to replace:

#define RETURN_IF_BAD(E) if (!SomeTestOf((E))) { \
   PrintErrorMsg(); return error_code; }

and given

template <class T>
class destroy_array {
  T* d_deletable;
public:
  destroy_array(T* todel) : d_deletable(todel) {}
  T* data() { return d_deletable; }
  ~destroy_array() { delete [] d_deletable; }
};

the macro

#define AUTO_NEW(T,N) (destroy_array tmpXXXXX(new T[(N)]) , \
                         tmpXXXXX.data())

is also not replaceable by an inline function.  The same
problem would occurs for any group of operations we want
to construct things that persist until the end of the
enclosing scope.

To get around these inconveniences I would like to
see a 'noscope' function that behaves much like an
inline function - in particular, it should bind its
arguments safely, just like an inline function does and be
amenable to the same sort of compiler discrection -
but which introduces no further scope around the
rest of its body.  The keyworld 'noscope' would be
used in contexts where 'inline' is used.  To distinguish
between the ordinary inline function like use of
return and the invocation of return in my first
macro example above, I would propose the keywork
'outerexit'.  This keyword would be used wherever
return is used in noscope function except that the
type of its argument would be required to match
the expected return type of the calling function.
In case of outerexit, destructors in the calling
function would be executed as with an exception
throw.


- Josh
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <rylek@cslab.felk.cvut.cz>
Date: 1997/10/26
Raw View
> How about, let's call them, 'post-constructors' and 'pre-destructors'?
>
> The idea is to allow one to declare member function in base class to be
> called automatically after the most derived constructor returns ('post-
> constructor'); or before the most derived destructor is called
> ('pre-destructor'). Because unlike constructors and destructors these
> functions are invoked on fully constructed objects, the dynamic binding
> could safely be used for virtual function calls.

    I am afraid this violates constructors/destructor idea in its bases.
Thus said, if you need these, there is possibly something wrong with
your class hierarchies ;-)

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/26
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

>Fergus Henderson <fjh@murlibobo.cs.mu.OZ.AU> writes:
>
>> kanze@gabi-soft.fr (J. Kanze) writes:
>>
>> >As long as the "as if" rule is in
>> >effect, statements like "implementations should not inline functions
>> >..." are meaningless.
>>
>> Well, if you really want to be pedantic, then the standard need just
>> make it clear that the "as if" rule doesn't apply in this case, e.g.
>> by changing the wording to
>>
>>     "implementations should not inline functions declared as `!inline',
>>     the ``as-if'' rule [cross-ref] notwithstanding."
>
>I'd like to see a formal definition of inlining. It seems
>very difficult to me.

True, but a formal definition of inlining would not be necessary
for `!inline' to be useful (just as a formal definition of inlining
is not necessary for `inline' to be useful).

>Also it means that you are able to recognise in the
>disassembly which instruction does what.

No, it doesn't mean that, at least not in the general case.
For the market forces to do their work, all that is needed
is _one_ example where a compiler does something obviously
against the intent of the rule above.

The point that people seem to be missing is that not everything needs
to be formally defined.  In many cases, informal definitions are
sufficient.  The Ada83 and Ada95 standards include many examples of
this.  In contrast, the C/C++ community doesn't seem to grasp this,
which leads to two negative consequences:

 (a) things which can't be defined formally are simply dropped;

 (b) the quality of the formal parts of the standard goes down,
     because sometimes things which really can't be defined formally
     are given supposedly-formal definitions which, from a formal
     perspective, are in fact meaningless.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/27
Raw View
Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> writes:

> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> >I'd like to see a formal definition of inlining. It seems
> >very difficult to me.
>
> True, but a formal definition of inlining would not be necessary
> for `!inline' to be useful (just as a formal definition of inlining
> is not necessary for `inline' to be useful).

IMO a formal definition of inlining would make the keyword
inline less usefull (if we say that functions declared inline
should be inlined).

> >Also it means that you are able to recognise in the
> >disassembly which instruction does what.
>
> No, it doesn't mean that, at least not in the general case.
> For the market forces to do their work, all that is needed
> is _one_ example where a compiler does something obviously
> against the intent of the rule above.

Thus, what about a pragma:

#pragma code_inline yes
#pragma code_inline no
#pragma code_inline <level>

These can only apply to a inline function. It's a hint to
the compiler to tell if the function code should be in-line
or out-of-line.

> The point that people seem to be missing is that not everything needs
> to be formally defined.  In many cases, informal definitions are
> sufficient.

The notion of what can be a signal handler (ie, anything which is
both a C function and a C++ function) seems informal enough to me. ;-)

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jodle@bix.com (jodle)
Date: 1997/10/27
Raw View
Mark Zeren (zeren@pobox.com) wrote:
: How about the ability to override operator.()?

Why stop there?  I want to be able to overload the whitespace operator.
Consider:

mytype operator(const mytype&, const mytype&);

// ...

mytype a,b,c,d,e,f,g;

a = b c d e f g;

I further propose that an operator should be able to change its own
precedence and direction of binding at runtime.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jodle@bix.com (jodle)
Date: 1997/10/27
Raw View
Joe Buck (jbuck@synopsys.com) wrote:
: Jean-Louis Leroy <jll@skynet.be>:
: >> And a typeof operator.

: claus@faerber.muc.de writes:
: >Isn't that typeid()? Or do you want to write sth. like:

:     int     a;
:     typeof(a) b;

: > I can't see why:

: For nested types, of course (STL).  So that you can write, say

:  typeof(a)::iterator a_iter = a.begin();

: instead of, say

:  map<some_big_type, some_other_type, complex_comparison>::iterator ...

I've desired this for a long time, even if it is limited to static type.
An even simpler example is:

    typeof(a) a_copy = a;

This would work with builtin types as well.  Dare I mention support for
kinds?  This, of course, is more relevant to dynamic type and has broader
implications for the language.  Consider:

void f(Base* a)
    {
    kind type = typeof(a);
    type o = a;
    type* p = new type;
    // ...
    }

This is radically different from the C++ we know today.  For example, the
size and type of o is unknown until type's initializer is evaluated at
runtime.  We fare a little better where p is concerned, but its
initializer becomes a major problem: the call to new cannot be bound until
runtime.  So, suddenly, we find ourselves supporting dynamic binding
without the aid of a convenient object 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: miker3@ix.netcom.com (Michael Rubenstein)
Date: 1997/10/27
Raw View
On 26 Oct 97 08:42:35 GMT, Valentin Bonnard <bonnardv@pratique.fr>
wrote:

>Mike Rubenstein <miker3@ix.netcom.com> writes:
>
>> I don't see how C++ can avoid variable size arrays.  It seems certain
>> that they will be adopted in the C9x standard.
>
>[...]
>
>> Unless C++ breaks away from the idea of trying to be compatible with
>> C,
>
>C++ now has many incompatibillities with C, and I think that's
>best not to try to be compatible with C9x and to avoid the added
>complexity.

I don't particularly disagree as far as what would be desirable, but
you're missing part of my point:  What addeded complexity?

Today just about every C++ compiler program is also a C compiler
(read: every one I've seen).  Is this going to change?  I don't see
that happening.  The C compilers will be upgraded to C9x and will have
to support variable length arrays.  How many of the compler
manufacturers will add this as an extension to C++?  My guess is
"every one."

When the C++ standard is revised in 10 years, I predict that just
about every C++ compiler will support variable length arrays as an
extension.  Now what is your argument against incorporating variable
length arrays?  Added complexity?  That's going to be very hard to
justify when they've been implemented in most compilers.

My argument is not that variable length arrays should be part of the
standard; I agree with Stroustrup that vectors are almost always
preferable.  I argue that unless the forces driving C++ change, it
will not be possible to avoid them.

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/28
Raw View
jodle@bix.com (jodle) writes:

>Mark Zeren (zeren@pobox.com) wrote:
>: How about the ability to override operator.()?
>
>Why stop there?  I want to be able to overload the whitespace operator.

C++ doesn't have a whitespace operator.
(It _does_ have a `.' operator.)

>I further propose that an operator should be able to change its own
>precedence and direction of binding at runtime.

Mildly amusing parody, but I think you are straying from the issue.
Changing precedence at runtime is meaningless, since in C++ parsing
is done at compile time, not at runtime.  Allowing user-defined
precedence at all would be a significant increase in complexity
for dubious gain.  Overloading operator `.', however, would be no
more complex than overloading operator `->'.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Sergei Organov <osv@javad.ru>
Date: 1997/10/28
Raw View
Mirek Fidler wrote:
>
> > How about, let's call them, 'post-constructors' and 'pre-destructors'?
> >
> > The idea is to allow one to declare member function in base class to be
> > called automatically after the most derived constructor returns ('post-
> > constructor'); or before the most derived destructor is called
> > ('pre-destructor'). Because unlike constructors and destructors these
> > functions are invoked on fully constructed objects, the dynamic binding
> > could safely be used for virtual function calls.
>
>     I am afraid this violates constructors/destructor idea in its bases.
> Thus said, if you need these, there is possibly something wrong with
> your class hierarchies ;-)
>

I thought this idea has nothing to do with "constructor/destructor idea
in its bases". The idea behind const/dest is left unchanged, I think.
For example, what's wrong with idea to register object somewhere just
after creation? I think it's Ok. However, for example, in
multithreading environment it's dangerous thing to do in constructor
because the object isn't fully constructed yet. This leads to separate
function that should be called after the object is constructed:

Foo foo;
foo.register();

But what if programmer forgets to call 'register()'? Why don't allow
class designer to specify that 'register()' should be called
automatically?

Am I missing something?

Sergei Organov.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/28
Raw View
jodle wrote:
>  Consider:
>
> void f(Base* a)
>     {
>     kind type = typeof(a);
>     type o = a;
>     type* p = new type;
>     // ...
>     }
>
> This is radically different from the C++ we know today.

typeof is a way to know the declared type of an object; it's
usable as a type name.

typeid returns a typeinfo describing the dynamic type of an
object:

void f(Base* a)
    {
    const typeinfo& type = typeid (a); // ok
    Base* b = dynamic_cast<Base*> (type.default_create ());
                                     // my imagination

So whatever you want, propose to do it with typeid not
typeof.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/28
Raw View
fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson) writes:

|>  kanze@gabi-soft.fr (J. Kanze) writes:
|>
|>  >[...] most of the support for long long is coming from vendors [...]
|>  >The reason the vendors support it, of course, is that they implemented it
|>  >without thinking of the consequences, and now want to make it standard.
|>  >Sort of like gets, in a way (although nowhere near as dangerous).
|>
|>  I think this is quite unfair to the vendors, who probably _did_
|>  consider the consequences quite seriously (see John Mashey's posts
|>  to comp.std.c).

Well, comparing it to gets is probably unfair -- it's far from being
that broken, even in my mind.  Still, it does break existing code, and
it didn't have to.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Gary Powell" <gary.powell@nospam.sierra.com>
Date: 1997/10/28
Raw View
I proposed that classes be able to set the precedence for user defined
operators to some value back in the early 90's. The idea being able to
create useful math operators for matries. I have also longed for more
symbols, and the ability to concatenate two or three symbols like  ".*" ,
or "+.*" to do inner and outer product etc. It was rejected as making code
more difficult to read. And perhaps only licensed library code writers
should be allowed to use this, but there are good and nice reasons for
wanting it.

I have longed for being able to overload operator.() because I wanted to
write a really smart pointer class, one I could use for debugging and turn
off for release code.

After porting heaps of other people's code I wish for int8, ... int64. Then
data structs for saved data wouldn't
have to be changed. The code which manipulates this stuff tends to be less
restrictive, and only goes forward, so an int which is bigger than those in
the past ports is generally fine.

gary.powell.nospam@sierra.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: mfinney@lynchburg.net
Date: 1997/10/28
Raw View
In <34536ded.1997962@nntp.ix.netcom.com>, miker3@ix.netcom.com (Michael Rubenstein) writes:

>Today just about every C++ compiler program is also a C compiler
>(read: every one I've seen).  Is this going to change?

I thought so also, until last week.  I was told that the next version
of the IBM VisualAge C++ compiler and the associated C compiler
are entirely separate (again).  The drive to add more features to
C++ compilers may have reached the point that it is easier to
keep an independent C compiler rather than worry about the differences
between C and C++ in a single compiler.


Michael Lee Finney
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/24
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>[...] most of the support for long long is coming from vendors [...]
>The reason the vendors support it, of course, is that they implemented it
>without thinking of the consequences, and now want to make it standard.
>Sort of like gets, in a way (although nowhere near as dangerous).

I think this is quite unfair to the vendors, who probably _did_
consider the consequences quite seriously (see John Mashey's posts
to comp.std.c).

The reason the vendors support it is that their customers want
support for 64-bit integral types on 32-bit systems (where `long'
is already 32 bits), e.g. for accessing large files, or for checking
for integer overflow efficiently, or for efficiently implementing
arbitrary-precision integers, or for writing cross-compilers to 64-bit
systems, or for various other applications.  The vendors also know that
this support must not come at the cost of losing binary backwards
compatibility.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/24
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>|>  kanze@gabi-soft.fr (J. Kanze) writes:
>|>
>|>  >Except...  Given the way the standard defines a conforming
>|>  >implementation (one whose observable behavior is the same as one
>|>  >instantiation of the abstract machine), how could you ban inlining.
>|>
>|>  Simple: you add a statement to the language standard saying
>|>  "implementations should not inline functions declared as `!inline'."
>|>
>|>  >It has no effect on observable behavior.
>|>
>|>  Not as far as the standard is concerned, no, but as far as users
>|>  are concerned the effect is easily observable, so if you put a
>|>  statement like the above in the standard, then market forces will
>|>  have no trouble enforcing it.
>
>Like they enforce "inline" today?

The difference is that implementing `inline' is non-trivial,
and indeed can be very difficult for the tricky cases.
So this inherent difficult counteracts the market forces.

On the other hand `!inline' would be trivial to implement.

>As long as the "as if" rule is in
>effect, statements like "implementations should not inline functions
>..." are meaningless.

Well, if you really want to be pedantic, then the standard need just
make it clear that the "as if" rule doesn't apply in this case, e.g.
by changing the wording to

    "implementations should not inline functions declared as `!inline',
    the ``as-if'' rule [cross-ref] notwithstanding."

>And I'm curious as to how a user can observe
>the effect -- about the only way I can think of is disassembly, and I
>don't see any strong market forces affecting what a disassembler will
>show.

A disassembler will show what code the compiler actually generates.
If it doesn't do this, then the behaviour will be regarded as a severe
bug, so the market forces to ensure this are quite strong.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
herbs@cntc.com (Herb Sutter) writes:

|>  kanze@gabi-soft.fr (J. Kanze) wrote:
|>  >bs@research.att.com (Bjarne Stroustrup) writes:
|>  >|>  C and C++ are so closely associated (in reality and in the minds of many
|>  >|>  people) that what harms the one usually harms the other. I suspect that
|>  >|>  more coordination of their evolution is needed.
|>  >
|>  >Starting with "complex"?  (I can understand the historical reasons why
|>  >C++ has a class, and C a built-in type.  But really, it would be nice if
|>  >they both were the same.)
|>
|>  Bjarne is right that more coordination is needed. Still, there has always been
|>  some coordination, and each of WG14 and WG21 has shown some active interest in
|>  what the other is doing. Several people are active members of both committees.

There's actually a lot of coordination, although I'm a bit disappointed
in the results with regards to inline.  The problems with complex are
linked to history, and so difficult to resolve.  (Basically, C++ had
complex long before C ever thought about it, or before anyone considered
that C might want it as well.  But the C++ solution, which uses
overloaded operators, simply doesn't work in C.  In some ways, I think
the "correct" solution would be to drop complex from the current C++
standard, and pick up the C version next go around, but then, I would
say that: my applications never use it:-).  And such a move today, or
even at the point when we first knew that C would have a builtin complex
type, would be impossible within the standardization framework without
setting the C++ standard back a year or so -- another CD vote, at
least.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Sergei Organov <osv@javad.ru>
Date: 1997/10/24
Raw View
How about, let's call them, 'post-constructors' and 'pre-destructors'?
The idea is to allow one to declare member function in base class to be
called automatically after the most derived constructor returns ('post-
constructor'); or before the most derived destructor is called
('pre-destructor'). Because unlike constructors and destructors these
functions are invoked on fully constructed objects, the dynamic binding
could safely be used for virtual function calls.

Sergei Organov
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

|>  kanze@gabi-soft.fr (J. Kanze) writes:
|>
|>  >Except...  Given the way the standard defines a conforming
|>  >implementation (one whose observable behavior is the same as one
|>  >instantiation of the abstract machine), how could you ban inlining.
|>
|>  Simple: you add a statement to the language standard saying
|>  "implementations should not inline functions declared as `!inline'."
|>
|>  >It has no effect on observable behavior.
|>
|>  Not as far as the standard is concerned, no, but as far as users
|>  are concerned the effect is easily observable, so if you put a
|>  statement like the above in the standard, then market forces will
|>  have no trouble enforcing it.

Like they enforce "inline" today?  As long as the "as if" rule is in
effect, statements like "implementations should not inline functions
..." are meaningless.  And without the "as if" rule, most serious
optimization is forbidden.  And I'm curious as to how a user can observe
the effect -- about the only way I can think of is disassembly, and I
don't see any strong market forces affecting what a disassembler will
show.  I suspect that if something like !inline were adopted, most
compilers would simply take it to mean: optimize for space rather than
speed.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Mark Zeren" <zeren@pobox.com>
Date: 1997/10/24
Raw View
How about the ability to override operator.()?

mjz
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:

|>  Valentin Bonnard <bonnardv@pratique.fr> writes:
|>
|>  >But the problem is with code which assume that, for any number i,
|>  >
|>  >    long l = i;
|>  >
|>  >is valid and will never overflow, which is incorrect if you add
|>  >a new type long long.
|>
|>  The assumption as stated above is not correct even in C89.  Consider
|>  for example `double i = 1.0e300;'.  The real issue is code that
|>  converts to `long' or `unsigned long' which is supposed to work for any
|>  _builtin integral type_ (rather than for any "number").

And that a certain number of types (like size_t) are guaranteed to be
built-in integral types.  (Note too that signedness also plays a role.
Long is only guaranteed to hold all builtin signed integral types, and
unsigned long all builtin unsigned integral types.  Thus, converting
size_t to unsigned long or ptrdiff_t to long are garanteed to work, but
size_t to long or ptrdiff_t to unsigned long aren't.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

|>  J. Kanze wrote:
|>  >
|>  > Jean-Louis Leroy <jll@skynet.be> writes:
|>  >
|>  > |>  when the Forth-83 standard came out, it comprised a mandatory part and
|>  > |>  an 'extension' part. An implemenation could choose not to implement the
|>  > |>  extended standard, but if it chose to, the 'words' (functions in Forth
|>  > |>  parlance) could behave only as ascribed by the standard.
|>  >
|>  > C and C++ also do this: compare hosted and non-hosted environments.
|>
|>  No one care because no one know that. When you see 'ANSI C conformant'
|>  on a compiler, it means hosted, not free-standing (the same where you
|>  see 'ANSI C++ conformant' ;-)

Not at all.  It depends on the target environment -- compilers for
embedded processors (often without an OS) are generally non-hosted.
Curiously enough, gcc is also non-hosted -- it depends on the libraries
of the target machine, its authors have no control over these, and
(correctly, IMHO) refuse to claim conformance for something they don't
control.

Of course, if a native compiler on a "normal" machine claimed
conformance, I would probably assume hosted, unless otherwise
specified.  But then, I suspect that with a Forth compiler in similar
circomstances, one would assume that the extensions were present.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

|>  It's only a hint to
|>  the compiler (unlike inline, which has extern static like
|>  semantics).

The inline keyword has no semantics -- an inline function must behave
exactly like a non-inline function, in every way, shape, form or
fashion.

In fact, the only meaning of the inline keyword in C++ is that the
function must be defined once in each translation unit which uses it,
rather than once and only once in the entire program.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/24
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  The
|>  key question is whether code like the following is still guaranteed to
|>  work:
|>
|>  void func(size_t s)
|>  {
|>   printf("size:%ul\n", (unsigned long)s);
|>  }
|>
|>  That code was guaranteed to work as intended by the C89 standard. Under
|>  the proposed C9x standard, that code would need to be modified to use
|>  the new features in the <inttypes.h> header file. Without such
|>  modifications, it may fail on any system that implements, for instance,
|>  64 bit pointers and 32 bit unsigned long's (it might still accidentally
|>  work for values that fit in 32 bits, depending upon the endianess).

The endianess plays no role -- the explicit conversion is well defined
in all cases.  In fact, the worst part of the change is that such code
probably will continue to work at first (and with the test suite data),
only to fail somewhere out in the field months, or even years, later.

|>  The
|>  same difficulty applies to any other integer-valued standard typedef.
|>  Automated searches for cases affected by this problem is very difficult,
|>  bordering on impossible, rendering conversion of large projects to C9x
|>  significantly more difficult than it would otherwise need to be.
|>  There is also a parsing problem, about which I know very little, caused
|>  by the fact that 'long long' is the only type whose recognition requires
|>  a count of duplicate tokens.

I find this a hack, too.  But since most of the support for long long is
coming from vendors, I presume that it isn't too difficult.  The reason
the vendors support it, of course, is that they implemented it without
thinking of the consequences, and now want to make it standard.  Sort of
like gets, in a way (although nowhere near as dangerous).

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/10/26
Raw View
Fergus Henderson wrote:
>
> kanze@gabi-soft.fr (J. Kanze) writes:
>
> >[...] most of the support for long long is coming from vendors [...]
> >The reason the vendors support it, of course, is that they implemented it
> >without thinking of the consequences, and now want to make it standard.
> >Sort of like gets, in a way (although nowhere near as dangerous).
>
> I think this is quite unfair to the vendors, who probably _did_
> consider the consequences quite seriously (see John Mashey's posts
> to comp.std.c).

If they had thought about it adequately, they should at least have named
it _longlong, rather than 'long long'. I would have preferred them to
call their 64 bit type 'long', but I can understand that they needed to
cater to a large body of non-conforming 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/26
Raw View
Mike Rubenstein <miker3@ix.netcom.com> writes:

> I don't see how C++ can avoid variable size arrays.  It seems certain
> that they will be adopted in the C9x standard.

[...]

> Unless C++ breaks away from the idea of trying to be compatible with
> C,

C++ now has many incompatibillities with C, and I think that's
best not to try to be compatible with C9x and to avoid the added
complexity.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/26
Raw View
Fergus Henderson <fjh@murlibobo.cs.mu.OZ.AU> writes:

> kanze@gabi-soft.fr (J. Kanze) writes:
>
> >As long as the "as if" rule is in
> >effect, statements like "implementations should not inline functions
> >..." are meaningless.
>
> Well, if you really want to be pedantic, then the standard need just
> make it clear that the "as if" rule doesn't apply in this case, e.g.
> by changing the wording to
>
>     "implementations should not inline functions declared as `!inline',
>     the ``as-if'' rule [cross-ref] notwithstanding."

I'd like to see a formal definition of inlining. It seems
very difficult to me. Or do you mean: generate un function
call to an extern function about which nothing can be
assumed (then you would need to define the notion of
function call, which is difficult if not impossible).

Also it means that you are able to recognise in the
disassembly which instruction does what. I completly breaks
everything.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jerry Leichter <leichter@smarts.com>
Date: 1997/10/22
Raw View
| >The problem described in c.s.c that programs may assume that no type
| >(size_t in particular) is greater than long;
|
| But in C++ this assumption has always been false in the general case,
| because you can use overloaded operators to define your own LongLong
| type....

C has also always allowed for types longer than long - a typedef to a
struct or an array can give you a type of arbitrary size.  But that's
not the point:  The guarantee in C - which C9X proposes to void - is
that long is *the longest integral type*.  Hence, any value of a
[signed, resp. unsigned] integral type may be safely cast to long
[resp., unsigned long] without loss of value.  (Alternatively, any
integral value may be cast to [unsigned] long and back without change.)

The story is no different from C++.  Sure, you can use overloaded
operators to define your own longlong, and even your own conversion
operators to make it look like casts work - but you can't define a new
built-in integral type.  There are still contexts in which your type
would differ from a built-in type - in the preference of built-in
conversions over user-defined conversions for overload resolution, for
one thing.

It's true that many of the most annoying problems that this change
causes in C are much less likely in C++.  For example, in C you are
today guaranteed that you can printf() any integral value with %ld
format.  No more.  However, C++ programs probably aren't using printf()
formatting much, and << can overload on "long long" or even a
user-defined longlong as easily as on long.

C++ programs that use C interfaces could run into subtle problems:  Many
things in C interfaces (for Posix, as one example) are defined in terms
of a size_t type.  Since size_t is defined to be *some* integral type,
it's currently safe to store a size_t in an unsigned long.  Not in the
proposed C9X!  This is every bit as much of an issue for C++ as for C.

       -- Jerry
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/22
Raw View
bs@research.att.com (Bjarne Stroustrup) writes:

|>  C and C++ are so closely associated (in reality and in the minds of many
|>  people) that what harms the one usually harms the other. I suspect that
|>  more coordination of their evolution is needed.

Starting with "complex"?  (I can understand the historical reasons why
C++ has a class, and C a built-in type.  But really, it would be nice if
they both were the same.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Hubert HOLIN <hh@ArtQuest.fr>
Date: 1997/10/22
Raw View
Valentin Bonnard wrote:

> Fergus Henderson wrote:
> >

[SNIP]

> > Why do you think `long long' would be a mistake, in the context of
> C++?
>
> The problem described in c.s.c that programs may assume that no type
> (size_t in particular) is greater than long; this is less a problem as
>
> people write function templates depending on the integer type
> (example:
> min/max).
>
> At least we don't have the printf dance.

[SNIP]

    "long long" does have legitimate uses which are not easily
reproducible by other means (I do a lot of integer-based image
processing, and their uniform existence would be a boon to my
algorithms, for instance).

    They also happen to be allowed by several compilers (gcc, Metrowerks
CodeWarrior,...), which leads one to believe their general adoption
should not be technically too difficult.

    As to the "c.s.c" argument, with which I am unfamiliar, the least I
can say is that it sounds strange. As presented, it seems based on the
fact that, as is frequently, and what we prefer to be,  the case, but is
explicitely not endorsed by the standard, sizeof(char) < sizeof(short) <
sizeof(long). What if the C compiler in question decides that
sizeof(that_compiler's_long) == sizeof(another_complier's_long_long)?

    What, I believe, this boils down to, is that one would really want
to have integer types, call them safe_char, safe_short,... so as not to
break existing code, such that sizeof(safe_char) < sizeof(safe_short) <
sizeof(safe_long) < sizeof(safe_long_long) < ... .

        Hubert Holin
        holin@mathp7.jussieu.fr
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "lg" <lg@mail.ndirect.co.uk>
Date: 1997/10/23
Raw View
M.T.Russell@ukc.ac.uk wrote in message <2767@stork.ukc.ac.uk>...
 >I'd like the syntax
 >
 > x.::whatever
 >
 >to be equivalent to
 >
 > {type of x}::whatever
 >
 >and similarly for x->::whatever.
 >
 >So you could write:
 >
 > for (a.::iterator pos = a.begin(); pos != a.end(); ++pos) {
 > // something
 > }
 >
 >I assume that .:: would not be hard for C++ parsers to cope with.  I think
 >this gets most of the benefit of typeof, while avoiding some of the
 >trickier issues.

This would be tasty syntactic sugar. But what sort of binding should there
be? Dynamic or static resolution of the class of the variable of "a"?
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/23
Raw View
Gabor Greif wrote:

> Disallowing inlining by !inline
>
> template <int I>
> struct bar
> {
>         !inline int foo(void) { return 1; }
> }
>
> This way the definition for the member can be kept in the header
> file, and one does not have to fiddle with .cpp implementation files
> and explicit instantiation of templates for bigger functions.

I don't understand this one. You have at the same time:
- a compile dependancy (the problem with inline)
- no space/time gain (the problem with non inline)

So you get the worst of both world !
Why would anyone want to do this ?

Also not your proposal has _no semantics_. It's only a hint to
the compiler (unlike inline, which has extern static like
semantics).

So there is definitly no point.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/23
Raw View
J. Kanze wrote:
>
> Jean-Louis Leroy <jll@skynet.be> writes:
>
> |>  when the Forth-83 standard came out, it comprised a mandatory part and
> |>  an 'extension' part. An implemenation could choose not to implement the
> |>  extended standard, but if it chose to, the 'words' (functions in Forth
> |>  parlance) could behave only as ascribed by the standard.
>
> C and C++ also do this: compare hosted and non-hosted environments.

No one care because no one know that. When you see 'ANSI C conformant'
on a compiler, it means hosted, not free-standing (the same where you
see 'ANSI C++ conformant' ;-)

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/23
Raw View
Hubert HOLIN wrote:

>     "long long" does have legitimate uses which are not easily
> reproducible by other means (I do a lot of integer-based image
> processing, and their uniform existence would be a boon to my
> algorithms, for instance).
>
>     They also happen to be allowed by several compilers (gcc, Metrowerks
> CodeWarrior,...), which leads one to believe their general adoption
> should not be technically too difficult.

They are completly trivial to implement; that's _not_ an implementation
problem.

>     As to the "c.s.c" argument, with which I am unfamiliar, the least I
> can say is that it sounds strange. As presented, it seems based on the
> fact that, as is frequently, and what we prefer to be,  the case, but is
> explicitely not endorsed by the standard, sizeof(char) < sizeof(short) <
> sizeof(long). What if the C compiler in question decides that
> sizeof(that_compiler's_long) == sizeof(another_complier's_long_long)?

sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)
<= sizeof (long long) (if you add long long)

But the problem is with code which assume that, for any number i,

    long l = i;

is valid and will never overflow, which is incorrect if you add
a new type long long.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1997/10/23
Raw View
Hubert HOLIN wrote:
>
> Valentin Bonnard wrote:
>
> > Fergus Henderson wrote:
> > >
>
> [SNIP]
>
> > > Why do you think `long long' would be a mistake, in the context of
> > C++?
> >
> > The problem described in c.s.c that programs may assume that no type
> > (size_t in particular) is greater than long; this is less a problem as
> >
> > people write function templates depending on the integer type
> > (example:
> > min/max).
> >
> > At least we don't have the printf dance.
...
>     As to the "c.s.c" argument, with which I am unfamiliar, the least I
> can say is that it sounds strange. As presented, it seems based on the
> fact that, as is frequently, and what we prefer to be,  the case, but is
> explicitely not endorsed by the standard, sizeof(char) < sizeof(short) <
> sizeof(long). What if the C compiler in question decides that
> sizeof(that_compiler's_long) == sizeof(another_complier's_long_long)?

The c.s.c argument does not depend upon that relationship; it does
depend upon sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long) which
I believe is guaranteed by the standard.

Setting sizeof(that_compiler's_long)==
sizeof(another_compiler's_long_long) is irrelevant to the argument. The
key question is whether code like the following is still guaranteed to
work:

void func(size_t s)
{
 printf("size:%ul\n", (unsigned long)s);
}

That code was guaranteed to work as intended by the C89 standard. Under
the proposed C9x standard, that code would need to be modified to use
the new features in the <inttypes.h> header file. Without such
modifications, it may fail on any system that implements, for instance,
64 bit pointers and 32 bit unsigned long's (it might still accidentally
work for values that fit in 32 bits, depending upon the endianess). The
same difficulty applies to any other integer-valued standard typedef.
Automated searches for cases affected by this problem is very difficult,
bordering on impossible, rendering conversion of large projects to C9x
significantly more difficult than it would otherwise need to be.
There is also a parsing problem, about which I know very little, caused
by the fact that 'long long' is the only type whose recognition requires
a count of duplicate tokens.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/23
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

>But the problem is with code which assume that, for any number i,
>
>    long l = i;
>
>is valid and will never overflow, which is incorrect if you add
>a new type long long.

The assumption as stated above is not correct even in C89.  Consider
for example `double i = 1.0e300;'.  The real issue is code that
converts to `long' or `unsigned long' which is supposed to work for any
_builtin integral type_ (rather than for any "number").

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/10/23
Raw View
J. Kanze wrote:
>
> bs@research.att.com (Bjarne Stroustrup) writes:
>
> |>  C and C++ are so closely associated (in reality and in the minds of many
> |>  people) that what harms the one usually harms the other. I suspect that
> |>  more coordination of their evolution is needed.
>
> Starting with "complex"?  (I can understand the historical reasons why
> C++ has a class, and C a built-in type.  But really, it would be nice if
> they both were the same.)

Maybe a solution would be to demand that for extern "C" functions,
complex<T> is stored as the equivalent C complex type, if this exists,
that is, the following should work:

C++ file:

extern "C" complex<double> f(complex<double>);

complex<double> void g()
{
  complex<double> c(1,2);
  return f(c);
}

C file:

typedef <C9X double complex type specifier> dblcomplex;

dblcomplex f(dblcomplex x)
{
  return x*x+5;
}
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/23
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>Except...  Given the way the standard defines a conforming
>implementation (one whose observable behavior is the same as one
>instantiation of the abstract machine), how could you ban inlining.

Simple: you add a statement to the language standard saying
"implementations should not inline functions declared as `!inline'."

>It has no effect on observable behavior.

Not as far as the standard is concerned, no, but as far as users
are concerned the effect is easily observable, so if you put a
statement like the above in the standard, then market forces will
have no trouble enforcing it.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/23
Raw View
"Gabor Greif" <gabor@datawatch.de> writes:

 |> On Mon, Oct 20, 1997 4:03 PM, Valentin Bonnard
 |> <mailto:bonnardv@pratique.fr> wrote:
 |> >> Similarly for calling member functions:
 |> >>         class_ancestry<0>::bar()
 |> >> would call the bar member of the first direct baseclass.
 |> >
 |> >But is there any practical use ?
 |> >
 |>
 |> I came across a situation where I needed exactly this feature
 |> to disambiguate member access involving MI classes passed
 |> as template parameters. I had to get around this by adding typedefs
 |> to every class that was meant to be passed to that template as a
 |> parameter.
 |>
 |> But here is a practical one:
 |>
 |> Disallowing inlining by !inline
 |>
 |> template <int I>
 |> struct bar
 |> {
 |>  !inline int foo(void) { return 1; }
 |> }
 |>
 |> This way the definition for the member can be kept in the header
 |> file, and one does not have to fiddle with .cpp implementation files
 |> and explicit instantiation of templates for bigger functions.
 |>
 |> No syntactic problems arise, since ! is not allowed where inline is
 |> allowed (in the anticipated standard).

Except...  Given the way the standard defines a conforming
implementation (one whose observable behavior is the same as one
instantiation of the abstract machine), how could you ban inlining.  It
has no effect on observable behavior.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <rylek@cslab.felk.cvut.cz>
Date: 1997/10/23
Raw View
> >For nested types, of course (STL).  So that you can write, say
> >
> >       typeof(a)::iterator a_iter = a.begin();
> >
> >instead of, say
> >
> >       map<some_big_type, some_other_type,
> complex_comparison>::iterator ...
>
> I'd like the syntax
>
>         x.::whatever
>
> to be equivalent to
>
>         {type of x}::whatever
>
> and similarly for x->::whatever.
>
> So you could write:
>
>         for (a.::iterator pos = a.begin(); pos != a.end(); ++pos) {
>                 // something
>         }

  Yes, I agree, but why not to use just:

    x.whatever

    x->whatever

    for(a.iterator pos = s.begin(); pos != a.end(); ++pos) {}

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/23
Raw View
lg wrote:
>
> M.T.Russell@ukc.ac.uk wrote in message <2767@stork.ukc.ac.uk>...

>  >I assume that .:: would not be hard for C++ parsers to cope with.  I think
>  >this gets most of the benefit of typeof, while avoiding some of the
>  >trickier issues.

I prefer typeof.

> This would be tasty syntactic sugar. But what sort of binding should there
> be? Dynamic or static resolution of the class of the variable of "a"?

This is a compile time thing. a is _not_ evaluated.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: herbs@cntc.com (Herb Sutter)
Date: 1997/10/23
Raw View
Jean-Louis Leroy <jll@skynet.be> wrote:
>when the Forth-83 standard came out, it comprised a mandatory part and
>an 'extension' part. [...] Wouldn't this approach make sense for C++?

I have experience working with de facto standards that have 'optional' parts
and 'levels' of conformance (naming no names). They're extremely painful to
use, and the only reason they were done that way was to provide as common an
API as possible to sit on top of existing incompatible systems... in other
words, they had little choice.

Even so, I can't recommend this approach at all. Not only is any code beyond
the 'mandatory' subset completely nonportable across vendor implementations,
but it's often nonportable across different releases of the same vendor's
implementation (even when the vendor is doing his best to be a good vendor).

---
Herb Sutter (herbs@cntc.com)

Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada   L5K 2N6
Tel 416-805-9088   Fax 905-822-3824
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: herbs@cntc.com (Herb Sutter)
Date: 1997/10/23
Raw View
kanze@gabi-soft.fr (J. Kanze) wrote:
>bs@research.att.com (Bjarne Stroustrup) writes:
>|>  C and C++ are so closely associated (in reality and in the minds of many
>|>  people) that what harms the one usually harms the other. I suspect that
>|>  more coordination of their evolution is needed.
>
>Starting with "complex"?  (I can understand the historical reasons why
>C++ has a class, and C a built-in type.  But really, it would be nice if
>they both were the same.)

Bjarne is right that more coordination is needed. Still, there has always been
some coordination, and each of WG14 and WG21 has shown some active interest in
what the other is doing. Several people are active members of both committees.

---
Herb Sutter (herbs@cntc.com)

Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada   L5K 2N6
Tel 416-805-9088   Fax 905-822-3824
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/24
Raw View
Gabor Greif wrote:
>
> Disallowing inlining by !inline
>
> template <int I>
> struct bar
> {
>         !inline int foo(void) { return 1; }
> }
>
> This way the definition for the member can be kept in the header
> file, and one does not have to fiddle with .cpp implementation files
> and explicit instantiation of templates for bigger functions.

There's no need for this. If you want to include the definition
in the header without inlining it, just include an out-of-line
definition in the header:

template <int I>
struct bar
{
 int foo();
};

template <int I> int bar<I>::foo() { return 1; }

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
Date: 1997/10/24
Raw View
Completely unrelated with the previous proposals...

I would really like to be able to do arrays of references.
I realize that those are not allowed on purpose (pbs with
array initialisation ?) but I hope that the problems to
overcome to have this feature are not unsolvable.

This is very useful when you want to precompute bunch of
constants (like big array constants) and want to be able
to use these constants in a loop in a non-trivial manner.

More generally speaking, I would like to see a much better
handling of arrays in C++ (why can't I initialize an member
which is an array in the initializer list).

General mathematical matrices and vectors and vectors would be
great too !!! But this is not stricly speaking a langage issue.

 Theo.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/24
Raw View
J. Kanze wrote:
>
> herbs@cntc.com (Herb Sutter) writes:
>
> |>  Bjarne is right that more coordination is needed. Still, there has
> |>  always been some coordination, and each of WG14 and WG21 has shown
> |>  some active interest in what the other is doing. Several people are
> |>  active members of both committees.
>
> There's actually a lot of coordination, although I'm a bit disappointed
> in the results with regards to inline.

Me too.

> In some ways, I think
> the "correct" solution would be to drop complex from the current C++
> standard, and pick up the C version next go around,

Don't do that ! Making C complex and C++ complex<> binary compatible
is enough.

Please don't remove from C++ what doesn't fit in C. The same for
inline: C must follow C++ (as far as it can with dumb linkers),
not the other way arround.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/20
Raw View
Fergus Henderson wrote:
>
> aGriffiths@ma.ccngroup.com (Alan Griffiths) writes:
>
> >Valentin Bonnard <bonnardv@pratique.fr> writes:
> >> and long long (this should be easy)
> >
> >No don't repeat that mistake!
>
> Why do you think `long long' would be a mistake, in the context of C++?

The problem described in c.s.c that programs may assume that no type
(size_t in particular) is greater than long; this is less a problem as
people write function templates depending on the integer type (example:
min/max).

At least we don't have the printf dance.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: skaller@zip.com.au (John (Max) Skaller)
Date: 1997/10/20
Raw View
On 20 Oct 97 09:20:59 GMT, Jean-Louis Leroy <jll@skynet.be> wrote:

>typeid() is a runtime facility, while typeof would extract the type of
>an expression at compile time, and allow you to use the resulting type
>just like you do of built-in types, user-defined types and typedefs.

Not just useful, MANDATORY. Without at least this facility,
it is impossible to implement even the most basic templates.

For example, it is not possible to implement a simple
iterator that simply delegates to another one without it --
without supplying the type manually, or using stupid
traits classes. A derived mechanism is:

 dcl x = expr;

where x is given the type of "expr", it can be done by

 typeof(expr) x = expr

which is extremely clumbsy (and doesn't properly
support "const" or references).

John Max Skaller                ph:61-2-96600850
mailto:skaller@zip.com.au       10/1 Toxteth Rd
http://www.zip.com.au/~skaller  Glebe 2037 NSW AUSTRALIA
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jbuck@synopsys.com (Joe Buck)
Date: 1997/10/21
Raw View
Jean-Louis Leroy <jll@skynet.be>:
>> And a typeof operator.

claus@faerber.muc.de writes:
>Isn't that typeid()? Or do you want to write sth. like:

    int     a;
    typeof(a) b;

> I can't see why:

For nested types, of course (STL).  So that you can write, say

 typeof(a)::iterator a_iter = a.begin();

instead of, say

 map<some_big_type, some_other_type, complex_comparison>::iterator ...

Similarly, if m is a map, typeof(m)::value_type is the map's value type,
always.  You can't mess it up.  And if you change map to the SGI STL
hash_map (another candidate for the next standards round) or a multimap,
your code doesn't change.

Yes, typedefs are also a possibility, but typeof would be simpler in many
cases and simplify changes (if a's type changes you must change any
associated typedefs to match).  And it promotes "write things once" coding
and more compact code in templates (no "typename" stuff since the parser
knows that typeof(x) is always a type and x is never a type).
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
 If you thought flashing ads on Web sites were annoying, wait till the Web
 and your operating system are "seamlessly integrated" and watch the
 pulsating promotional crud spill out over your desktop.  -- Scott Rosenburg
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jean-Louis Leroy <jll@skynet.be>
Date: 1997/10/21
Raw View
Steve,

when the Forth-83 standard came out, it comprised a mandatory part and
an 'extension' part. An implemenation could choose not to implement the
extended standard, but if it chose to, the 'words' (functions in Forth
parlance) could behave only as ascribed by the standard.

I felt that this was a good idea. Forth remained available - in a
standard, predictible form - on small computers, while programs written
to the extended standard were (supposedly <VBG>) portable to other
extended-standard implementations.

Wouldn't this approach make sense for C++? I said elsewhere that I'd
like coroutines to be part of the standard. I realize that they are
easily implemented on OSs that natively support them (NT4, for
example), but may be a nightmare to implement on some processors or
OSs. They would be perfect candidates for an extended standard ` la
Forth-83.

jl
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/21
Raw View
Ted Clancy wrote:
>
> And while we're talking about numbers, has anyone worked out a fix for
> the -32768 thing? That should be added.

I always just write signed(32768).

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: espie@ens.fr (Marc Espie)
Date: 1997/10/21
Raw View
In article <62dkd2$2ku$1@halcyon.com>, Tim Smith <tzs@halcyon.com> wrote:

>This one is completely off the wall, but why not allow spaces in identifiers?
>E.g.,

> int average speed = 10;
> int total distance = 100;
> int     trip time = total distance / average speed;

>Keywords would stay keywords, so
>
> int sizeof average speed = 4;
> int my int variable = 3;
>
>would be errors.  10 years ago, this would be an outrageous suggestion, but
>considering some of the other things the poor parser has been made to deal
>with, this change would be mild.

Do you really want that one ? I know I wouldn't. Technical points aside,
I believe you forgot to take the most important parser into account:
yourself.  I know that I already have trouble reading obscure code, and
I do believe that the underscore in int average_speed = 10; is a very
useful visual help: unobstrusive, aesthetical, and takes me half a second
less time to read that line. Multiply that by thousands of lines, conceive
more contrieved expressions, and you will soon find that being able to
delineate variables at a glance IS a life-save.

>Besides, it would give those who are tired of the religious wars over
>fooBar vs. foo_bar something new to argue about.
:-)
--
[nosave]<http://www.eleves.ens.fr:8080/home/espie/index.html>
microsoft network is EXPLICITLY forbidden to redistribute this message.
`Seiza no matataki kazoe, uranau koi no yuku e.'
 Marc Espie (Marc.Espie@ens.fr)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/21
Raw View
Christopher Eltschka wrote:
>
> Why y? I would prefer 0b11011111 (b like binary).
> I also could accept 0d11011111 (d like dual), although this could
> be irritating because of the %d printf format specifier meaning
> decimal. But "y" looks nothing like "binary" to me.

I wouldn't commit suicide if 0b were chosen. I suggested 0y
because b is a valid hex digit. Also, y is the last letter of
binary, just as x is the last letter of hex.

> Does every implementation have an escape character? (Does EBCDIC
> define an escape character?)

Does every implementation define a vertical tab, or an alert?
I'm not sure how such things are handled on machines that use
EBCDIC, or worse, on machines that cross-compile for EBCDIC. (Or
perhaps worst, EBCDIC machines that cross-compile for ASCII.)

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/21
Raw View
Jean-Louis Leroy wrote:
>
> Why has the STL changed my mind on this? Well, it trained me to think in terms
> of iterators. Iterators are, in general, more useful than the equivalent
> function. They implement a 'pull' model that is less retrictive than 'push'
> models.
>
> I'll give an example. Last year I needed to iterate over all the files in a set
> of directories that matched any of a set of patterns. Optionally, the search
> would recurse in subdirectories.
>
> Instead I wrote the loop/recurse version and turned it into an iterator by
> making the function a coroutine. As a result, the code is very intuitive:

[code snipped]

Nice idea. However, coroutines are simply a special case of
multi-threading, where one "thread" always enters and exits at
the same level so that it doesn't need a separate stack.
However, as soon as you allow a coroutine, someone's going to
want to do a "resume" while nested down a level in a subroutine.
This won't work unless the coroutine has its own stack, in which
case you've got 90% of what you need for cooperative
multi-threading, so you might as well add the other 10% (a ready
list) and be done with it.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/21
Raw View
Tim Smith wrote:
>
> This one is completely off the wall, but why not allow spaces in > identifiers?

Why not just extend the character set of identifiers to include
0x80..0xFF, and then use 0xA0, which displays as a blank but
isn't...

Naahhh...

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Esa Pulkkinen <esap@cs.tut.fi>
Date: 1997/10/21
Raw View
skaller@zip.com.au (John (Max) Skaller) writes:
> For example, it is not possible to implement a simple
> iterator that simply delegates to another one without it --
> without supplying the type manually, or using stupid
> traits classes. A derived mechanism is:
>
>  dcl x = expr;
>
> where x is given the type of "expr", it can be done by
>
>  typeof(expr) x = expr
>
> which is extremely clumbsy (and doesn't properly
> support "const" or references).

Hmm... Since you brought this issue up - how would the dcl syntax
support const and references? Consider this:

X &f();
const X &g();
const X h();
X i()

dcl a = f(); // a is "X&" or "X"?
dcl b = g(); // b is "const X&",  "const X" or "X"?
dcl c = h(); // c is "const X" or "X" (perhaps also references?)?
dcl d = i(); // d is "X"? (could also be "const X&" perhaps)
dcl e = T::x; // what if x is a type?
dcl myF1 = h;    // myF is "X&(*)()". Potentially dangerous, could also
                 // be missing '()'. Is it possible not to catch this
                 // error when using myF1? what if h() returned a
                 // function object?
dcl a = 10, b = f; // allowed? a is an int, b is "X&(*)()"?

Now I would assume this dcl syntax would always use non-cv-qualified
non-reference version of the type, i.e. always copy the object.  I would
also assume same for the typeof() construct. This is because that would
cause least surprise for the users (or would it? Really, I don't know).
Consider an innocent example:

vector<int> myVector;
dcl myValue = myVector[10];
if (myValue != 10)
  myValue = 10; // Now how did the programmer mean to change myVector,
                // or change a copy of the 11th item stored in myValue?

vector<bool> myBoolVector;
dcl myValue2 = myBoolVector[2]; // Hmm.. myValue2 isn't bool for sure.
                               // myValue2 is a proxy object referencing
                               // myBoolVector.
myValue2 = true; // still modifies myBoolVector?

If I were reading the above code, I would assume both myValue and
myValue2 are separate variables not referencing myVector or
myBoolVector, i.e.of non-reference type. But because of the proxy object
needed to implement vector<bool>, this isn't possible (or is it?). Also
that interpretation would cause problems if you really wanted myValue to
be the reference type - how would you do that if dcl automatically
deduced to a non-reference type? (You need additional syntax to deduce
to an reference type then. Same for const.)

OTOH, consider the alternative: if myValue would be interpreted as a
reference to the vector, then there is a problem: you need something
like: "dcl x = make_copy(myVector[10])" to make a copy of the value,
with make_copy defined as:

template <class T>
T make_copy(const T& x) { return x; }

But still, this doesn't solve the problem with vector<bool>, instead,
make_copy would have to be specialized for the proxy class to make
it work properly.

As a conclusion, I also think something similar to typeof/dcl is needed,
but there is a huge range of possibilities to explore and the details
must be resolved before anything like this should be adopted.
--
   Esa Pulkkinen                        | C++ programmers do it virtually
   E-Mail:  esap@cs.tut.fi              | everywhere with class, resulting
   WWW   :  http://www.cs.tut.fi/~esap/ | in multiple inheritance.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/21
Raw View
Jean-Louis Leroy <jll@skynet.be> writes:

 |> > > Coroutines.
 |> >
 |> >  I think these should better be supported by some library... We dont
 |> > need them in C++ language constructs...
 |>
 |> I've implemented coroutines several times in my 12 years of programming.
 |> In Forth, in C and twice in C++. Always managed to get them to work.
 |> Never in a portable way, of course ;o)
 |>
 |> I would say that the real issue then is, how useful are they? Before
 |> the advent of the STL, I wouldn't have though they were so useful that
 |> they should be part of the language.
 |>
 |> Why has the STL changed my mind on this? Well, it trained me to think
 |> in terms of iterators. Iterators are, in general, more useful than the
 |> equivalent function. They implement a 'pull' model that is less
 |> retrictive than 'push' models.

I agree with the utility of iterators.  But as your example showed,
co-routines are still useful for implementing them.  (Iterators do
encapsulate a manually maintained stack well, of course.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bs@research.att.com (Bjarne Stroustrup)
Date: 1997/10/21
Raw View
miker3@ix.netcom.com (Mike Rubenstein) writes

 > I don't see how C++ can avoid variable size arrays.  It seems certain
 > that they will be adopted in the C9x standard.  I'll be surprised if
 > you will be able to find a single C++ compiler that doesn't offer
 > variable size arrays as an extension when the next C++ standardization
 > effort is undertaken.
 >
 > Unless C++ breaks away from the idea of trying to be compatible with
 > C, the argument that not allowing variable size arrays would introduce
 > a gratuitous incompatibility with C will be compelling.



Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/21
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

>Fergus Henderson wrote:
>>
>> aGriffiths@ma.ccngroup.com (Alan Griffiths) writes:
>>
>> >Valentin Bonnard <bonnardv@pratique.fr> writes:
>> >> and long long (this should be easy)
>> >
>> >No don't repeat that mistake!
>>
>> Why do you think `long long' would be a mistake, in the context of C++?
>
>The problem described in c.s.c that programs may assume that no type
>(size_t in particular) is greater than long;

But in C++ this assumption has always been false in the general case,
because you can use overloaded operators to define your own LongLong type.

It might be reasonable to campaign for a requirement that size_t
be no longer than `long', but saying that we shouldn't have `long long'
at all seems to me to be an over-reaction.  Certainly if C has it,
then the arguments for putting it in C++ will be overwhelming.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/10/22
Raw View
On 21 Oct 97 11:24:12 GMT, Jean-Louis Leroy <jll@skynet.be> wrote:

>when the Forth-83 standard came out, it comprised a mandatory part and
>an 'extension' part. An implemenation could choose not to implement the
>extended standard, but if it chose to, the 'words' (functions in Forth
>parlance) could behave only as ascribed by the standard. ...
>
>Wouldn't this approach make sense for C++?

A related example would be the "level 0" and "level 1" compliance
options of ISO Pascal.

In the earliest meetings of the C++ Committee we discussed these
possibilities and concluded that we wanted exactly one definition for
the language. Thus, we deliberately defined no "optional" features or
"levels of compliance" (except for a "freestanding" implementation).

As it happens, we have today the sort of situation you advocate, as an
artifact of the standards process. Due to the moving-target nature of
the draft standard, newer features could be thought of as optional, in
a pragmatic sense. All compilers support the traditional C++ language
features, but newer features are supported by only some compilers. I
don't know of anyone who likes this situation, yet allowing optional
language features would only perpetuate it. No two compilers would
ever support exactly the same feature set.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: M.T.Russell@ukc.ac.uk
Date: 1997/10/22
Raw View
In article <62ge0g$3k5@hermes.synopsys.com> jbuck@synopsys.com (Joe Buck) writes:
>For nested types, of course (STL).  So that you can write, say
>
> typeof(a)::iterator a_iter = a.begin();
>
>instead of, say
>
> map<some_big_type, some_other_type, complex_comparison>::iterator ...

I'd like the syntax

 x.::whatever

to be equivalent to

 {type of x}::whatever

and similarly for x->::whatever.

So you could write:

 for (a.::iterator pos = a.begin(); pos != a.end(); ++pos) {
  // something
 }

I assume that .:: would not be hard for C++ parsers to cope with.  I think
this gets most of the benefit of typeof, while avoiding some of the
trickier issues.

Mark Russell
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/10/22
Raw View
Esa Pulkkinen wrote:
>
> skaller@zip.com.au (John (Max) Skaller) writes:
> > For example, it is not possible to implement a simple
> > iterator that simply delegates to another one without it --
> > without supplying the type manually, or using stupid
> > traits classes. A derived mechanism is:
> >
> >       dcl x = expr;
> >
> > where x is given the type of "expr", it can be done by
> >
> >       typeof(expr) x = expr
> >
> > which is extremely clumbsy (and doesn't properly
> > support "const" or references).
>
> Hmm... Since you brought this issue up - how would the dcl syntax
> support const and references? Consider this:
>
[... examples snipped ...]
>
> Now I would assume this dcl syntax would always use non-cv-qualified
> non-reference version of the type, i.e. always copy the object.  I would
> also assume same for the typeof() construct. This is because that would
> cause least surprise for the users (or would it? Really, I don't know).

Well I would expect for typeof, that given the following templates:

template<typename T> void f(T t);
template<typename T> void g(T& t);

the following two lines are completely equivalent:

f(expr); g(expr);
f<typeof(expr)>(expr); g<typeof(expr)>(expr);

Everything else would be surprising.
Note that this completely determines the result of typeof.

Now the rules for template argument type induction are already in the
(draft)
standard, so adding typeof to it should be relatively easy: Just refer
to
the template type induction rules.

[...]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Gabor Greif" <gabor@datawatch.de>
Date: 1997/10/22
Raw View
On Mon, Oct 20, 1997 4:03 PM, Valentin Bonnard
<mailto:bonnardv@pratique.fr> wrote:
>> Similarly for calling member functions:
>>         class_ancestry<0>::bar()
>> would call the bar member of the first direct baseclass.
>
>But is there any practical use ?
>

I came across a situation where I needed exactly this feature
to disambiguate member access involving MI classes passed
as template parameters. I had to get around this by adding typedefs
to every class that was meant to be passed to that template as a
parameter.

But here is a practical one:

Disallowing inlining by !inline

template <int I>
struct bar
{
 !inline int foo(void) { return 1; }
}

This way the definition for the member can be kept in the header
file, and one does not have to fiddle with .cpp implementation files
and explicit instantiation of templates for bigger functions.

No syntactic problems arise, since ! is not allowed where inline is
allowed (in the anticipated standard).

 Gabor
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/10/22
Raw View
Paul D. DeRocco wrote:
>
> Tim Smith wrote:
> >
> > This one is completely off the wall, but why not allow spaces in
> > identifiers?
>
> Why not just extend the character set of identifiers to include
> 0x80..0xFF, and then use 0xA0, which displays as a blank but
> isn't...
>
> Naahhh...

Maybe because it doesn't display as a blank on all systems?
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/22
Raw View
Jean-Louis Leroy <jll@skynet.be> writes:

|>  when the Forth-83 standard came out, it comprised a mandatory part and
|>  an 'extension' part. An implemenation could choose not to implement the
|>  extended standard, but if it chose to, the 'words' (functions in Forth
|>  parlance) could behave only as ascribed by the standard.

C and C++ also do this: compare hosted and non-hosted environments.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jean-Louis Leroy <jll@skynet.be>
Date: 1997/10/17
Raw View
> Now that the standard is basically a done deal,
> have there been any suggestions on how C++
> should evolve in the future and what things
> should be added to any future standard C++?

> 4....

Coroutines. And a typeof operator.

Jean-Louis Leroy
http://ourworld.compuserve.com/homepages/jl_leroy
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/17
Raw View
P Murray wrote:
>
> Now that the standard is basically a done deal,
> have there been any suggestions on how C++
> should evolve in the future and what things
> should be added to any future standard C++?

I'd be curious to see what people suggested to the committee,
before public comment period ended. As far as I know, all public
comment went into a black hole, where it will presumably be
carefully considered, but it would have been nice had all this
input been posted publicly.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/18
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

>Please don't put variable size arrays:
>
>int i;
>char p[i];
>
>nor other things like that.

Why not?

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/18
Raw View
Zalman Stern wrote:
>
> P Murray (pcm@vus002.telstra.com.au) wrote:
> : Now that the standard is basically a done deal,
> : have there been any suggestions on how C++
> : should evolve in the future and what things
> : should be added to any future standard C++?
>
> Full support of relevant items from C9X. E.g. the restrict keyword, etc.

and long long (this should be easy)

Please don't put variable size arrays:

int i;
char p[i];

nor other things like that.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <rylek@cslab.felk.cvut.cz>
Date: 1997/10/18
Raw View
Jean-Louis Leroy wrote:

> Coroutines.

 I think these should better be supported by some library... We dont
need them in C++ language constructs...

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/18
Raw View
Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> writes:

> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> >Please don't put variable size arrays:
> >
> >int i;
> >char p[i];
> >
> >nor other things like that.
>
> Why not?

They complicate a language which is already too complicated
(the rules for sizeof are strange with variable size arrays),
and that's useless as we have vector which does the thing
better (especially when we want to discourage the use of
built-in arrays).

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: miker3@ix.netcom.com (Mike Rubenstein)
Date: 1997/10/18
Raw View
Mirek Fidler <rylek@cslab.felk.cvut.cz> wrote:

> Fergus Henderson wrote:
>
> > Valentin Bonnard <bonnardv@pratique.fr> writes:
> >
> > >Please don't put variable size arrays:
> > >
> > >int i;
> > >char p[i];
> > >
> > >nor other things like that.
> >
> > Why not?
>
>    Because we still need run-time performance of C. If you need variable
> size array, use templates. But dont suggest to remove C pointer system
> from C++ (which variable size array would lead to).

I don't see how C++ can avoid variable size arrays.  It seems certain
that they will be adopted in the C9x standard.  I'll be surprised if
you will be able to find a single C++ compiler that doesn't offer
variable size arrays as an extension when the next C++ standardization
effort is undertaken.

Unless C++ breaks away from the idea of trying to be compatible with
C, the argument that not allowing variable size arrays would introduce
a gratuitous incompatibility with C will be compelling.


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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Mirek Fidler <rylek@cslab.felk.cvut.cz>
Date: 1997/10/18
Raw View
Fergus Henderson wrote:

> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> >Please don't put variable size arrays:
> >
> >int i;
> >char p[i];
> >
> >nor other things like that.
>
> Why not?

   Because we still need run-time performance of C. If you need variable
size array, use templates. But dont suggest to remove C pointer system
from C++ (which variable size array would lead to).

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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/18
Raw View
Mirek Fidler <rylek@cslab.felk.cvut.cz> writes:

>Fergus Henderson wrote:
>
>> Valentin Bonnard <bonnardv@pratique.fr> writes:
>>
>> >Please don't put variable size arrays:
>> >
>> >int i;
>> >char p[i];
>> >
>> >nor other things like that.
>>
>> Why not?
>
>   Because we still need run-time performance of C.

But performance is one reason very much in favour of adding
variable-size arrays: they can give much better performance than
user-defined array classes or even standard library array classes such
as `vector'.  Variable-size arrays can be allocated on the stack,
often with a single register add instruction, whereas an array
template must allocate storage on the heap, which is much more
expensive.

>If you need variable
>size array, use templates. But dont suggest to remove C pointer system
>from C++ (which variable size array would lead to).

No, variable size arrays don't change the C pointer system.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/19
Raw View
P Murray wrote:
>
> Now that the standard is basically a done deal,
> have there been any suggestions on how C++
> should evolve in the future and what things
> should be added to any future standard C++?

Some embarassingly simple suggestions for the lexer:

Allow binary numbers to be written with a 0y prefix. A bit mask
like 0y11011111 is much clearer than 0xDF.

Allow embedded underscores in numbers, which are ignored.
1_000_000_000 is much clearer than 1000000000, and
0y1110_0001_1111_1111 is much clearer than 0y1110000111111111.

Allow /e to refer to escape in character and string literals,
since it is such a common control character.

--

Ciao,
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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Ted Clancy <s341282@student.uq.edu.au>
Date: 1997/10/20
Raw View
Paul D. DeRocco wrote:
>
> P Murray wrote:
> >
> > Now that the standard is basically a done deal,
> > have there been any suggestions on how C++
> > should evolve in the future and what things
> > should be added to any future standard C++?
>
> Some embarassingly simple suggestions for the lexer:
>
> Allow binary numbers to be written with a 0y prefix. A bit mask
> like 0y11011111 is much clearer than 0xDF.
>
> Allow embedded underscores in numbers, which are ignored.
> 1_000_000_000 is much clearer than 1000000000, and
> 0y1110_0001_1111_1111 is much clearer than 0y1110000111111111.

And while we're talking about numbers, has anyone worked out a fix for
the -32768 thing? That should be added.

And (dare I mention it again) how about a null keyword?

--
Visit the USS-Unique! http://student.uq.edu.au/~s341282/UQ-Trek/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: tzs@halcyon.com (Tim Smith)
Date: 1997/10/20
Raw View
P Murray <pcm@vus002.telstra.com.au> wrote:
>Now that the standard is basically a done deal,
>have there been any suggestions on how C++
>should evolve in the future and what things
>should be added to any future standard C++?

This one is completely off the wall, but why not allow spaces in identifiers?
E.g.,

 int average speed = 10;
 int total distance = 100;
 int     trip time = total distance / average speed;

Keywords would stay keywords, so

 int sizeof average speed = 4;
 int my int variable = 3;

would be errors.  10 years ago, this would be an outrageous suggestion, but
considering some of the other things the poor parser has been made to deal
with, this change would be mild.

Besides, it would give those who are tired of the religious wars over
fooBar vs. foo_bar something new to argue about.

--Tim Smith
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: claus@faerber.muc.de (=?ISO-8859-1?Q?Claus_Andr=E9_F=E4rber?=)
Date: 1997/10/20
Raw View
Jean-Louis Leroy <jll@skynet.be> schrieb:
> > Now that the standard is basically a done deal,
> > have there been any suggestions on how C++
> > should evolve in the future and what things
> > should be added to any future standard C++?
>
> > 4....
>
> Coroutines.

What are coroutines?

> And a typeof operator.

Isn't that typeid()? Or do you want to write sth. like:

    int     a;
    typeof(a) b;

I can't see why: In the example above, you know the type. In templates, =20
you do have the type as a parameter:

    template <class T> void swap( T& a, T& b )
    {   T c =3D a;
        a =3D b;
        b =3D c;
    }

The only place where they would be useful would be in macros, but imo. =20
macros should only be used for adaption of compiler differences, and in =20
cases you'd need the type of a parameter a template would probably be =20
the better solution.

--=20
Claus Andr=E9 F=E4rber <http://www.muc.de/~cfaerber/> Fax: +49-8061-3361
PGP: ID=3D1024/527CADCD FP=3D12 20 49 F3 E1 04 9E 9E 25 56 69 A5 C6 A0 C9=
 DC
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jean-Louis Leroy <jll@skynet.be>
Date: 1997/10/20
Raw View
> > Coroutines.
>
>  I think these should better be supported by some library... We dont
> need them in C++ language constructs...

I've implemented coroutines several times in my 12 years of programming. In
Forth, in C and twice in C++. Always managed to get them to work. Never in a
portable way, of course ;o)

I would say that the real issue then is, how useful are they? Before the advent
of the STL, I wouldn't have though they were so useful that they should be part
of the language.

Why has the STL changed my mind on this? Well, it trained me to think in terms
of iterators. Iterators are, in general, more useful than the equivalent
function. They implement a 'pull' model that is less retrictive than 'push'
models.

I'll give an example. Last year I needed to iterate over all the files in a set
of directories that matched any of a set of patterns. Optionally, the search
would recurse in subdirectories.

Now it's very easy to write a function that performs some action on each file
using loops and recursion. You can even make it somewhat flexible and reusable
by encapsuling the actions to perform in a functor:

scanfiles(directories, patterns, recurse)
    for each directory in directories
        for each file in directory
            for each pattern in patterns
                if match(file, pattern)
                    action();
        if recurse
            for each directory in directories
                scanfiles(directories, patterns, recurse)

It turned out that this option wasn't viable. The file scanner was part of a
multifile search-and-replace for Microsoft's IDE. I needed to give back control
to the IDE after each file.

I knew that one can turn any algorithm into a non-recursive one by using stacks
of states, of course. I considered the kind of code this approach would lead me
to write. It would not be simple to write, to read nor debug, nor would it be
maintainable.

Instead I wrote the loop/recurse version and turned it into an iterator by
making the function a coroutine. As a result, the code is very intuitive:

coroutine scanfiles(directories, patterns, recurse, iterator)
    {
    for each directory in directories
        for each file in directory
            for each pattern in patterns
                if match(file, pattern)
                    iterator->file = file
                    resume iterator;
        if recurse
            for each directory in directories
                scanfiles(directories, patterns, recurse, iterator)
    iterator->more = false
    }

scanfile_iter : input_iterator
    {
    scanfile_iter(directories, patterns, recurse)
        more = true
        scanner = start(scanfiles, directories, patterns, recurse, this)
        resume scanner

    scanfile_iter()
        more = false

    operator ++
        resume scanner

    string operator *()
        return file

    friend bool operator ==(iter1, iter2)
        return iter1.more == iter2.more

    bool more;
    string file;
    coroutine scanner;
    };

iterators are a very flexible way of organizing data access. They're easy to
write for collections residing in memory. But soon you want to use the approach
for more complex sequences. In that case the easiest route is often to write a
function that enumerates the elements, then turn it into a coroutine.

The file scanner example is not an exception BTW. At least not for me. Since
then I have encountered that kind of problem several times. I indulged in
inferior solutions (like copy elements to a vector) because the app needed to
run on both NT and Unix. If coroutines had been there and standard and ready to
use, of course...

jl
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/10/20
Raw View
Paul D. DeRocco wrote:
>
> P Murray wrote:
> >
> > Now that the standard is basically a done deal,
> > have there been any suggestions on how C++
> > should evolve in the future and what things
> > should be added to any future standard C++?
>
> Some embarassingly simple suggestions for the lexer:
>
> Allow binary numbers to be written with a 0y prefix. A bit mask
> like 0y11011111 is much clearer than 0xDF.
>

Why y? I would prefer 0b11011111 (b like binary).
I also could accept 0d11011111 (d like dual), although this could
be irritating because of the %d printf format specifier meaning
decimal. But "y" looks nothing like "binary" to me.
BTW, even better would be s.th. similar to the GNU Pascal
(and I think also Extended Pascal standard) arbitrary basis numbers
(where arbitrary means up to 36). That is, if you write f.ex.
8#555, it's C-style 0555. 16#affe is C-style 0xaffe, and
36#z1 means "z1" in basis 36, that is 35*36+1=1261.

In C++ you could not use # for this (preprocessor!), but you could
f.ex. use $ for it (this would not interfere with the use of $ in
identifiers by some compilers, as numbers still begin with a digit,
and so $ in numbers shouldn't be more of a problem than f.ex. x in
numbers).

> Allow embedded underscores in numbers, which are ignored.
> 1_000_000_000 is much clearer than 1000000000, and
> 0y1110_0001_1111_1111 is much clearer than 0y1110000111111111.
>

That would indeed be nice.

> Allow /e to refer to escape in character and string literals,
> since it is such a common control character.

Does every implementation have an escape character? (Does EBCDIC
define an escape character?)
I guess escape is a special ASCII character, and therefore not
suitable for standardisation.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: aGriffiths@ma.ccngroup.com (Alan Griffiths)
Date: 1997/10/20
Raw View
In article: <3447ABB6.1C33@pratique.fr>  Valentin Bonnard <bonnardv@pratique.fr> writes:
> and long long (this should be easy)

No don't repeat that mistake!

__
Alan Griffiths              | Senior Systems Consultant, Experian (Formerly CCN)
alan.griffiths@experian.com (agriffiths@ma.ccngroup.com, Tel. +44 115 934 4517)
(ACCU C++ SIG organiser     | <http://www.accu.org/> alan@octopull.demon.co.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Gabor Greif" <gabor@datawatch.de>
Date: 1997/10/20
Raw View
On Sun, Oct 19, 1997 11:06 AM, Paul D. DeRocco
<mailto:pderocco@ix.netcom.com> wrote:
>P Murray wrote:
>>
>> Now that the standard is basically a done deal,
>> have there been any suggestions on how C++
>> should evolve in the future and what things
>> should be added to any future standard C++?
>
>

What about a new kind of scoping construct:

// class_ancestry<int> selects the (zero based) direct baseclass
// class_ancestry<typename> selects the first baseclass that is a (subclass
of) typename
// class_ancestry<(typename,n)> selects the nth baseclass
       that is a (subclass of) typename
// class_ancestry<0,0>  access to nested baseclasses

// this would be handy in template classes, where the names of the
// baseclasses are sometimes not known

struct A { int a; };

struct B { int b; };

struct C : A,B { int c; };

struct D : C,A { int d; };

void foo(void)
{
 D bar;
 bar.class_ancestry<0>::a = 1; // sets D::C::A::a
 bar.class_ancestry<1>::a = 2; // sets D::A::a
 bar.class_ancestry<0,B>::b = 2; // sets D::C::B::b
 bar.class_ancestry<(A,1)>::a = 2; // sets D::A::a
}

Similarly for calling member functions:
 class_ancestry<0>::bar()
would call the bar member of the first direct baseclass.

 Just wondering,

 Gabor
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/10/20
Raw View
zalman@netcom.com (Zalman Stern) writes:

|>  P Murray (pcm@vus002.telstra.com.au) wrote:
|>  : Now that the standard is basically a done deal,
|>  : have there been any suggestions on how C++
|>  : should evolve in the future and what things
|>  : should be added to any future standard C++?
|>
|>  Full support of relevant items from C9X. E.g. the restrict keyword, etc.

This seems obvious.

My favorite, although I'm not sure on all of the details, is a builtin
class __local_context.  Type derived from this class can only be
declared auto; the "class" itself makes all of the local variables
(incuding arguments) visible as protected members.  An example of use:

    struct IntegrateVisitor
    {
        virtual double operator()( double x ) = 0 ;
    } ;

    extern double integrate( IntegrateVisitor const& v ) ;

    double
    f( double a , double b )
    {
        struct Visitor : public IntegrateVisitor , public __local_context
        {
            virtual double operator()( double x )
            {
                return a * x + b ;
            }
        } ;
        return integrate( Visitor() ) ;
    }

or:

    void
    f()
    {
        char*   p = new char[ 10 ] ;
        struct Cleanup : public __local_context
        {
            ~Cleanup() { delete [] p ; }
        }       c ;
        // ...
    }

I'd actually like some sort of special syntax to simplify these two
cases.  The second would be easy:

    void
    f()
    {
        char*   p = new char[ 10 ] ;
        cleanup { delete [] p ; }
        //  ...
    }

Keyword cleanup introduces an unnamed instance of an unnamed class
derived from __local_context; the given code is its destructor.

I'm not too sure what is needed for the first: maybe:

    return integrate(
        lambda double : IntegrateVisitor ( double x )
        {
            return a * x + b ;
        } ) ;

In this case, "lambda <type> [ : classname [ , classname ]...] (
optparamlist ) { code } " introduces a temporary object of an unnamed
class derived from __local_context and the list of classes, with a
single function operator() returning type, taking the paramlist as args,
and having the given code.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/10/20
Raw View
On 17 Oct 97 03:09:17 GMT, "Paul D. DeRocco" <pderocco@ix.netcom.com>
wrote:

>I'd be curious to see what people suggested to the committee,
>before public comment period ended. As far as I know, all public
>comment went into a black hole, where it will presumably be
>carefully considered, but it would have been nice had all this
>input been posted publicly.

The comments that are submitted in accordance with NCITS (formerly X3)
procedures don't go into a black hole. Each comment is logged by NCITS
and by the Committee, discussed and voted on, and a reply is sent to
the submitter and to NCITS. The answers to the comments on CD2 have
not yet been prepared, but should be sent out by the end of the year.

There isn't any procedure for posting the comments and answers, and
internal committee documents are not supposed to be posted. (I realize
that some committees do post internal documents publicly, but
according to our understanding of NCITS rules, that isn't allowed.)

It might be possible to get a copy of the CD1 comments and replies (it
runs over 100 pages) from NCITS. You could check their web page
<http://www.ncits.org/> for contact information.

Few comments are suggestions for enhancements or additions, and most
of those were for things the Committee had previously discussed and
rejected. The Committee does keep lists of proposals which have
potential merit but which could not be adopted due to timing. After
the standard is published, the Committee will continue to meet to deal
with defect reports and requests for clarification, and can also take
the time to investigate proposals that would apply to the next round
of standardization.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/10/20
Raw View
On 20 Oct 97 03:15:50 GMT, tzs@halcyon.com (Tim Smith) wrote:

>This one is completely off the wall, but why not allow spaces in identifiers? ...

It would make error detection, reporting, and recovery much less
reliable. (Meaning you would have even less chance of getting a
helpful error message when you make a mistake.)

It would also allow more typographical errors to result in valid
programs, or in misleading error messages.

FORTRAN used to allow blanks (because of 1950's era unreliable input
devices), but now does not. There are good reasons for the change.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jean-Louis Leroy <jll@skynet.be>
Date: 1997/10/20
Raw View
> What are coroutines?

A coroutine is like a function that can be suspended and later resumed,
while conserving its context (local variables etc). They're pretty much
like threads where context switch would be explicit. Like it was in
16-bit Windows.

Many problems require a form of parallel processing without needing the
illusion of true concurrent execution that threads provide. When
working with coroutines, you don't need to worry about serializing
access to data structures, deadlocks and the like.

For an example of the kind of problems coroutines nicely solve, see my
file scanner example elsewhere in this thread.

> > And a typeof operator.
>
> Isn't that typeid()? Or do you want to write sth. like:
>     int     a;
>     typeof(a) b;

typeid() is a runtime facility, while typeof would extract the type of
an expression at compile time, and allow you to use the resulting type
just like you do of built-in types, user-defined types and typedefs. It
would be useful in arithmetic-oriented components. For example, you
would expect a matrix<T> class to know about standard conversions and
promotions, so that adding a matrix<int> and a matrix<double> would
yield a matrix<double>. If typeof were available, you could write:

template<class T1, class T2>
matrix< typeof(T1() + T2())> operator +(matrix<T1> m1, matrix<T2> m2)
    {
    typeof(T1() + T2())* result_iter;
    // or:
    typedef typeof(T1() + T2()) result_type;
    result_type* result_iter;
    }

Currently, you must write traits classes to achieve this effect. Doing
it with a two-argument trait class is easy, but causes maintenance
problem (registering a new type requires 2N-1 specializations, where N
is the number of previously registered types). It's possible to make it
work with a one-argument traits class but this requires partial
specialization and a good deal of not-so-obvious template
metaprogramming.

Like coroutines, this feature is useful. Unlike coroutines, though, it
is also cheap (I think).

Jean-Louis Leroy
http://ourworld.compuserve.com/homepages/jl_leroy
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/10/20
Raw View
aGriffiths@ma.ccngroup.com (Alan Griffiths) writes:

>Valentin Bonnard <bonnardv@pratique.fr> writes:
>> and long long (this should be easy)
>
>No don't repeat that mistake!

Why do you think `long long' would be a mistake, in the context of C++?

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/20
Raw View
Gabor Greif wrote:
> What about a new kind of scoping construct:

[...]

> void foo(void)
> {
>         D       bar;
>         bar.class_ancestry<0>::a = 1;   // sets D::C::A::a
>         bar.class_ancestry<1>::a = 2;   // sets D::A::a
>         bar.class_ancestry<0,B>::b = 2; // sets D::C::B::b
>         bar.class_ancestry<(A,1)>::a = 2;       // sets D::A::a
> }
>
> Similarly for calling member functions:
>         class_ancestry<0>::bar()
> would call the bar member of the first direct baseclass.

But is there any practical use ?

Remember, we don't put things in C++, not even in C+=2000
unless there is a need for it. Otherwise, we could imagine
hundreds of changes which would complicate the language
and compilers.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: pcm@vus002.telstra.com.au (P Murray)
Date: 1997/10/16
Raw View
Now that the standard is basically a done deal,
have there been any suggestions on how C++
should evolve in the future and what things
should be added to any future standard C++?

A few things I can think of...

1. Compiler support for *optional* use of Garbage Collection
with a choice of garbage collection algorithms.  If the compiler
knows about GC then I'm sure it can be made more efficient
although I certainly wouldn't want to be forced to use it
if I didn't want to.

2. Some sort of Parrallel support.

3. Compiler suport for differing language levels or standards
(e.g.full Standard C++, Lightweight (realtime?) Standard C++,
Parrallel Standard C++, etc...).  Or is this a vendor specific
implementation issue?

4....

Thanks,
- Peter.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: zalman@netcom.com (Zalman Stern)
Date: 1997/10/17
Raw View
P Murray (pcm@vus002.telstra.com.au) wrote:
: Now that the standard is basically a done deal,
: have there been any suggestions on how C++
: should evolve in the future and what things
: should be added to any future standard C++?

Full support of relevant items from C9X. E.g. the restrict keyword, etc.

-Z-
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]