Re: private destructor and templates
I'm passing information between threads (one managed, one not) and if
something gets mixed up so there are still messages in flight
(PostMessage) when I call DestroyWindow, I'd like to not lose anything
more than just leaking a small buffer object (up to 200 bytes) on the
heap. Since the .NET gc can't track pointers inside message queues, this
is how I've chosen to do it.
That is in violation of the docs for PostMessage:
"If you send a message in the range below WM_USER to the asynchronous
message functions (PostMessage, SendNotifyMessage, and
SendMessageCallback), its message parameters cannot include pointers.
Otherwise, the operation will fail. The functions will return before the
receiving thread has had a chance to process the message and the sender
will free the memory before it is used."
My message isn't below WM_USER. It is however, exactly equal to WM_USER,
which raises the concern that some other app might also use it, and might
not be careful where it sends messages.
In other words, you shouldn't fire off pointers to a window and expect the
window to delete them. Instead, you should use SendMessage, and delete
them yourself. This then avoids the whole issue.
Since I'm implementing a user message where I control both ends, having the
window delete the pointers is completely feasible. SendMessage would not
be, since it would block my worker thread.
Incidentally, this is why it's very important to me to avoid virtual
calls to anything. Anyone could drop messages into my queue with an
arbitrary LPARAM.
I don't understand that.
(*(LPFUNCTION)lParam)() or ((CSomething*)lParam)->method() with method being
virtual, is a huge security hole.
((CSomething*)lParam)->method() where method is non-virtual is quite safe
however, provided method doesn't implicitly trust its this pointer. Since I
am only reading from the structure and have that wrapped in an SEH block, I
think I'm ok. The idea of freeing that pointer still troubles me somewhat.
A message authentication code of some type might be in order.
Toward that end, is it possible to filter WM_TIMER messages from being
passed to DispatchMessage in a .NET app?
Sorry, I've no .NET expertise.
The issue is that DispatchMessage handles WM_TIMER in exactly the broken
method described above.
I don't want the compiler to generate a
destructor for the base class,
But you've written a destructor - it even does something (calls
FreeAgent();).
Sorry, I meant I didn't want the compiler to generate destructors for the
derived classes.
Ahh, ok.
I won't declare any variables on the stack
and I will use the base Destroy function to deallocate it.
If you won't declare any variables on the stack, just drop your
declaration of a destructor - it isn't needed. Instead, to prevent
accidental external delete calls, you could declare a class operator new
public and operator delete protected, which shouldn't affect your POD
Sadly, protected operator delete causes a compile error at every use of
operator new.
I think this is in case a constructor throws -- the instance isn't
constructed at that point, so the destructor needn't be accessible. But
operator delete needs to be. (/me frowns)
Actually that is it, because marking derived constructors nothrow with
throw() makes the error go away.
Ahh, yes. I didn't realise the derived classes have destructors (which is
yet another violation of the requirements on POD data).
I made operator delete protected before deleting the private destructor,
which certainly contributed to the problem. But all of my constructors
needed to be declared non-throwing anyway.
That is problematic, since your destructor isn't virtual. You can't
destroy an object through a base class pointer unless it has a virtual
destructor.
If all derived types just add additional POD fields, then I wouldn't need
to destroy it virtually.
Calling delete with the wrong type is illegal C++, unless the destructor
is virtual. It happens to work on some compilers and versions, but not
necessarily all, since the compiler is at liberty to use the type of the
deleted object to determine the size of the allocation that created it.
Also, a debugging implementation might check that constructed objects have
their destructors run.
Based on what you've said, the easiest option would be to stop using
PostMessage and instead destroy messages at the sending site. If you
Can't do that, the message passing vs remote procedure call distinction is
important here.
can't do that, you are probably best off moving to using real POD objects,
dropping your use of new and delete expressions, and using ::operator new
and ::operator delete (or malloc and free), which work
I'd defined my own operator new and operator delete in the base class as
you'll recall. I had used
static void* operator new(size_t bytes)
{
return new char[bytes];
}
static void operator delete(void* p)
{
delete [] p;
}
I'll go ahead and change these to call malloc and free. Would that be legal
then?
Some derived classes do override operator new with a placement parameter
indicating the size of an variably-sized buffer. They delegate to the base
class operator new after adjusting the size of the allocation. Is that also
highly suspect?
fine with raw memory, and don't care about pointer types or destructors.
If you want more standards compliant code, you could replace constructors
with initialization functions, and drop inheritence entirely (making your
Destroy function a free function).
I could do that by making the first member of each structure an instance of
what's currently the base class, in the same fashion that the Windows API
does structure polymorphism. But what would that change, besides having to
explicitly specify the name of that structure to use its members?
I take it you are suggesting allocating structures with
(derived_type*) base_type::Alloc(sizeof derived_type + extra_buffer_bytes)
It seems to me that you're conflating OO and C style programming in an
unnecessary and confusing way.
Would you prefer I use a POD union? That has really bad locality of
definition which translates into unmaintainability.
C style programming can be object oriented, and C++ can be procedural.
Really C++ is just a lot of syntactic sugar on top of C, plus some really
nifty things like templates.
I find it really handy to have a polymorphic set of structures that share
the initial few members and then each add several more. This is possible in
C, but really ugly. Take a look at any code using BITMAPCOREHEADER and it's
derivatives BITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADER in the context
of BITMAPINFO and you'll see the ugliness I'm trying to avoid.
I'm sorry to hear that what I'm doing is broken, because maintaining
duplicate code ala BITMAP*HEADER isn't very appealing (did we really need
four different declarations of the width member with four different names?).
Tom