On 26.11.2014 21:41 Steve Maas wrote:
> Okay, fair enough, users are responsible for deleting the objects
> they create. That makes sense, but two small comments:
>
> 1) The documentation does not reflect this (unless I missed it).
This is basic OOP knowledge, no need to say.
> In fact, the very first example in the online manual does not delete the
> window object. Neither does any of the test examples (unless I missed
> it) that dynamically allocates the main window.
You may like it or not, but this is "The FLTK Way". This has been
discussed many times before. Since FLTK has no knowledge how an object
has been created (new, local/automatic, static) FLTK _can not_ delete
objects (particularly Windows) when the program ends. There are usual
OOP mechanisms that work as everywhere (going out of scope calls the
d'tor), but for windows created with new there is no way for FLTK to
know when to delete them. And, to emphasize the 'L' in FLTK: FLTK is the
"Fast Light Tool Kit". Its philosophy is not to create bloat for
managing stuff that can be managed in user code. FLTK does not maintain
a list of window objects because it is not needed by FLTK. Only windows
that are shown are managed internally by FLTK.
> Consequently, users
> could easily get the impression that FLTK cleans up after itself (as so
> many other GUI toolkits do) which, as is now clear, is not the case.
Okay, that impression would be wrong as far as destructors are
concerned. However, it is often better NOT to call destructors at the
end of the program because this would take unnecessary long for no
effect. If you need d'tors you are free to do what you want to
guaranteee that they are called (and you should do that). Again: you are
responsible for the objects you created.
> 2) When you say "let the system clean up for you", you should clarify
> that the system in fact does not clean up for you. It does not call
> delete, or the destructors, or closes resources properly.
Be fair! I did exactly that: "As with all other objects you create
during the runtime of a program, you (the programmer) are responsible
for deleting the objects or you can let the system clean up for you. The
latter means that there will be no memory leaks unless you create
objects frequently and don't delete them, but if you require d'tors to
be called for cleanup tasks, then you must do this yourself. There's
nothing FLTK can do for you."
Please read the 2nd sentence of the cited paragrah again.
> As far as I
> understand, it just reclaims the resources in a rather brute force
> manner, which is definitely not something a developer should rely on as
> a mechanism to properly de-allocate resources.
Sorry, it is exactly that what has been said often before. We do not
recommend "reclaiming" all objects by calling all destructors at the end
of the program. That does not mean that YOU should not do it for objects
that are worth it, for instance if you have open files and such. But
that's a different story. Here is an example: we have to allocate font
structures so that text can be rendered during runtime. We do NOT free
font structures when the program terminates. All memory will be released
by the OS, unless documented otherwise. Sometimes we allocate memory for
something that will be used frequently during runtime. We do not release
this memory, because it will be reused later. free()ing and malloc()ing
(or delete and new) are just a waste of CPU cycles in this case. Hence
memory check programs will report a memory leak. We consider this a
false positive.
> Now, I'm sure you knew
> this, but what I'm saying is that I don't think this is a programming
> practice that should be promoted as it could very easily lead to
> problems. In my opinion, if FLTK is not going to provide an automatic
> clean up mechanism it should stick to good C++ programming practices
> through its documentation and examples. Sorry, I'm somewhat of a C++
> purist in that regard. But, of course, that's just my humble opinion.
You can be sure that we take care of deleting structures that are worth
it during runtime of the program. But we do deliberately not delete
objects before terminating the program, unless this is necessary or done
by automatic destructors. We consider memory leaks only if they increase
during runtime, but not if a memory resource is not free()d before
program exit. Whenever we get reports of memory leaks (usually created
by using valgrind or similar) we do check it and fix it, if it is a
memory leak. Really.
One last point to this "end of program" and cleanup discussion. FLTK
does not have the information when a program will be terminated. When
Fl::run() terminates this does not mean that the end of the program is
near. You can create new windows, call Fl::wait(), Fl::check(), another
instance of Fl::run(), call fl_ask() etc. and maybe run another instance
of a loop. You can even reuse a window that has been hidden and not
deleted before. There is no guaranteed "end of program" point that FLTK
could use to cleanup, not even atexit() will always work. So instead of
trying the impossible, FLTK is lightweight and leaves this up to the
programmer.
> Thanks to all for taking the time to respond!
You're welcome.