Re: Associating C++ new with constructor

Ross Boylan
2007-02-15T22:10:32Z

On Thu, 2007-02-15 at 22:29 +0200, Michael Veksler wrote:
> Ross Boylan wrote:
> ...
> > On Thu, Feb 15, 2007 at 03:35:14PM +0200, Michael Veksler wrote:
> >
> >> The idea is simple, and took me less than a day to implement:
> >> Define a template class that can monitor object creation and
> >> destruction.
> >> Insert a member of this type into all non-POD classes:
> >> class MyFoo {
> >> ....
> >> ....
> >> ...
> >> Count<MyFoo> m_count_for_MyFoo;
> >> };
> >>
> The difficulty with this, is that it will work reliably only for
> non-POD classes. For POD (Plain Old Data) classes or
> structs, you are not allowed to automatically modify them,
> because they might participate in code such as
> struct A {
> int a, b;
> };
> void Serialize(ostream & out, const A& a) {
> out.write(reinterpret_cast<const char*>(&a), sizeof(a));
> }
>
> This is well defined only if A is a POD, if you add a Count
> instance then the program becomes:
> 1. undefined
> 2. outputs wrong stuff to the stream.
I'm not following. Do you mean that the C++ standard doesn't like the
code, or just that streaming out (and back in) an arbitrary object (the
counter instance) is unlikely to work, along with any other operations
that treat A as a bucket of bits (e.g., memmove)?
....
> >> It is imperfect since it can't reliably detect all
> >> non-POD classes, and it does not work for std::***
> >> classes. To make it 100% reliable, I had to write
> >> a complete C++ parser!.
> >>
> >
> > Why isn't this reliable for all classes in your source code (at least
> > if you add a search for "struct")? Are you referring to cases that
> > use pre-processor magic, or is there something else?
> >
> Read my comment above about the importance of non-POD checks.
> There is no preprocessor magic, only a trivial perl script that inserts
> instances into non-POD classes. The inaccuracy comes from
>
> 1. It is difficult to find all definitions of all classes. You should
> ignore
> occurrences of the "class" word in strings and in /* */ comments.
> You should find "class" words expanded by some user macros.
That's what I meant by my reference to "preprocessor magic" above.
> This is virtually impossible to get right without at least running
> a preprocessor.
> 2. It is difficult to be certain that some class is a non-POD class,
> since its POD-ness depends also on its parents and members.
> Also, user's macros may hide stuff, like virtual methods.
> Templates make it even more difficult.
>
> I simply made some dumb assumptions in my script that all "class"
> definitions are non-POD (or at least never used as POD), and
> all "struct" definitions are suspected to be POD. Fortunately,
> this assumption is correct most of the time due to common
> coding conventions.
> > Another approach is in libcwd, which records the class along with the
> > memory allocation if you insert a call to AllocTag() after the call to
> > new. AllocTag uses templates under the hood to get the type of the
> > pointer automatically, and libcwd provides a macro NEW that will take
> > care of it automatically, e.g., A *pA = NEW(A()).
> >
> So you have to write your code this way, or write a preprocessor script
> to modify
>
> A *pA= new A(new B, new C[5]));
>
> to
>
> A *pA= NEW(NEW(B), NEW_ARRAY(C, 5));
Yes (I'm not sure above the array syntax either). Actually, nesting the
NEWs might blow up, since the macro expands to a couple of statements (I
think--I guess it could use a "," operator).
>
> (I just guess how new over an array are done, I don't really use libcwd).
> > This problem was driving me crazy enough that I was looking into
> > putting hooks in gcc, which has the advantage of providing a C++
> > parser. That approach has a few disadvantages. Aside from being a
> > big project (at least for someone like myself who knows little about
> > compilers), it would be impractical to redistribute.
> >
> I don't think there should be any problem to redistribute such a tool.
> I know of at least one such project.
If my instructions for building the test suite start with "build a
custom compiler with this patch set" that is likely to be off-putting.
In fact, it's off-putting for me :)

There's a project to make it easier to create addons to gcc (GEM), but
since it's not in the main distribution one has to build a custom
compiler to use an addon anyway.

--
Ross Boylan wk: (415) 514-8146
185 Berry St #5700 ross@biostat.ucsf.edu
Dept of Epidemiology and Biostatistics fax: (415) 514-8150
University of California, San Francisco
San Francisco, CA 94107-1739 hm: (415) 550-1062