Pointer to member: is this legal C++ code?

  • Permalink
  • submit to reddit
  • Email
  • Follow


I am attempting to use pointers to members to build a "map" (not in the STL
sense) of a structure. I want to use this map to serialize the structure
automatically.

The tricky bit is that I don't want to repeat the serialisation code on each
struct I want to serialize, since there are quite a few of these (about 480)
and the result is likely to contain errors. Instead I want the compiler to
do the job for me. To accomplish this I've placed the serialisation code and
the array of pointers to members in a base class, and derive the structs I
want to serialize from this base class. In doing this, I end up with
pointers to members that are defined on the base class, but actually
pointing to a member of the derived class.

I have been unable to unearth a reason why this would be illegal, and
"common sense" and experimentation suggests it should work, but common sense
is not always the best guide when it comes to C++. So, is this a legal thing
to do? What theoretical and/or practical problems will I run into? Is there
a better solution?

This is some example code showing the bit I'm concerned about:

class cBase {
 public:
  int cBase::*MyIntPtr;
};

class cDerived: public cBase {
 public:
  cDerived ()
    { MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

  int MyInt;
};


Thanks for any insight provided,

Hans Guijt



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Hans 8/12/2003 12:51:24 AM

See related articles to this posting

Hans Guijt wrote:

> This is some example code showing the bit I'm concerned about:
>
> class cBase {
>  public:
>   int cBase::*MyIntPtr;
> };

Legal but pointless as cBase has no members of type int.

> class cDerived: public cBase {
>  public:
>   cDerived ()
>     { MyIntPtr = (int cBase::*)(&cDerived::MyInt); };

No!  &cDerived::MyInt is of type int cDerived::*, and you
can't cast it to a member of the base class like that.
Casting member pointers is the opposite way around to
casting objects:  with an object you can cast a pointer to
derived to a pointer to base; with member pointers you cast
can cast a member pointer of a base class to a member
pointer to a base class.

If you think about it, this is the correct behaviour as it
prevents usage like the following

  cBase* b = new cBase;
  int cBase::* mp = &cDerived::MyInt;
  int i = b->*mp; // Help!  There is no such member

--
Richard Smith

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Richard 8/12/2003 6:15:22 PM

Andrea Griffini wrote:

> On 11 Aug 2003 20:51:24 -0400, Hans Guijt <hguijt@xs4all.nl> wrote:
> 
>  >The tricky bit is that I don't want to repeat the serialisation code on
>  >each struct I want to serialize, since there are quite a few of these
>  >(about 480) and the result is likely to contain errors. Instead I want
>  >the compiler to do the job for me.
> 
> Allow me a question... did you ever consider to use code
> generation ?

I did. Staying inside the C++ system for code generation
is a solution that is
- easier to maintain (yes, I see this every day),
- more reliable (errors get catched via the type system)
- faster at runtime (since C++ compiler starts optimization
in the code generation stage) 
- simply cool

C++ allows a maximum of abstraction, use it.
If You need _generic_ Serialization, build it.
There _is_ a solution. If we do not find it by ourselves
we could ask Andrei Alexandrescou.


You mentioned C++ compilers which disagree with the template code.
The problem is not the code. The problem is that some people are
allowed to call their crap a "C++ compiler" without getting punished.

Fortunately the most important compiler _do_ understand C++
by now. This means that gcc-3.4 will be able to compile my code
like all EDG-based versions do since 2002. 
So if You are on a widely used platform,
there is no problem left with disagreeing compilers.


Markus

-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/ 

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/12/2003 6:19:10 PM

"Richard Smith" <richard@ex-parrot.com> wrote in message
news:Pine.LNX.4.55.0308121107210.9088@sphinx.mythic-beasts.com...
> Hans Guijt wrote:
>
> > This is some example code showing the bit I'm concerned about:
> >
> > class cBase {
> >  public:
> >   int cBase::*MyIntPtr;
> > };
>
> Legal but pointless as cBase has no members of type int.
Surprisingly, not pointless.  I was familiar with using Hans' method with
pointers to member *function* in order call derived class member functions
(including derived class accessors) bound to a (statically) base pointer,
but never considered that you could do the same with pointers to member
*data*.  However when I checked the Standard it seems that there is no
reason that it won't work with pmd also.
>
> > class cDerived: public cBase {
> >  public:
> >   cDerived ()
> >     { MyIntPtr = (int cBase::*)(&cDerived::MyInt); };
>
> No!  &cDerived::MyInt is of type int cDerived::*, and you
> can't cast it to a member of the base class like that.
The paragraph on static_cast applied to pointers to member, 5.2.9/9 I think,
indicates that a pointer to derived class member can be upcast to a pointer
to base class member as long as there is a valid inverse standard
conversion.  I couldn't find any distinction made there between pmf and pmd
types.  In sanctioning the downcast, the paragraph delineating the standard
conversion of pointers to member, 4.11/2, just requires accessibility and a
nonvirtual base class; it also makes no distinction between pmd and pmf
types.  Finally, the section on C-style casts, ie. "cast notation", section
5.4, indicates that the C-style cast in question should be interpreted as a
static_cast. Putting those elements together, Hans' cast looks okay to me.
> Casting member pointers is the opposite way around to
> casting objects:  with an object you can cast a pointer to
> derived to a pointer to base; with member pointers you cast
> can cast a member pointer of a base class to a member
> pointer to a base class.
Richard, your explanation is valid reasoning for standard conversions, which
may be done implicitly (and nonanalytically) by the compiler.  In that case
great care is exercised by language rules to avoid dereferencing a member
that doesn't actually exist, as you pointed out.  Explicit casts however are
allowed to evade this relationship, with the understanding that the writer
of the cast expression is guaranteeing that the dynamic object really does
contain the member referred to by the pointer to member-- the compiler can't
know at compile time whether the member is valid or not; the writer promises
that it will be valid at run time, and the cast acts as a "manual override"
of normal behavior to give the writer this capability.

Hiram Berry




      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Hiram 8/12/2003 11:03:36 PM

Richard Smith <richard@ex-parrot.com> wrote 

> Hans Guijt wrote:
> 
> > This is some example code showing the bit I'm concerned about:
> >
> > class cBase {
> >  public:
> >   int cBase::*MyIntPtr;
> > };
> 
> Legal but pointless as cBase has no members of type int.
> 
> > class cDerived: public cBase {
> >  public:
> >   cDerived ()
> >     { MyIntPtr = (int cBase::*)(&cDerived::MyInt); };
> 
> No!  &cDerived::MyInt is of type int cDerived::*, and you
> can't cast it to a member of the base class like that.
> Casting member pointers is the opposite way around to
> casting objects:  

You're probably thinking about the standard conversion (4.11/2). 
Strangely enough, however, this is actually a perfectly legal static
cast (see 5.2.9/9).  In particular, the standard says:

  If class B contains the original member, or is a base or
  derived class of the class containing the original member,
  the resulting pointer to member points to the original
  member.

Since cBase is a base class of the class (cDerived) that contains the
original member (cDerived::MyInt), the value of MyIntPtr is
well-defined.

If, however, the object for which the pointer to member is
dereferenced is of a dynamic type that does not have the pointed-to
member (e.g. cBase, cOtherDervied, etc.), the behavior of the
dereferncing expression is undefined (5.5/4).  So it's probably best
to do a dynamic_cast on this before actually using MyIntPtr.

That said, if the "mapping" is really being initialized on a
per-object basis, as in the OP's code snippet, I'm not sure I see the
point of using pointers-to-members at all.  Another poster has already
noted that it's possible to do the same thing with plain ol'
references (or pointers).  And if you squint at that approach just
right, and it starts to look a lot like reinventing the vtable.

So...my own first cut at the problem would be to ask whether we can't
get what we need with plain old virtual functions?

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply johnchx2 8/12/2003 11:05:28 PM

On 12 Aug 2003 14:19:10 -0400, Markus Werle
<numerical.simulation@web.de> wrote:

 >I did. Staying inside the C++ system for code generation
 >is a solution that is
 >- easier to maintain (yes, I see this every day),

Depending on the level of template trickery my impression
is that you can get code that's way more complex to
understand than simple imperative code generation (if
you want to understand the template trickery, of course;
if you want to use template trickery without understanding
it then it's another matter - you will just start crying
when somehing will not work (and it's when, not if) ).

Something as simple as "do this for every data member
of the class" is already out of the reach of templates.
Serialization is IMO a perfect example.

You can get somewhat close using inheritance to try
to emulate containment (ask Andrei for the details) ...
and honestly it's impressive what you can get by playing
with templates. Like it's impressive seeing someone that
can stand up on just one hand.

But IMO you shouldn't forget that you don't have to;
we normally have legs and we can stand while reading
a newspaper, and we can even jump and run.

 >- more reliable (errors get catched via the type system)

What do you mean ? The generated code is passed
through the compiler and will eventually raise errors
that are quite descriptive. Note that the generated
code will probably be clear explicit non-template code.
How can be templates *more* reliable than this ?
Template code has some type variability that non-template
code has not: true that template can be better about type
checking than macros; but it's worse than non-template.

Also error reporting is a very typical example of areas
in which templates are quite weak. Normally with current
technology an error message in a template will have
the form of two screenfulls of babbling nonsense.
Error reporting in templates is such a weak spot that
there's even someone that is making a living on this
defect by selling you third party add-ons to help compilers!

 >- faster at runtime (since C++ compiler starts optimization
 >in the code generation stage)

As a first impression I am honestly tempted to qualify
this statement as distilled nonsense; can you explain what
you mean ? Why could be explicit non-template code worse
than template code for the optimizer ?

 >- simply cool

Oh. This is true. I was somewhat fooled by OP's request
in thinking that he was interested in something working;
and preferably simpler and better for the compiler too.

Looks like you're looking for something cool instead.

Probably the more complex and intricate is the cooler is;
your dream is - just guessing - writing code that no one
else in your workgroup will even barely understand. In this
case I completely agree templates can be better for that.

 >C++ allows a maximum of abstraction, use it.

I think one should use abstraction only to the point of
return of investment. A typical case is IMO <algorithm>.
In many cases it's way more complex to try to describe an
abstraction in such a rigid language that just write the
implementation you want. The compiler is happier, the
code is faster, the collegues are less frustrated when
reading the code and error messages you get do actually
have a meaning. All way "uncool", I suppose.

 >If You need _generic_ Serialization, build it.

IMO just a few in the world need generic serialization
(and they need it to sell it, not to use it).
Many need *specific* serialization and IMO sometimes this
can be an area in which code generators can do miracles.
It's something very stupid an repetitive and a program is
better for this kind of job.
Sure I think one should build a tool to avoid repeating
tasks; I am a true supporter the idea of of working to
avoid working. I think this is one of the souls of a
real programmer. I've to admit that I actually also happen
to be a terrible performer in repetitive brainless jobs.

Building using the wrong tool is another issue, however.
Like I said in the past I think templates are a impressive
new shiny hammer. A really nice one, honest. Still this
doesn't mean everything is now a nail.

 >There _is_ a solution. If we do not find it by ourselves
 >we could ask Andrei Alexandrescou.

There are many solutions. Of course if you add artificial
limits you can end up in a place where there is only one
solution. Or even none, but an almost pratical quasi-solution
(for example inheritance as a mean for monkeying inclusion).

 >You mentioned C++ compilers which disagree with the template code.
 >The problem is not the code. The problem is that some people are
 >allowed to call their crap a "C++ compiler" without getting punished.

So ? Sometimes there are other reasons for which a specific
platform must be used. C++ portability was a joke a few years
ago... now the situation is not terrible, especially if you
avoid the dark corners. But template trickery is one of
those corners.

Most portable libraries are currently *NOT* written in just
generic portable C++, but have a lot of #ifdefs and macros
to try to handle the diversity. Most of the times it can be
done, true, but I'm not paid to try to find new problems and
obstacles... my employer expects from me solutions.
If I can't get something working then my employer is not really
that happier if the problem is in a vendor part, especially if
I could have easily avoided the problematic area completely.
Let alone if they get to know that I entered deliberately
and without need an area that was a well-known source of
portability problems. And please don't make my employer hear
the comments about my code in the caffetteria; I'm not sure
if my employer will be that happy no one else - and not even
me in a few months - can understand what's in the code.

 >Fortunately the most important compiler _do_ understand C++
 >by now. This means that gcc-3.4 will be able to compile my code
 >like all EDG-based versions do since 2002.
 >So if You are on a widely used platform,
 >there is no problem left with disagreeing compilers.

I guess all third party libraries for Win32 in the world
(for example for controlling special hardware) now support
g++/cygwin in addition to VC++ 6, right ?

Anyway, I hoped my suggestion helped. Seems you think it didn't.

Andrea

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Andrea 8/13/2003 7:46:03 AM

"David Turner" <david@firepro.co.za> schreef in bericht
news:bha3io$grr$1@ctb-nnrp2.saix.net...

> "Hans Guijt" <hguijt@xs4all.nl> wrote in message
> news:3F37ECC2.9020603@xs4all.nl...

>  > This is some example code showing the bit I'm concerned about:
>  >
>  > class cBase {
>  >  public:
>  >   int cBase::*MyIntPtr;
>  > };
>  >
>  > class cDerived: public cBase {
>  >  public:
>  >   cDerived ()
>  >     { MyIntPtr = (int cBase::*)(&cDerived::MyInt); };
>  >
>  >   int MyInt;
>  > };

> There's nothing wrong with the idea, but perhaps I can offer a
> simplification:
>
> class Base {
> protected:
>      int& intref;
> };
>
> class Derived: public Base {
>      int my_int;
> public:
>      Derived(): intref(my_int) { }
> };

My apologies; for the sake of this post I simplified the code a great deal.
I'm actually using a third class to store the member pointers, allowing me
to share the mapping information between instantiations of cDerived (of
which there are generally speaking enough that this is worth doing). The
various responses I received seem to (mostly) agree that doing this is
legal. If it had not been, this would have been my fallback solution.

> Apart from slightly cleaner syntax, this offers the advantage of a
potential
> optimization: intref is likely to be eliminated altogether by the
compiler.
>
> Another way to do this is of course through virtual accessor members
> (although that might be a little heavy for a lightweight object).  Yet
> another technique which is fruitful is the Curiously Recurring Template:
>
> template<class D>
> class Base {
> public:
>      void serialize(ostream& of) {
>          D* subject = static_cast<D*>(this);
>          of << subject->fetchInt();
>      }
> };
>
> class Derived: public Base<Derived> {
>      int my_int;
> public:
>      int fetchInt() const { return my_int; }
> };

Unless I'm mistaken, don't these two solutions require that the base class
is already aware of the contents of the derived class? This is not a problem
if that contents consists of just a single integer, but I'm dealing with
much larger structures containing various types of data. Effectively, what
I'm trying to accomplish is getting the serialize() function without
actually having to write it for each class I want to serialize.


Regards,

Hans Guijt



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Hans 8/13/2003 1:37:07 PM

Andrea Griffini wrote:

> On 12 Aug 2003 14:19:10 -0400, Markus Werle
> <numerical.simulation@web.de> wrote:
> 
>  >I did. Staying inside the C++ system for code generation
>  >is a solution that is
>  >- easier to maintain (yes, I see this every day),
> 
> Depending on the level of template trickery my impression
> is that you can get code that's way more complex to
> understand than simple imperative code generation (if
> you want to understand the template trickery, of course;
> if you want to use template trickery without understanding
> it then it's another matter - you will just start crying
> when somehing will not work (and it's when, not if) ).

Yes, but libraries like boost::mpl or things that will 
become a library like daixtrose, help a lot here.

> Something as simple as "do this for every data member
> of the class" is already out of the reach of templates.
> Serialization is IMO a perfect example.

Yes. Of course the serialization problem leaves a lot
of open questions if we uses templates. OTOH I hesitate
to give up the one-shot-within-the-language too soon.

Templates, when used wisely, can save You a lot of 
headaches that only appear with distinct code generators.

> You can get somewhat close using inheritance to try
> to emulate containment (ask Andrei for the details) ...
> and honestly it's impressive what you can get by playing
> with templates. Like it's impressive seeing someone that
> can stand up on just one hand.
> 
> But IMO you shouldn't forget that you don't have to;
> we normally have legs and we can stand while reading
> a newspaper, and we can even jump and run.

We always have 2 choices here: generate code using the
C++ language itself or a separate code generator.

> >- more reliable (errors get catched via the type system)
> 
> What do you mean ? The generated code is passed
> through the compiler and will eventually raise errors
> that are quite descriptive. Note that the generated
> code will probably be clear explicit non-template code.
> How can be templates more reliable than this ?
> Template code has some type variability that non-template
> code has not: true that template can be better about type
> checking than macros; but it's worse than non-template.
> 
> Also error reporting is a very typical example of areas
> in which templates are quite weak. Normally with current
> technology an error message in a template will have
> the form of two screenfulls of babbling nonsense.
> Error reporting in templates is such a weak spot that
> there's even someone that is making a living on this
> defect by selling you third party add-ons to help compilers!

OK, I give You an example:
I have to write numerical simulation software. 
For several different purposes I need to use the same method to
solve different specific sets of partial differential equations.

Since the task of discretization of partial differential 
equations is quite complex and since I need to differentiate 
the discretized equations with regard to every variable 
contained, I decided to create a full blown automatic 
discretiziation and differentiation.

So now you who probably are not familiar to finite-element
code generation could (if I gave my code to you) use my code
to generate time implicit fem-fct-solvers for an abritrary 
system of partial differential equations within hours just by
typing code similar to:

Solver.AddPDE<2>(Differentiation<Time>(m_1)
                 + 
                 Differentiation<Space_x>(Pow<2>(m_1) 
                                          / 
                                          rho + p)
                 +
                 Differentiation<Space_y>((m_1 * m_2) / rho)
                 == Null);

The rest is done _by_ _the_ _compiler_.
So the level of abstraction is at peak: we have a 1-to-1 
correspondence between the equations and the code we need to
write.

If You make an error, e.g. try to multiply something with a 
differentiation like in

rho * Differentiation<Time>(m_1)

the myriads of compiler errors you get also contain the string
"[ alot of undercores stripped ]
__ERROR_You_must_not_multiply_space_or_time_diffs_with_something_else__
[ alot of undercores stripped ]", so you understand your error 
immediately.

Using the type system to catch these errors appears so much simpler to me
than if (thiscondition) { ... } else { throw ... } etc.

I just happened to write a rather rich file and command line parser with
default formulas etc. using boost::spirit where I decided to try to be
object oriented and also circumvent the type system a little bit. In that
code I had to build in some traps for common errors. I really got mad about
it.  This is why I like code that exploits the C++ parser and the C++ type
system.


> 
>  >- faster at runtime (since C++ compiler starts optimization
>  >in the code generation stage)
> 
> As a first impression I am honestly tempted to qualify
> this statement as distilled nonsense; 

It's impressive how things can be formulated to pass the mods :-)

> can you explain what
> you mean ? Why could be explicit non-template code worse
> than template code for the optimizer ?

I take this back. I say: in theory, if I had a very good 
highly optimizing compiler, this compiler might see through my
complete code generation routines and find a way to improve the
overall runtime performance, because optimization starts 
during automatic discretization.

I have no proof for this, since I never tried to achieve my goals
with a separate code generator, but I heard some people are working 
on code folding for templates, such that the dependency between
the number of instantiations of some generic algorithm and the
code size is no longer linear. Also my profiler tells me that
it's not the code generation part that contributes to runtime, but
rather things outside that part. So since the overhead tends to zero
with today's compilers I felt strong enough to make the statement.


>  >- simply cool
> 
> Oh. This is true. I was somewhat fooled by OP's request
> in thinking that he was interested in something working;
> and preferably simpler and better for the compiler too.

I think that my code generator is simply cool because it works
and is rather simple to use.

> Looks like you're looking for something cool instead.

I search for solutions that are generic such that they solve 
a problem once for all times.


> Probably the more complex and intricate is the cooler is;
> your dream is - just guessing - writing code that no one
> else in your workgroup will even barely understand. 

Please take a look at daixtrose. I worked hard on using
class and variable names that make sense to others.
My unpublished finite element code has great parts 
that read like books:

 if (!only_first_order)
   {
     //////////////////////////////////////////////////////////////////////
     // recalculation of F_ with new data in final 1st order solution:
     CalculateAntidiffusiveFluxes(Timestep_);
     PrelimitAntidiffusiveFluxes();
     LimitAntidiffusiveFluxes();
 
     //////////////////////////////////////////////////////////////////////
     // final solution
     IterateFinalSolution(Timestep_, ConvergenceCriterion); 
   }

> In this
> case I completely agree templates can be better for that.

Of course templates can be misused for obfuscated C++.
OTOH templates help a lot to separate concepts.
A list is a list, independent of whether it is a list
of apples or pees.

>  >C++ allows a maximum of abstraction, use it.
> 
> I think one should use abstraction only to the point of
> return of investment. 

Sometimes you need a long breath to finally end up with
something that is stronger, easier to use and faster
to apply to new situations.
Of course you have to pay for power, like one of
my Professors said: there is a conservation law for
the complexity and work to be done.

> A typical case is IMO <algorithm>.
> In many cases it's way more complex to try to describe an
> abstraction in such a rigid language that just write the
> implementation you want. The compiler is happier, the
> code is faster, the collegues are less frustrated when
> reading the code and error messages you get do actually
> have a meaning. All way "uncool", I suppose.

No. This is the way to approach it.
Once you find you write some code twice, then it is 
time to write the template version.
I wonder why it took millions of people writing linked lists
before someone decided to write one for all times.
(BTW: writing a std::list is so much cheaper than writing
a code generator for a listSomeClass)

Also, in case you got familiar with templates
I think a good design or code description shows 
the independence of the patterns and if you reflect this
independence in your code, you will get awarded for this 
immediately.


> 
>  >If You need generic Serialization, build it.
> 
> IMO just a few in the world need generic serialization
> (and they need it to sell it, not to use it).

Ah. 

> Many need specific serialization and IMO sometimes this
> can be an area in which code generators can do miracles.

A template with controllable or specializable aspects
(keyword "policy") maybe too.

> It's something very stupid an repetitive and a program is
> better for this kind of job.

Funny, but I use templates always to avoid code repetition.

> Sure I think one should build a tool to avoid repeating
> tasks; I am a true supporter the idea of of working to
> avoid working. I think this is one of the souls of a
> real programmer. I've to admit that I actually also happen
> to be a terrible performer in repetitive brainless jobs.
> 
> Building using the wrong tool is another issue, however.
> Like I said in the past I think templates are a impressive
> new shiny hammer. A really nice one, honest. Still this
> doesn't mean everything is now a nail.

But since I saw typelist I really feel like there is no reason to avoid
templates for the serialization task.  Although I cannot iterate the members
in a class I can iterate the members in a typelist. Therefore if I had to do
serialization my first attempt always would be some template stuff.

OTOH I agree that some external code generator might quickly
help here a lot, but I always fear the maintenance problem.

>  >There is a solution. If we do not find it by ourselves
>  >we could ask Andrei Alexandrescou.
> 
> There are many solutions. Of course if you add artificial
> limits you can end up in a place where there is only one
> solution. Or even none, but an almost pratical quasi-solution
> (for example inheritance as a mean for monkeying inclusion).
> 
>  >You mentioned C++ compilers which disagree with the template code.
>  >The problem is not the code. The problem is that some people are
>  >allowed to call their crap a "C++ compiler" without getting punished.
> 
> So ? Sometimes there are other reasons for which a specific
> platform must be used. C++ portability was a joke a few years
> ago... now the situation is not terrible, especially if you
> avoid the dark corners. But template trickery is one of
> those corners.

The point I wanted to make is that I expect C++ portability to
reach the level C and Fortran have today within a couple of years.
So _all_ language aspects of C++ should be considered for new code
disregarding the crap compilers (which I also expect to vanish soon)

> Most portable libraries are currently NOT written in just
> generic portable C++, but have a lot of #ifdefs and macros
> to try to handle the diversity. Most of the times it can be
> done, true, but I'm not paid to try to find new problems and
> obstacles... my employer expects from me solutions.
> If I can't get something working then my employer is not really
> that happier if the problem is in a vendor part, especially if
> I could have easily avoided the problematic area completely.
> Let alone if they get to know that I entered deliberately
> and without need an area that was a well-known source of
> portability problems. And please don't make my employer hear
> the comments about my code in the caffetteria; 

I agree with your intention here.
I simply do not see a contradiction anymore.
When e.g. Qt first was published it was wise to write rather
non-templated code and create private container substitutes
for the STL. As of today I believe it would be wise to rewrite
the code step by step reverting back to std:: and also 
exploiting the stuff that brings speed. 

> I'm not sure
> if my employer will be that happy no one else - and not even
> me in a few months - can understand what's in the code.

Since Vandevoorde/Josuttis finally took the time to 
publish a "complete guide" (which I think is the first time
a book deserves such a 2nd title) no one is allowed to
cry anymore at the sight of some <> brackets.

Also I do not see how avoiding templates should hinder anyone
to write obfuscated code. C++ _is_ ugly, yes, but after some
weeks you get the used to <> like you got used to {} and stopped
to forget the ; at class end.


>  >Fortunately the most important compiler do understand C++
>  >by now. This means that gcc-3.4 will be able to compile my code
>  >like all EDG-based versions do since 2002.
>  >So if You are on a widely used platform,
>  >there is no problem left with disagreeing compilers.
> 
> I guess all third party libraries for Win32 in the world
> (for example for controlling special hardware) now support
> g++/cygwin in addition to VC++ 6, right ?
> 
> Anyway, I hoped my suggestion helped. Seems you think it didn't.

I think it did. I just wanted to mention I had made very good 
experience with the opposite method, so it should not be 
abandoned too soon. Probably my wordings shadowed this intent, sorry.


best regards,


Markus 

-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/ 

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/13/2003 4:06:16 PM

"Hans Guijt" <hguijt@inter.nl.net> wrote 

> So the solution I came up with involves an array of unions of pointers to
> member. This is a pretty good solution: I need just a single function to
> initialize the array (meaning I need to do a limited amount of work), I can
> share the array between instantiations of derived classes, and I can add any
> operation on the structures that I desire by simply adding a single new
> function. The solution provides me with both type safety and readability in
> the client code, since it can simply access the payload as if it were any
> normal C++ class. 

This sounds very interesting.  For some reason, though, I'm having
trouble visualizing how it works in practice.  For example, how does
cBase know the type of the result of dereferencing one of the pointers
in the array?  Perhaps posting a snippet of the serialization code,
showing how cBase selects a member from the union and uses the result
would help me see what's going on.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply johnchx2 8/13/2003 10:47:14 PM

Markus Werle wrote:

> Andrea Griffini wrote:
> 
> 
>>On 11 Aug 2003 20:51:24 -0400, Hans Guijt <hguijt@xs4all.nl> wrote:
>>
>> >The tricky bit is that I don't want to repeat the serialisation code on
>> >each struct I want to serialize, since there are quite a few of these
>> >(about 480) and the result is likely to contain errors. Instead I want
>> >the compiler to do the job for me.
>>
>>Allow me a question... did you ever consider to use code
>>generation ?
> 
> 
> I did. Staying inside the C++ system for code generation
> is a solution that is
> - easier to maintain (yes, I see this every day),
> - more reliable (errors get catched via the type system)
> - faster at runtime (since C++ compiler starts optimization
> in the code generation stage) 
> - simply cool
> 
> C++ allows a maximum of abstraction, use it.
> If You need _generic_ Serialization, build it.
> There _is_ a solution. If we do not find it by ourselves
> we could ask Andrei Alexandrescou.

There is no solution as long as we're restricted to the current C++ 
standard. (At least not one that doesn't require one to build 
compile-time representations for the types to be serialised.)

What I'd like to see was standard support for something like 
type_description<T>, which would contain fields like 
type_description<T>::is_pod, type_description<T>::base_classes, 
type_description<T>::member_functions, 
type_description<T>::public::members, &c.

-- 
Aatu Koskensilta (aatu.koskensilta@xortec.fi)

"Wovon man nicht sprechen kann, daruber muss man schweigen"
  - Ludwig Wittgenstein, Tractatus Logico-Philosophicus

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Aatu 8/14/2003 12:27:54 PM

Andrea Griffini wrote:

> On 13 Aug 2003 12:06:16 -0400, Markus Werle
> <numerical.simulation@web.de> wrote:
> 
>>Yes, but libraries like boost::mpl or things that will
>>become a library like daixtrose, help a lot here.
> 
> Suggesting using a template library is one thing.
> Suggesting writing a template library is another.
> 
>>Templates, when used wisely, can save You a lot of
>>headaches that only appear with distinct code generators.
> 
> Can you make an example of headache ?

Parsing.
Writing a parser that handles every situation is hard. 
Using the C++ type system and exploiting the C++ parser 
saves you a lot.
Since the parser is missing in my approach, I do not
have to maintain one. This is what I do within daixtrose.
The expression is parsed using template metaprogramming,
but most of the time I can simply rely on the C++ rules.


>>We always have 2 choices here: generate code using the
>>C++ language itself or a separate code generator.
> 
> There would be a choice if templates could iterate
> over the members. But serialization is out of the reach
> of template (unless of course you don't want to iterate
> over the members but try to change my needs on an iteration
> over the base classes).

I disagree and by the same time stay in debt regarding
a counter example due to lack of time.

> [...]
>>OK, I give You an example:
>>I have to write numerical simulation software.
>>For several different purposes I need to use the same method to
>>solve different specific sets of partial differential equations.
> 
> I thought the discussion was about serialization and
> member enumeration in general. 

I thought it was about code generation no matter what
the problem/task is.

> I for example think that
> template are very nice for dimensionality parametrization;
> even if the results of a few experiments I made about
> efficency of the generated code are if compared to hand
> unrolled code not that good (not terrible, but still worse).

With today's compilers you get it down to factor 1.6 in numerics.

> I agree that in *theory* compilers can see what's common
> in templates and merge those parts.
> Unfortunately this is not what compiler technology gives
> us today... and the code bloating risk is always here to
> remember us this fact.
> Just try to do the simplest experiment with g++...

Bah! Which version? Which command-line options?
I was talking with Intel C++ 7.1 (using IPO) in mind. 

>>I think that my code generator is simply cool because it works
>>and is rather simple to use.
> 
> And it does serialization iterating over the members ?

No, but it shows that an in-language code generator can be
the Right Thing to do. Would _you_ use the compiler
to differentiate expressions? I do. 

>>I search for solutions that are generic such that they solve
>>a problem once for all times.
> 
> So much damage to the human race has been done by who
> was seeking the definitive solution. I think there's
> no definitive solution (especially because there's no
> definitive problem).

I said: _a_ problem. There is no definitive solution, but 
probably one that can be reused. This is what templates are
all about.

>>A list is a list, independent of whether it is a list
>>of apples or pees.
> 
> There are a lot of variations even on a list, and the
> view given by the standard library is just one possible
> view, that in some context doesn't fit well. I use a
> lot of linked lists in my code, but I rarely used std::list.

I had some crazy experience with std::map:
I use std::map to store entries of a sparse matrix.
Since this part of my code really is the expensive part
I tried to substitute std::map with things like Loki::AssocVector
and to use other allocators. And guess: std::map always wins.

So all those SpecialPurposeMyOneIsTheBetterOne container
writers of the world got beaten by a std::container.
That was new to me.

> std::vector is IMO much more neutral and generally useful.

Yep.

>>Once you find you write some code twice, then it is
>>time to write the template version.
> 
> Only if the template use is really saving something.
> I for example think C++ for_each is worse than a for
> loop for several reasons (this is not true for other
> languages, of course, but it's IMO true for C++).

When I changed a container inside some class and found
out that the algo code still compiled and worked(!) due 
to the use of begin() and end() memfuns and this std::algorithm stuff 
I began to love these std::algorithms a lot.

together with boost::lambda/function they sometimes also 
make code cleaner and easier to understand.

>>I wonder why it took millions of people writing linked lists
>>before someone decided to write one for all times.
>>(BTW: writing a std::list is so much cheaper than writing
>>a code generator for a listSomeClass)
> 
> I normally write my simple linked lists by hand.

Wow! 

> [..]
> But back to serialization... ;)
> 
>>But since I saw typelist I really feel like there is no reason to avoid
>>templates for the serialization task.  Although I cannot iterate the
>>members in a class I can iterate the members in a typelist. Therefore if I
>>had to do serialization my first attempt always would be some template
>>stuff.
> 
> Good luck. I don't see that a reasonable solution
> because there are much better ones... they're not 100%
> C++, so ? I think it's better that way than ending up
> with a pure 100% C++ version that solves a problem
> roughly similar to what I wanted to solve and that
> also has a lot of pratical problematic issues.

Your decision as you like it.

>>The point I wanted to make is that I expect C++ portability to
>>reach the level C and Fortran have today within a couple of years.
>>So _all_ language aspects of C++ should be considered for new code
>>disregarding the crap compilers (which I also expect to vanish soon)
> 
> Including template recursion 40 levels deep ? 

No, sometimes more than 200. Recursion is fine.

> Including
> taking forever to compile C++ code written that way ?

Compile time is nonlinear with time:
The power of our computers increase exponentially
and compiler vendors finally found out how to deal with 
templates. Every new compiler version cuts down compile time
by at least 10%.
I use templates because the runtime performance
is better when I calculate it at compile time. This pays off
most of the times.

> [...]
> Still I wouldn't so sure I necessarely will end up
> believing that pushing using a 40 leves deep hierarchy
> down the throat of my compiler when what I wanted was
> just a list of 40 members is a sensible thing to do.

40 members in a class looks like a candidate for a redesign.
Especially if it is something which calls serialization.
OTOH size does not matter. The solution should scale well.
So probably the OP will reach his goal earlier with
an external code generator, but I still think the in-C++
approach is achievable and may have some advantage.

>>I think it did. I just wanted to mention I had made very good
>>experience with the opposite method, so it should not be
>>abandoned too soon. Probably my wordings shadowed this intent, sorry.
> 
> You had good experiences in other areas (dimensionality
> and policy) and not in members enumeration.

If the set of possible member names and types is finite 
I see a good chance to have a generic C++ solution.
fast.

> May be you're right and that's a good path ... but my gut
> feeling is that this is a circus thing, not for serious use.

Compile time differentiation like in daixtrose looks like
a circus thing but is used in production code.


Markus


-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/ 

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/15/2003 9:15:58 PM

Aatu Koskensilta wrote:


> What I'd like to see was standard support for something like
> type_description<T>, which would contain fields like
> type_description<T>::is_pod, 

http://www.boost.org/libs/type_traits/index.htm

> type_description<T>::base_classes,

If the set of base classes is finite You can check for this.

> type_description<T>::member_functions,
> type_description<T>::public::members, &c.

You want those as typelist?

Markus




-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/ 

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/15/2003 9:16:45 PM

In article <bhifqm$10jsa$1@ID-153032.news.uni-berlin.de>,
  on 15 Aug 2003 17:15:58 -0400,
  Markus Werle <numerical.simulation@web.de> wrote:

 > Andrea Griffini wrote:
 >
 >> On 13 Aug 2003 12:06:16 -0400, Markus Werle
 >> <numerical.simulation@web.de> wrote:
 >>
 >>>The point I wanted to make is that I expect C++ portability to reach
 >>>the level C and Fortran have today within a couple of years.  So
 >>>_all_ language aspects of C++ should be considered for new code
 >>>disregarding the crap compilers (which I also expect to vanish soon)
 >>
 >> Including template recursion 40 levels deep ?
 >
 > No, sometimes more than 200. Recursion is fine.

Not if you care about portability, it's not. (see 14.7.1p14 and Annex B
for details)

Regards,
  Andy S
-- 
"Light thinks it travels faster than anything but it is wrong. No matter
  how fast light travels it finds the darkness has always got there first,
  and is waiting for it."                  -- Terry Pratchett, Reaper Man

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Andy 8/17/2003 11:40:11 AM

Markus Werle <numerical.simulation@web.de> writes:

 > Andrea Griffini wrote:
[snip]
 >> Including template recursion 40 levels deep ?
 >
 > No, sometimes more than 200. Recursion is fine.
[snip]

The standard only requires 17 levels be supported. (Most compilers
     support much more, when given appropriate flags.)

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 8/18/2003 10:29:58 AM

Andy Sawyer wrote:

> In article <bhifqm$10jsa$1@ID-153032.news.uni-berlin.de>,
>   on 15 Aug 2003 17:15:58 -0400,
>   Markus Werle <numerical.simulation@web.de> wrote:
> 
>  > Andrea Griffini wrote:
>  >
>  >> On 13 Aug 2003 12:06:16 -0400, Markus Werle
>  >> <numerical.simulation@web.de> wrote:
>  >>
>  >>>The point I wanted to make is that I expect C++ portability to reach
>  >>>the level C and Fortran have today within a couple of years.  So
>  >>>_all_ language aspects of C++ should be considered for new code
>  >>>disregarding the crap compilers (which I also expect to vanish soon)
>  >>
>  >> Including template recursion 40 levels deep ?
>  >
>  > No, sometimes more than 200. Recursion is fine.
> 
> Not if you care about portability, it's not. (see 14.7.1p14 and Annex B
> for details)

You got me.
I always wondered how one could circumvent this restriction
of the standard and appreciate any link or hint to some
technique to achieve this.

OTOH all modern compilers seem to support this without any
trouble - which I find a logical consequence of having as much 
symmetry as possible between the runtime and the compile time system.
Or: Ain't the limitation a defect anyway? 
Think of "for (size_t i = 1; i != 18; ++i);"


Markus

-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/ 

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/18/2003 5:26:12 PM

Markus Werle <numerical.simulation@web.de> wrote in message news:<bhig2u$10jsa$2@ID-153032.news.uni-berlin.de>...
> Aatu Koskensilta wrote:
> 
> 
> > What I'd like to see was standard support for something like
> > type_description<T>, which would contain fields like
> > type_description<T>::is_pod, 
> 
> http://www.boost.org/libs/type_traits/index.htm

Sadly, many of these just always return the "safest" answer.

> 
> > type_description<T>::base_classes,
> 
> If the set of base classes is finite You can check for this.
> 
> > type_description<T>::member_functions,
> > type_description<T>::public::members, &c.
> 
> You want those as typelist?

I've talked myself into promising to do this for my MS thesis; adding
this kind of stuff onto gcc.  If the result isn't complete crap; you
may find it useful.  It's supposed to be done by April; and may
actually be finished by then.

On the other hand, I may find it easier to fake my death, learn
spanish, and move to Venezuela.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply lallysingh 8/18/2003 11:54:23 PM

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

> llewelly <llewelly.at@xmission.dot.com> writes:
>
> | Markus Werle <numerical.simulation@web.de> writes:
> | 
> |  > Andrea Griffini wrote:
> | [snip]
> |  >> Including template recursion 40 levels deep ?
> |  >
> |  > No, sometimes more than 200. Recursion is fine.
> | [snip]
> | 
> | The standard only requires 17 levels be supported.
>
> The standard does not require 17.

No, it requires *at least* 17, sorry if that wasn't clear from the 
    following text which you snipped.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 8/19/2003 11:26:55 PM

llewelly wrote:

 > Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
 >
 >> llewelly <llewelly.at@xmission.dot.com> writes:
 >>
 >> | Markus Werle <numerical.simulation@web.de> writes:
 >> |
 >> |  > Andrea Griffini wrote:
 >> | [snip]
 >> |  >> Including template recursion 40 levels deep ?
 >> |  >
 >> |  > No, sometimes more than 200. Recursion is fine.
 >> | [snip]
 >> |
 >> | The standard only requires 17 levels be supported.
 >>
 >> The standard does not require 17.
 >
 > No, it requires *at least* 17, sorry if that wasn't clear from the
 >     following text which you snipped.

Is there already a defect report about this?

Markus

-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/20/2003 11:39:45 PM

Markus Werle <numerical.simulation@web.de> writes:

[...]

|  >> | The standard only requires 17 levels be supported.
|  >>
|  >> The standard does not require 17.
|  >
|  > No, it requires *at least* 17, sorry if that wasn't clear from the
|  >     following text which you snipped.
|
| Is there already a defect report about this?

What would the defect be?

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/21/2003 11:01:36 AM

Markus Werle <numerical.simulation@web.de> writes:

 > llewelly wrote:
 >
 >  > Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
 >  >
 >  >> llewelly <llewelly.at@xmission.dot.com> writes:
 >  >>
 >  >> | Markus Werle <numerical.simulation@web.de> writes:
 >  >> |
 >  >> |  > Andrea Griffini wrote:
 >  >> | [snip]
 >  >> |  >> Including template recursion 40 levels deep ?
 >  >> |  >
 >  >> |  > No, sometimes more than 200. Recursion is fine.
 >  >> | [snip]
 >  >> |
 >  >> | The standard only requires 17 levels be supported.
 >  >>
 >  >> The standard does not require 17.
 >  >
 >  > No, it requires *at least* 17, sorry if that wasn't clear from the
 >  >     following text which you snipped.
 >
 > Is there already a defect report about this?

I don't know. I seem to recall I saw a proposal to raise most of the
     (informative) implementation limits somewhere on the commitee
     site, but I cannot find it.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 8/21/2003 11:02:33 AM

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

 > llewelly <llewelly.at@xmission.dot.com> writes:
 >
 > | Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
 > |
 > | > llewelly <llewelly.at@xmission.dot.com> writes:
 > | >
 > | > | Markus Werle <numerical.simulation@web.de> writes:
 > | > |
 > | > |  > Andrea Griffini wrote:
 > | > | [snip]
 > | > |  >> Including template recursion 40 levels deep ?
 > | > |  >
 > | > |  > No, sometimes more than 200. Recursion is fine.
 > | > | [snip]
 > | > |
 > | > | The standard only requires 17 levels be supported.
 > | >
 > | > The standard does not require 17.
 > |
 > | No, it requires *at least* 17, sorry if that wasn't clear from the
 > |     following text which you snipped.
 >
 > well, the point was that it does not even require at least 17.
 > Leaving in the rest of your text does not change that :-)

I looked again and the limits section is informative and not
     normative which is not what I had thought, but you are correct. I
     appologize.

 > The standard text just says there is an implementation-defined limit.
 > I hope implementors won't take 17 as a conformance limits.  I hope
 > they would choose sensible limits that support contemporary template
 > usage.

IOWs, more than 17. How much more I don't know. I still think most
     implementors provide more than 17 layers, though gcc at least
     requires a special flag.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 8/21/2003 12:37:09 PM

llewelly <llewelly.at@xmission.dot.com> writes:

[...]

|  >  > No, it requires *at least* 17, sorry if that wasn't clear from the
|  >  >     following text which you snipped.
|  >
|  > Is there already a defect report about this?
|
| I don't know. I seem to recall I saw a proposal to raise most of the
|      (informative) implementation limits somewhere on the commitee
|      site, but I cannot find it.

Since they are not normative, there is no real benefit in "improving"
on them.  The only effect such a revision might have is to lead people
in believing that the limits in annex B have a conformance value.

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/22/2003 9:36:23 AM

llewelly <llewelly.at@xmission.dot.com> writes:

[...]

|  > The standard text just says there is an implementation-defined limit.
|  > I hope implementors won't take 17 as a conformance limits.  I hope
|  > they would choose sensible limits that support contemporary template
|  > usage.
|
| IOWs, more than 17.

I hope they take at least an order of magnitude.

| How much more I don't know. I still think most
|      implementors provide more than 17 layers, though gcc at least
|      requires a special flag.

Some past versions of GCC uses 17 as a default; but recent ones default
to 500.

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/22/2003 9:36:59 AM

On 22 Aug 2003 05:36:59 -0400, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:

>| IOWs, more than 17.
>
>I hope they take at least an order of magnitude.

I'm confused...

I don't understand why instead of just pumping up some
number so that template "misuses" can be ratified as
uses there can't be focus on the serious code generation
problem in its essence.

I mean being able to do loops when I want loops and
ifs when I want ifs and data structures when I want
data structures to support code generation.
A template metaprogram is a program, and there's an
historical proven record that having more than just
recursion and lists can make things way easier.

What's the nice part of insisting on running without
using our legs ?

Andrea

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Andrea 8/22/2003 4:32:16 PM

In article <m3n0e3rx89.fsf@uniton.integrable-solutions.net>, Gabriel Dos 
Reis <gdr@integrable-solutions.net> writes
>Since they are not normative, there is no real benefit in "improving"
>on them.  The only effect such a revision might have is to lead people
>in believing that the limits in annex B have a conformance value.

There was an extended discussion within WG21 in the mid 90s about how to 
deal with such limits. The problem with making them normative is that it 
might encourage implementors to consider those values as 'normal'. If 
you are writing for small systems you might want to keep the values low 
and also expect that your users will only use low values. Such should 
not prevent you from producing a conforming implementation. OTOH we 
would want implementors to make limits as high as possible while noting 
that a user who tried to simultaneously use several cases close to the 
limit might find their system had inadequate resources.

As a result those figures provided in the annex are really minimal 
values for all but very special cases and implementors in general should 
provide much higher values.

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


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Francis 8/22/2003 5:42:28 PM

Francis Glassborow <francis@robinton.demon.co.uk> writes:

| In article <m3n0e3rx89.fsf@uniton.integrable-solutions.net>, Gabriel Dos 
| Reis <gdr@integrable-solutions.net> writes
| >Since they are not normative, there is no real benefit in "improving"
| >on them.  The only effect such a revision might have is to lead people
| >in believing that the limits in annex B have a conformance value.

[...]

| As a result those figures provided in the annex are really minimal 
| values for all but very special cases and implementors in general should 
| provide much higher values.

We are in violent agreement.  Which is why I reacted to the mysterous
"17" limit.  I would like to see implementors have limits that serve
users, language use, etc.  I would hate to see implementors, in
general, impose very low limits because those numbers happen to appear
in a nonnormative part of the Standard. 

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/24/2003 11:47:59 PM

Andrea Griffini <agriff@tin.it> writes:

| On 22 Aug 2003 05:36:59 -0400, Gabriel Dos Reis
| <gdr@integrable-solutions.net> wrote:
| 
| >| IOWs, more than 17.
| >
| >I hope they take at least an order of magnitude.
| 
| I'm confused...
| 
| I don't understand why instead of just pumping up some
| number so that template "misuses" can be ratified as
| uses there can't be focus on the serious code generation
| problem in its essence.

I must confess I don't get what you are driving at.


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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/24/2003 11:48:25 PM

Andrea Griffini <agriff@tin.it> wrote
 >
 > I don't understand why instead of just pumping up some
 > number so that template "misuses" can be ratified as
 > uses there can't be focus on the serious code generation
 > problem in its essence.
 >
 > I mean being able to do loops when I want loops and
 > ifs when I want ifs and data structures when I want
 > data structures to support code generation.
 > A template metaprogram is a program, and there's an
 > historical proven record that having more than just
 > recursion and lists can make things way easier.
 >

Yes...and there is interesting work underway on this problem.  If you
haven't seen Daveed Vandevoorde's "Reflective Metaprogramming" paper,
you might want to take a look:

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1471.pdf

I gather it's been pretty well received, but I don't know whether it
has a real chance to become part of C++0x.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply johnchx2 8/26/2003 8:31:12 AM

Markus Werle <numerical.simulation@web.de> writes:

 > Gabriel Dos Reis wrote:
 >
 >> Markus Werle <numerical.simulation@web.de> writes:
 >>
 >> [...]
 >>
 >> |  >> | The standard only requires 17 levels be supported.
 >> |  >>
 >> |  >> The standard does not require 17.
 >> |  >
 >> |  > No, it requires *at least* 17, sorry if that wasn't clear from the
 >> |  >     following text which you snipped.
 >> |
 >> | Is there already a defect report about this?
 >>
 >> What would the defect be?
 >
 > The defect is that there _is_ a compiler limit at all.
 > The computer should be the limit, not the language, right?

Note that I was wrong to think that the 17 limit in the appendix was
     normative - it isn't.

Since the 17 isn't normative, we are back to Gaby's question - what
     would the defect be?

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 8/27/2003 9:52:10 AM

Markus Werle <numerical.simulation@web.de> writes:

| Gabriel Dos Reis wrote:
| 
| > Markus Werle <numerical.simulation@web.de> writes:
| > 
| > [...]
| > 
| > |  >> | The standard only requires 17 levels be supported.
| > |  >>
| > |  >> The standard does not require 17.
| > |  >
| > |  > No, it requires *at least* 17, sorry if that wasn't clear from the
| > |  >     following text which you snipped.
| > |
| > | Is there already a defect report about this?
| > 
| > What would the defect be?
| 
| The defect is that there _is_ a compiler limit at all.

The standard does not talk about a compiler.  It defines a
parameterized abstract machine, its behaviour, mapping of C++
programs to behaviour of the parameterized abstract machine.  It
places requirements on implementations, in roughly two ways:
  (1) implementations ought to carry out some computations at
      translation time, as part of the translation of a C++ programs;

  (2) implememntations ought to carry out some computations as part of
      executing the translated programs.

As part of assumptions in category (1), the C++ definition assumes
bounded computations, taking bounded resources.  

[...]

| Since a nested template can be represented by a tree structure

actually, nested templates are not trees; they are either possibly
infinite trees or graphs (possibly with cyclic compoenents).

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/27/2003 3:35:58 PM

Andrea Griffini <agriff@tin.it> wrote in message
news:<7h1hjvopmdvdbfg46oltkn3ncvbh4jiftg@4ax.com>...
> On 11 Aug 2003 20:51:24 -0400, Hans Guijt <hguijt@xs4all.nl> wrote:

>  >The tricky bit is that I don't want to repeat the serialisation code
>  >on each struct I want to serialize, since there are quite a few of
>  >these (about 480) and the result is likely to contain
>  >errors. Instead I want the compiler to do the job for me.

> Allow me a question... did you ever consider to use code
> generation ? I do not mean getting crazy in writing magic
> template code just to discover that you ended up using a
> part on which not all the C++ compilers agree on, but
> using an *exernal* code generator, written for example
> in PERL or Python. Starting from an input file like:

>    Employee:
>      name    = string
>      address = string
>      level   = EmployeeLevel
>      salary  = Money

>    Department:
>      code    = int
>      name    = string
>      ...

> you can generate all the C++ code you need in just a few lines of a
> suitable text processing tool.

It's nice to finally hear some common sense.  There seems a tendancy
today to want to do everything with templates.  For some things
(e.g. expression templates in things like mathematical integration),
they are definitly the way to go -- despite all the problems.  But for
many things, the old ways are still the best.  I've used some automatic
code generation (usually using a shell script with AWK, but sometimes
considerably more complex -- usimg ASN.1 as the source language, for
example) in almost all projects I've worked on over the last twenty
years.  I think I first got the idea from one of Jon Bentley's
"Programming Pearls" columns, concerning mini-languages.

Since you are designing the mini-language, some obvious tips:

  - Make it easy to parse.  It's only going to be used for one thing, so
    don't go hog wild on flexibility, supporting formatting options that
    no one in your shop uses.  Something line oriented like your example
    here is fine -- a parser in AWK might start with something like:

        NF == 1 && $1 ~ /:$/ {
            className = substr( $1, 1, length( $1 ) - 1 )
            next
        }

    In my experience, it is fairly easy to design a mini-language which
    is both easy to parse and easy to use.

    If you prefer working in C++, both Boost and I have regular
    expression classes available on the net (Boost's is exceptionally
    flexible, mine is probably slightly easier to use, and will work
    with some very old compilers -- earlier versions worked with CFront
    2.1, although I've updated it to use STL since then.), and I have a
    FieldArray class which does AWK style tokenizing.  (And of course,
    std::map handles AWK style arrays.)

  - Support comments and empty lines.  This is a minimum for user
    confort.  In AWK, I generally wrap the awk program in a shell script
    which uses sed to strip comments; in C++, I use a filtering
    streambuf on the input.

Note however that you don't always have to define a new mini-language.
If you look in the experimental section at my site, you'll find that I
use a number of generators which use UnicodeData.txt (a file I picked up
at the Unicode site) as a source for code generation.

> The only important thing is in this case IMO to be able to generate
> the code in its final form (i.e. code that you do not have to modify
> manually in the generated source) because in my experience
> regenerating will be needed, and you don't want to lose all the change
> you made.

It's possible to use a shell script to modify the output -- I've done
this with lex and yacc output.  But it's a pain, and if you're designing
the generator, there should be no need to.  If you need user specific
behavior (almost certainly the case when designing for persistence), the
obvious solution is to derive or use containment; don't put the behavior
in the generated class, but in the hand written one above it.

> Generation can be most probably made part of the make in your
> compiling environment (just make the generated module source code
> depend on the input file) and so there's no risk of forgetting to
> regenerate when you need.  I normally add something like

>     /**************************************
>     ****************************************
>     **                                    **
>     **              WARNING               **
>     **    Automatically generated code    **
>     **                                    **
>     **  Code generated by xyz.pl: do not  **
>     **  edit because any change will be   **
>     **  lost at next regeneration.        **
>     **  Modify generator instead.         **
>     **                                    **
>     ****************************************
>      **************************************/

> so there should be no risk of coworkers breaking things.

I'd have put this in my list of tips if you hadn't mentionned it.  It's
very essential.

> There's nothing that forces you to use ONLY the C++ compiler. IMO
> there are better tools than the C++ primitive preprocessor and the
> template machinery for this kind of use.

That's true, but it's also worth pointing out that with the correct set
of classes, C++ can behave very much like any number of langages.  When
I first started C++, my first classes were to give it AWK like
capabilities; I still use most of these classes regularly (although I've
replaced my String and AssocArray classes with std::string and
std::map).

> You can even generate multiple sources (for example for a C++ server
> and a Java client that need to talk).

That's the principle behind Corba, of course.

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply kanze 8/28/2003 8:04:07 PM

llewelly wrote:

> Markus Werle <numerical.simulation@web.de> writes:
> 
>  > Gabriel Dos Reis wrote:
>  >
>  >> Markus Werle <numerical.simulation@web.de> writes:
>  >>
>  >> [...]
>  >>
>  >> |  >> | The standard only requires 17 levels be supported.
>  >> |  >>
>  >> |  >> The standard does not require 17.
>  >> |  >
>  >> |  > No, it requires *at least* 17, sorry if that wasn't clear from
>  >> |  > the
>  >> |  >     following text which you snipped.
>  >> |
>  >> | Is there already a defect report about this?
>  >>
>  >> What would the defect be?
>  >
>  > The defect is that there _is_ a compiler limit at all.
>  > The computer should be the limit, not the language, right?
> 
> Note that I was wrong to think that the 17 limit in the appendix was
>      normative - it isn't.
> 
> Since the 17 isn't normative, we are back to Gaby's question - what
>      would the defect be?

Again: the defect is that there is a limit within the
(where's-the-difference-Gabriel) abstract machine. 
I cannot bear the fact that my code might not compile if I 
change platform, just because some artificial limit exists 
that is rather arbitrary and chooseable by the vendor. 

If _I_ choose to wait several days for the compiler to finish, 
why should anyone hinder this by some rule. 

Gabriel, what happens if I want the limit in gcc to be augmented 
beyond 500: Is it changing one line in the source code 
(#define MAXNUM_NESTED_TEMPLATE) or are there more implications?


Markus

-- 

Build your own Expression Template Library with Daixtrose!
Visit http://daixtrose.sourceforge.net/ 

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Markus 8/28/2003 8:31:45 PM

Markus Werle <numerical.simulation@web.de> writes:

[...]

| I cannot bear the fact that my code might not compile if I
| change platform, just because some artificial limit exists
| that is rather arbitrary and chooseable by the vendor.

Not all machines ae equal, there are differences and limits to what
can be done with one or the other.  That is a simple fact.

| If _I_ choose to wait several days for the compiler to finish,

sure, you can choose.  If it ever terminates.

| why should anyone hinder this by some rule.

Nobody is hinder anything.

| Gabriel, what happens if I want the limit in gcc to be augmented
| beyond 500: Is it changing one line in the source code
| (#define MAXNUM_NESTED_TEMPLATE) or are there more implications?

Since it an implementation-defined behaviour, it should be documented
in the companion documentation.  For GCC, you might want to look up
-ftemplate-depth=

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 8/29/2003 10:43:06 AM

Markus Werle <numerical.simulation@web.de> writes:

{excess quotes from earlier in thread snipped -mod}
 >
 > Again: the defect is that there is a limit within the
 > (where's-the-difference-Gabriel) abstract machine.
 > I cannot bear the fact that my code might not compile if I
 > change platform, just because some artificial limit exists
 > that is rather arbitrary and chooseable by the vendor.
 >
 > If _I_ choose to wait several days for the compiler to finish,
 > why should anyone hinder this by some rule.
 >
 > Gabriel, what happens if I want the limit in gcc to be augmented
 > beyond 500: Is it changing one line in the source code
 > (#define MAXNUM_NESTED_TEMPLATE) or are there more implications?
[snip]

It's passing a different commandline parameter, e.g.
     g++ -ftemplate-depth-10000 . I've no idea what the max is,
     however.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply llewelly 8/29/2003 11:03:00 AM

Markus Werle <numerical.simulation@web.de> wrote in message
news:<bil08j$ahreh$1@ID-153032.news.uni-berlin.de>...
> llewelly wrote:

> > Markus Werle <numerical.simulation@web.de> writes:

> >  > Gabriel Dos Reis wrote:

> >  >> Markus Werle <numerical.simulation@web.de> writes:

> >  >> [...]

> >  >> |  >> | The standard only requires 17 levels be supported.

> >  >> |  >> The standard does not require 17.

> >  >> |  > No, it requires *at least* 17, sorry if that wasn't clear
> >  >> |  > from the following text which you snipped.

> >  >> | Is there already a defect report about this?

> >  >> What would the defect be?

> >  > The defect is that there _is_ a compiler limit at all.
> >  > The computer should be the limit, not the language, right?

> > Note that I was wrong to think that the 17 limit in the appendix was
> >      normative - it isn't.

> > Since the 17 isn't normative, we are back to Gaby's question - what
> >      would the defect be?

> Again: the defect is that there is a limit within the
> (where's-the-difference-Gabriel) abstract machine.  I cannot bear the
> fact that my code might not compile if I change platform, just because
> some artificial limit exists that is rather arbitrary and chooseable
> by the vendor.

But that's always been the case, with every programming language which
has ever existed.  We tend to forget it today, because given the size of
modern machines, the limits are higher than anything we might actually
want.  Still, both Sun CC and g++ refuse to compile the following,
perfectly legal program:

limit.hh:

    #ifndef CNT
    #define CNT 10000
    #endif

    #if CNT != 0
    #include "limit.hh"
    #endif

limit.cc:

    #include "limit.hh"

Resource limits exist.  The standard says that exceeding the resource
limits of the system is undefined behavior -- in the case above, g++
actually gives an intelligent error message; Sun CC simply says that it
could not open the include file (doubtlessly because the system has no
more file descriptors, but the compiler doesn't tell me this).

Technically, the following shell script is a conforming C++ compiler:

    echo "Resource limits exceeded"

Of course, it would still be conforming regardless of the message.

When the C compiler was being written, this fact bothered some of the
authors, to the point that they introduced normative minimum limits,
with a statement that "The implementation shall be able to translate and
execute at least one program that contains at least one instance of
every one of the following limits:"  This didn't please everyone, of
course, particularly because it really doesn't buy you much.  The shell
script now becomes something like:

    if [ cmp $1 theOneProgramWeKnowHowToCompile.c ]
    then
        cp theOneProgramWeKnowHowToCompile.o ` basename $1 .c `.o
    else
        echo "Resource limits exceeded"
    fi

In addition, apparently, many C compilers took the limits as an absolute
value, probably with the idea that a program which respected them would
compile anywhere, where as a program which didn't wouldn't, and
signaling an error in case of non-portability was doing the programmer a
favor.

The contents of the C++ standard are a compromize between those who
wanted something like what was in the C standard, and those who didn't.
IIRC, it was one of the most difficult compromizes.

Annecdotally, in the pre-C standard days, I actually used a C compiler
which only allowed 100 cases in a switch.  It also took the fact that
exceeding resources is undefined behavior very literally: if there were
more than 100 cases, it handled the first 100 correctly, used the 101st
as a default, and ignored the rest.  With no diagnostic whatsoever.

I took me more than a week to track down why my code wasn't working.

As you can imagine, I'm not totally without sympathy for the people who
want the limits:-).

> If _I_ choose to wait several days for the compiler to finish, why
> should anyone hinder this by some rule.

The reason for limiting template recursion is simple: to detect endless
recursion.  When CFront was written, the authors chose 17; I don't know
the reasons for that particular number, but it was reasonable at the
time.  I imagine that most people would prefer a somewhat higher limit
today.  (Note that it is a similar artificial limit in g++ which allows
it to give an intelligible error message in my include example, above.)

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

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply kanze 8/29/2003 3:08:14 PM
comp.lang.c++.moderated 10596 articles. 7 followers. Post

34 Replies
112 Views

Similar Articles

[PageSpeed] 30

  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

pointer to SPECIALIZED member function template not legal c++ ?
Hi, the following code: template< typename objectT , typename worldT > void(objectT::* getInvocationFunctionFor( objectT* v ))(worldT&) { return &(objectT::custom_func/*<worldT>*/); } will work unless I activate the commented template arg. Only exception is VC++, but GCC 4.x and Comeau won't take it. I would like to know, whether there is a good reason for making this illegal and whether somebody knows a nice workaround. Or did I do something stupid here? Ingo On Oct 19, 2:29=A0pm, Ingo <Ingo.Nol...@recurdyn.de> wrote: > template< typename obje...

Is it legal for a POD-struct to have a member with pointer to member function type?
Consider this example: class B { public: void foo (); }; struct A { int i; typedef void (B::*pf) (); pf m_pf; }; Is 'A' a POD-struct? I cannot find anything in the standard that says that it shouldn't be. Regards, Richard -- Richard Corden [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.comeaucomputing.com/csc/f...

How to pass C++ member function to C function expecting function pointer?
I'm just starting to use C++, and don't want to have to rewrite all of the old C routines that I've been using for 20+ years. One of these is a general purpose function minimizer, which expects to be passed a pointer to the function to be minimized, double func(double p[]) How do I use this to minimize a function defined within a class in C+ +? To be specific, suppose I define the following class, which returns the sum of squared differences between an input vector and a (private) vector called trueParms: class max_func { public: max_func(vector <double> ...

Converting from C style struct offset to C++ style member pointer
When I get a struct offset from a C style API as int. I.e.: struct S { int I1; double D1; int I2; }; int offset = offsetof(S, I2); Now in C++ code I would like to convert this offset to a type safe C++ member pointer of type int S::*. Older gcc versions simply accepted a cast, newer version reject the cast. Marcel Hi Marcel % Marcel M�ller wrote: > When I get a struct offset from a C style API as int. I.e.: > > struct S > { int I1; > double D1; > int I2; > }; > > int offset = offsetof(S, I2); > > Now in C++ co...

C++ Templates
I'm writing a little framework for interface programming, where the interfaces are represented by template classes with modern features like properties � la C#. While these properties are member variables with Get and Set operations, it is the implementing class that shall handle these calls and hence I want Get and Set to be members of the class that implements the interface. The folowing code is an example what I want to achive (simplfied). First the interface class and then an example with a class that declares a property "time_pos". -------------- Begin code -------------- ...

Is this a legal C++ code?
Hi everyone, I originally implemented following code in Visual StudioC++ 2005 with SP1, it gets compiled and runs well. However when I try to compile it in VC++ 2005 without SP, the compiler compains about an internal error and stop the building process. I also tried to compile it in gcc, but I get a error message of: "error: no matching function for call to `for_each(__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, __gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string...

Is this legal C code?
I have the following code: A * F(B * x) { A * y = (A *) *x->data ; return y ; } Is this legal? Do you need more information about the details of the A and B structures in order to assess this? This is just the skeleton of some code (removing details irrelevant here) that I have. The code works as expected, but that return y ; line worries me. Will the value of y after F returns be as expected under all circumstances? Jim Ford wrote: > I have the following code: > > A * F(B * x) > { > A * y = (A *) *x->data ; > > return y ; > } > >...

Is this legal C++ code?
=============================== #include <iostream> template <class T> struct wrapped { wrapped(const T&) {} }; template <class T> wrapped<T> wrappit(const T& x) { return wrapped<T>(x); } template <class T> int run_function(const T& x, bool wrapped) { if (wrapped) { return 0; } else { return run_function(wrappit(x), true) + 1; } } int main() { std::cout << run_function(0.5, false) << std::endl; } =============================== It can never compile, but is it actually illegal according to t...

Passing a C++ object's member function to a C function expecing a function pointer!
Sounds nasty doesn't it!! Well it's kinda what I need to do! I have an external C struct (external to the C++ project/classes etc.) which is wants a function ptr assigned to one of it's members: struct blah { int (func_ptr*) (int a, int b, float c); }; etc... However, my code is in C++ and a wish to assign a non-static member function (I know I can do this) to this struct member! Can this be done!? Some how with pointers or references? What about the STL's mem_func stuff? Can anyone shed some light on this? Cheers Jim James, "James Vanns" <jimv@canterbury.a...

Fuction pointers
Can anyone tell me whether the following is legal C? int foo(int); int bar(int (*)(int)); int main(void) { int x; x = bar(&foo); return 0; } int bar(int (*foo)(int)) { /* ... */ } I had some similar code which compiled fine using 'gcc -Wall', but I'm concerned about what would happen if I called 'foo' from withing 'bar'. Would it use the pointer it is passed, or the function declared at the start, if they were different functions? Or is this undefined behaviour? What if I used the dereferencing operator when calling foo? I've changed the...

Legal pointer-to-member operations
Hello group, Should the program below be valid? Or should it generate a compilation error? Any references to the Standard would be appreciated... Thanks! #include <iostream> using namespace std; struct foo { int a; int b; }; template<typename T1, typename T2, typename T3> bool before(T2 T1::*mem1, T3 T1::*mem2) { return mem1 < mem2; } int main() { if (before(&foo::a, &foo::b)) cout << "foo::a comes before foo::b in memory" << endl; else cout << "foo::b comes before foo::a in memory" << endl;...

Pointer to member template. Is this legal?
template <class klass, class PointerToMemFunc, class PointerToMemFunc2, PointerToMemFunc, PointerToMemFunc2> class MyClass { klass * object_; }; This works and compiles. Now I would like to know if it's possible to do something in the lines of (which doesn't work as of now for me): template ... class MyClass { klass * object_; typedef decltype((object_->*PointerToMemberFunc)()) ReturnType; }; As you can see, there are two parameters that are called the same way. One of them is a pointer to member function type, the other is an address to one of t...

Pointer-to-member-function code okay?
I am compiling under Visual C++ 2005 Express (with the Platform SDK installed). I have a class that is responsible for creating and repeatedly running a Timeslice() method using a thread: class cProcessBlock : public cBase { public: . . . virtual void Timeslice(); // executed repeatedly by a 'while' loop in a thread }; I also declare a function pointer typedef to handle cProcessBlock callbacks: typedef void (cProcessBlock::*PortCallbackFnPtr)(shared_ptr<cBase>); cProcessBlock has a descendant, cPort that registers callback methods (in an STL map) and is responsible...

simplifying c code with function pointers
I love this place. This one problem keeps coming back to bite me. Suppose I have the following situation (actually I do). func1() { codeA somefunc1() codeB } func2() { codeA somefunc2() codeB } func3() { codeA somefunc3() codeB } I'm trying to follow the DRY school of thought and simplify this down to one function. Sometimes I just use macros, but it's just awful. Then I got to thinking, gee if only c had closures. Well I did some searching, and according to wikipedia, you can simulate closures with just a function pointer that takes a void po...

legal C++ code (use of templates with parameters)?
A question on C++: Is the following legal C++ code? typedef int (*func)(int); template <class A> class D1 { public: template <class B> func f(void) { return A::some_func<B>; } }; template <class A1, class B1> func g(void) { return A1::m1<B1>; } g++ (4.4.1) would not compile this code, with error /tmp/t.cpp: In member function =91int (* D1<A>::f())(int)=92: /tmp/t.cpp:12: error: expected primary-expression before =91>=92 token /tmp/t.cpp:12: error: expected primary-expression before =91;=92...

copy derived structure, is it legal c++ code?
Hi, I am trying to copy some variables from a struct to a derived struct. If I have something like, .... struct STRUCTA { int numA; long numB; float numC; } struct STRUCTB public STRUCTA { int numD; } .... STRUCTA structA = {0,1,2}; STRUCTB structB; memcpy( &structB, &structA, sizeof( STRUCTA) ); .... // Is the above code legal to copy the structure from structA to structB Thanks F. FFMG schrieb: > I am trying to copy some variables from a struct to a derived struct. > If I have something like, > ... > struct STRUCTA > { > int numA; > long numB; > ...

is this code legal w.r.t. C standard ?
Hi , is this code legal w.r.t. C standard ? Kindly also consider C99 and C0x standard also func( ) { /* certain statements - A*/ if ( condition - 1) { /* certain statements - B */ } else if ( condition - 2) { if ( condition ) { /* certain statements - C*/ } int * ptr = malloc( 4 ); // Can we delarecalre variable here *ptr = 10; printf( " value at *ptr = %d \n",*ptr); } else { /* certain statements - D */ } return ; } ...

C++ member pointers and anonymous structs/unions broken?
Hi, The program below stores the 5 unsigned ints a, b, c, x and y in an anonymous union, so that they share storage space with state[]. Additionally x and y share storage space with nums[]. The main function displays the address of each of the 5 integers twice, first using the member pointer table "members" and then using an instance of myclass. The results are surprising: the values for x and y are incorrect when using the member pointers. laptop:~/scratch> g++ -W -Wall foo.cc -o foo laptop:~/scratch> ./foo a -> 0x8049718 0x8049718 b -> 0x804971c 0x804971c x -> 0x8...

Allowing function pointer code to work on a member function
Hi all I have a conundrum that is puzzling me. I have a large codebase in C that I am converting to C++ as fast as possible (i.e. slowly because I keep learning new idioms and stumbling with C++ 'features'). One part of the C code is some optimisation functions that expect a pointer to a function which is sent an array of doubles and returns a double i.e. simplified.. void optimise( double (*funk)( double* ) ); I now have a bunch of classes with member functions which also take double* and return double that I want to use in this optimiser, but the compiler won't let me be...

Weird Pointer In C, Please Help. Code supply...
//Working Example: #include <stdio.h> #include <time.h> int main () { time_t rawtime; /* define rawtime as time_t */ time ( &rawtime ); printf ( "Current date and time are: %s", ctime (&rawtime) ); /*call ctime use &rawtime*/ return 0; } //Not Working Example: #include <stdio.h> #include <time.h> int main () { time_t *rawtime; /* define rawtime as pointer point to time_t */ time ( rawtime ); printf ( "Current date and time are: %s", ctime (rawtime) ); /* call ctime use rawtime */ return 0; } it's very ...

full source code for an atomic c++ smart pointer prototype...
Here are the pre-alpha code downloads: http://appcore.home.comcast.net/vzoom/refcount/ Here is some pre-alpha documentation: http://appcore.home.comcast.net/vzoom/refcount/doc/ http://appcore.home.comcast.net/vzdoc/atomic/static-init/ This pointer abstraction is atomically thread-safe... Please note that this is different than the "current" shared_ptr algorithm. It's not atomic wrt strong competing accesses... That is, a thread has to own a reference to a shared data-structure before it can try to acquire another one. This restriction does not apply to the prototyped algo...

c++-faq-lite
Hi, in this FAQ (http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.7) an example is given of how to 'use' a pointer to a member function. I have trouble even implementing a subset of it: --------- Fredmain.cpp ------------ #include "Fred.h" typedef int (Fred::*FredMemFn)(char x, float y); int main() { FredMemFn p = &Fred::f; } -------------------------------------------- ---------------- Fred.h ------------------ class Fred { public: Fred(); ~Fred(); int f(char x, float y); }; -------------------------------------------...

Call to static member function through a 0-pointer of instance: legal
Given the definition of Foo: class Foo { public: static int fnStatic() { // no access to class members return 0; } int fnObject() { // no access to class members return 1; } private: int i_; }; Is the following well defined by the standard: int useFoo() { Foo* foo = 0; int s = foo->fnStatic(); int o = foo->fnObject(); return s + o; } Under g++ 3.3 it works, and I can rationalize why it does. I've found the situation while chasing a core-dump in a non-static class member function, exactly at the first acc...

Mixing C WINAPI code with classes. Need a pointer back to my class from CreateWindow
Hello In a class I am calling Createwindow etc to create a window. Then I have a callback function which handles user actions. I want to pass the this pointer from the class somehow when I create the window so that the callback function can then call a class member function. I see in WNDCLASSEX there is a value cbClsExtra and cbWndExtra. Can I store the pointer in there? What is the best way to do this? Also how do I then extract the pointer in my callback function? Angus Comber angus@NOSPAMiteloffice.com "Angus Comber" <angus@NOiteloffice.com.PLEASENOSPAM...