lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Fall through


From: Vadim Zeitlin
Subject: Re: [lmi] Fall through
Date: Fri, 11 Dec 2015 17:52:35 +0100

On Fri, 11 Dec 2015 15:23:49 +0000 Greg Chicares <address@hidden> wrote:

GC> >  I don't know of any tools flagging if/else-if chains without the final
GC> > else as an error
GC> 
GC> I'm really surprised.

 Notice that I don't claim that no such tools exist, but I definitely
didn't see this in any compiler nor static analysis tool I used so far
(although I typically don't use the latter with the strictest options as
they result in too much noise, so perhaps they can do it if configured).

GC> And what about the missing cases...exactly what falls through? For the
GC> inner if...else chain, we examine 'tn_range_types.hpp' and see
GC>   {int, double, calendar_date}
GC> so the inner chain is exhaustive, for now.

 Personally I would use boost::variant<int, double, calendar_date> and its
visitor function to ensure that it's exhaustive at compile-time.

GC> Therefore, we should replace
GC> the null else with at least a warning. As for the outer if...else chain,
GC> at the bottom of 'input.hpp' we see:
GC> 
GC>         z = exact_cast<ce_product_name         >(m); if(z) return z;
GC>         z = exact_cast<datum_string            >(m); if(z) return z;
GC>         z = reconstitutor<datum_sequence,Input>::reconstitute(m); if(z) 
return z;
GC>         z = reconstitutor<mc_enum_base  ,Input>::reconstitute(m); if(z) 
return z;
GC>         z = reconstitutor<tn_range_base ,Input>::reconstitute(m); if(z) 
return z;
GC> 
GC> and obviously 'ce_product_name' is missing. I believe we've mentioned
GC> that before on this mailing list, but we haven't fixed it, so we should
GC> at least mark it inline as a known defect.

 I'm not sure about this. The intention was clearly to use fallback
converter in this case, so there would only be a defect here if this
converter didn't behave correctly for ce_product_name.

GC> >  And while it's hard to do it in this particular case (it would be simpler
GC> > with C++11...), generally speaking I prefer using switch() to chains of
GC> > if() statements as you can rely on the compiler checking the completeness
GC> > for you as both clang and g++ will also warn you about the missing cases 
if
GC> > you switch over an enum. This still doesn't make C++ switch() as nice as
GC> > pattern matching in some other languages, but it gets a little bit closer
GC> > to it.
GC> 
GC> I'm not so fond of it because 'break' is normally wanted, but must be
GC> written explicitly.

 If the compiler warns you when it isn't, this is not a problem -- which is
why the clang warning with which I started this (sub)thread is so nice.

GC> I like the ternary operator best of all, in the limited cases where it's
GC> appropriate, e.g.:
GC> 
GC>     return
GC>           (PC_24 == pc) ? fe_fltprec
GC>         : (PC_53 == pc) ? fe_dblprec
GC>         : (PC_64 == pc) ? fe_ldblprec
GC>         : throw std::runtime_error("Failed to determine hardware 
precision.")
GC>         ;

 I would absolutely use a switch here with an enum containing PC_XX
constants to ensure that adding some new PC_128 would result in a
_compile_- rather than run-, time error. Of course, one doesn't prevent the
other and when using a compiler without support for -Wswitch-enum, such as
pre-historic versions of gcc, a run-time error would still be generated:

        e_ieee754_precision convert_precision(e_pc_nn pcnn)
        {
                switch (pcnn)
                        {
                        case e_PC_24: return fe_fltprec;
                        case e_PC_53: return fe_dblprec;
                        case e_PC_64: return fe_ldblprec;
                        }

                throw std::runtime_error("...");
        }

 In this particular case it's a bit stupid, of course, as you would need to
define another enum (e_pc_nn) first, so you don't really gain much. But if
an enum already exists, e.g. when doing something with e_ieee754_precision
values, writing a switch over it is definitely safer than using the ternary
operator.

 Regards,
VZ

reply via email to

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