lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Event handling modernization


From: Vadim Zeitlin
Subject: Re: [lmi] Event handling modernization
Date: Thu, 31 Mar 2016 01:55:48 +0200

On Wed, 30 Mar 2016 23:45:48 +0000 Greg Chicares <address@hidden> wrote:

GC> On 2014-11-30 01:04, Vadim Zeitlin wrote:
GC> [...]
GC> >  The 0002-Don-t-count-all-MDI-children-just-check-if-there-is-.patch one
GC> > addresses my urge to avoid performing unnecessary actions: we don't really
GC> > need the count of MDI children frame here at all, so why bother counting
GC> > all of them (even if "all" is probably virtually always just a few) when 
we
GC> > can stop after just the second one? Subsidiarily, why count them at all if
GC> > we don't have any active child anyhow.
GC> 
GC> This gives me pause:
GC> 
GC> 
http://docs.wxwidgets.org/trunk/classwx_m_d_i_parent_frame.html#a981df3eae1daa82772fe10e3bcba7215
GC> | virtual wxMDIChildFrame* wxMDIParentFrame::GetActiveChild() const
GC> | Returns a pointer to the active MDI child, if there is one.
GC> | If there are any children at all this function returns a non-NULL pointer.
GC> 
GC> I take "any...at all" to mean that if the parent frame has no MDI children,
GC> but does have a child window of some other type, then this function returns
GC> a non-NULL wxMDIChildFrame* that must point to an object that is not 
actually
GC> a wxMDIChildFrame.

 I'm really not sure how can the above be interpreted in this way, the
function declared as returning wxMDIChildFrame* definitely can't return a
(non-null) pointer to something that is not a wxMDIChildFrame. The text
above just emphasizes that if there are any [MDI; implicitly implied]
children, then one of them will be active, so there is no need to test that
it returns a non-null pointer if you know that any [MDI] children exist.

 I think it's reasonable to expect that wxWidgets at least tries to not
invoke undefined behaviour and any reasonable interpretation of the
documentation should be compatible with this general principle.

GC> Maybe I'm reading too much into this, but it worries me:
GC> wouldn't such a pointer be likely to be misused?

 To put it mildly, such pointer could *only* be misused, so there can be
absolutely no sane reason to ever return it and, of course, wxWidgets
doesn't do it.

GC> I'll just rule that out, at no real cost, thus:
GC>      wxMDIChildFrame* child_frame = frame_->GetActiveChild();
GC> -    if(child_frame)
GC> +    if(dynamic_cast<wxMDIChildFrame*>(child_frame))

 This dynamic_cast is totally unnecessary.

GC> Since I rewrote this in order to understand it, let me also ask...here:
GC> 
GC> 
https://github.com/vadz/lmi/commit/461ba86312ed5409237652d19309a3b8f28ddeaa.patch
GC> +        for(wxWindowList::const_iterator i = wl.begin(); i != wl.end(); 
++i)
GC> +            {
GC> +            wxMDIChildFrame* const child = 
dynamic_cast<wxMDIChildFrame*>(*i);
GC> +            if(child && child != child_frame)
GC> 
GC> Why
GC>   wxMDIChildFrame* const child // the thing-pointed-to cannot be changed
GC> instead of
GC>   wxMDIChildFrame const* child // the pointer cannot be changed
GC> ?

 Err, sorry, the comments are exchanged. In my code, it's the pointer that
is const and this indeed was a conscious and deliberate choice: I declare
all local variables that are not going to change "const" as I believe that
this helps a lot with reading and understanding the code. In fact, I'd go
as far as avoiding non-const local variables if it can be done without any
unreasonable contortions.

GC> Anyway, I'll commit
GC>   wxMDIChildFrame const*const child // nothing can be changed
GC> because I don't see any argument against it.

 True, wxMDIChildFrame itself could be const too, but it's all but hopeless
to work with "wxWindow const*" in wxWidgets API as almost all the functions
require non-const pointers, so I don't even try to do it any more.

 Regards,
VZ

reply via email to

[Prev in Thread] Current Thread [Next in Thread]