Boost logo

Boost :

From: Eugene Lazutkin (eugene.lazutkin_at_[hidden])
Date: 2003-07-18 13:36:03

I have a few comments in no particular order.

1) I cannot imaging someone programming in C++ and using "FILE*s,and file
descriptors" instead of iostream & Co. You've must be talking about
incomplete systems like embedded systems, which don't have complete standard
C++ library. Are there any real life examples for that? How frequent are

2) Windows handles are problem indeed because they are not covered by
standard libraries. MFC covers it but being a behemoth it is not suitable
for some applications. ATL is better but it doesn't address handle issue. A
lot of people and their grandma have created their own home-brewed handle

2a) You are not entirely correct in assumption that "Most Windows' handles
are actually void pointers". For years Microsoft uses so called "strict
definitions" by default (you have to switch to old mode explicitly). This is
relevant code from their headers for illustration purposes:

#ifndef NO_STRICT
#ifndef STRICT
#define STRICT 1
#endif /* NO_STRICT */
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct
name##__ *name
#define DECLARE_HANDLE(name) typedef HANDLE name

As you can see HANDLE is void* but almost all other handles declared using
DECLARE_HANDLE() macro, which makes them of different types. Notable
exception is HGDIOBJ, which is void* as well. The former was done to
facilitate inheritance-like relationship between generic GDI handle
(HGDIOBJ) and specialized GDI handles (HPEN, HBRUSH, HFONT, HRGN, and so on)
with C compiler.

2b) It appears to me that Windows handles and their profound importance are
quite unique. I never struggled with something like that on X Window, for
example. If this is the case, we are talking about platform-specific
solution. I am not sure Boost is right place for platform-specific
libraries. Of course, it is possible to make such library
platform-independent but is it going to be used outside of Windows world?

3) Necessity to call get() method every time you need to use handle is
cumbersome. That's why auto_ptr or any other smart pointers define
operator->() and operator*(). Instead of these operators smart_handle should
define operator Handle() (where Handle is underlying handle type).

4) Sometimes destruction of handles is more than a simple call to
one-argument procedure. Real example from Windows, which is encountered

HDC hDC = GetDC(hWindow);
// do some drawing...
ReleaseDC( hWindow, hDC );

In this example destruction (releasing) involves some kind of context
(window handle). Apparently it is not handled by proposed library.

5) While I frequently needed scoped handles, I never encountered real need
to have "weak" handles and reference-counted handles. When I wanted to do
something like that, I created object, which was handled by smart pointer of
some kind. Admittedly this is not light weight solution but it was never a
bottleneck in my projects. Scoped handles are used extensively a should be
as light weight as possible.



PS: Yeah, I am one of those poor guys, who wrote Windows handle wrappers for
themselves. If you want to take a look, I can send you a file.

"John Madsen" <johnmadsen_usenet_at_[hidden]> wrote in message
> Starting from the smart_ptr headers (shared, scoped, and weak), I've
> corresponding handle classes. The motivation is to provide RAII semantics
> handle based resources. Windows' HANDLEs, FILE*s, and file descriptors
are the
> most obvious examples.
> There are two main differences between the smart_handle and smart_ptr
> 1) Pointer specific features have been removed for smart_handle. Both
> implicit and explicit type coercion features are gone as are operators *
and ->.
> 2) Rather than taking the handle type as a template parameter,
> classes take a handle policy (or traits class or description class or
> the correct term is).
> (2) is designed to deal with the fact that the actual type of a handle
> uniquely identifies the handle type. Most Windows' handles are actually
> pointers, file descriptors are ints, etc. Because the smart_handle
> take a handle policy as a template parameter, smart_handles that are
> distinct types will be properly distinguished by the language's type
> For example, to define a scoped_handle for a Windows' file HANDLE you'd do
> following:
> struct win_file_handle {
> typedef HANDLE handle_type;
> static bool is_valid(handle_type h) { return h !=
> static void release(handle_type h) { if (is_valid(h))
::CloseHandle(h); }
> static handle_type default_value() { return INVALID_HANDLE_TYPE; }
> static bool equal(handle_type lhs, handle_type rhs) { return
lhs==rhs; }
> };
> typedef scoped_handle<win_file_handle> scoped_win_file_handle;
> This type would be unrelated to, for example, a Windows HBITMAP, although
> HANDLE and HBITMAP are void*s.
> To some degree, of course, the existing smart_ptr classes already provide
> of this functionality through their deleter object. However, I believe
> are significant advantages to having separate smart_handle classes:
> - Not all handles are pointers (e.g., file descriptors) and thus cannot be
> with smart_ptrs
> - Semantically, handles simply aren't pointers. E.g, the pointer
> operators make no sense for handles.
> - Otherwise incompatible handles may in fact be typedef'd to the same
thing -
> smart_handle makes these different types, smart_ptr does not.
> - smart_ptr provides pointer conversion semantics that are inappropriate
> handles
> - smart_ptr assumes that an invalid value is designated by 0 - this is not
> necessarily true for handles
> I've uploaded the implementation to the Yahoo group's file area as
> I've included a rudimentary test case for
> whose main goal is just to exercise all of the code.
> I'd certainly love to hear ideas, criticism, etc. and ultimately see this
> become part of boost.
> Thanks,
> John Madsen
> john at illura dot com.
> _______________________________________________
> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at