casting - Why downcast and then assign to base-class in C++? -
i have stumbled upon following code structure , i'm wondering whether intentional or poor understanding of casting mechanisms:
struct abstractbase{ virtual void dothis(){ //basic implementation here. }; virtual void dothat()=0; }; struct deriveda: public abstractbase{ virtual void dothis(){ //other implementation here. }; virtual void dothat(){ // stuff here. }; }; // more derived classes similar structure.... // dubious stuff happening here: void strangestuff(abstractbase* pabstract, int switcher){ abstractbase* = null; switch(switcher){ case type_derived_a: // why use abstract base pointer here??? = dynamic_cast<deriveda*>(pabstract); a->dothis(); a->dothat(); break; // similar case statement other derived classes... } } // "main" deriveda* pderiveda = new deriveda; strangestuff( pderiveda, type_derived_a );
my guess is, dynamic_cast statement result of poor understanding , bad programming style in general (the whole way code works, feels painful me) , doesn't cause change in behaviour specific use case.
however, since i'm not expert on casting, i'd know whether there subtle side-effects i'm not aware of.
my guess coder screwed up.
a second guess skipped check a
being null in simplification.
a third, , highly unlikely possibility, coder exploiting undefined behavior optimize.
with code:
= dynamic_cast<deriveda*>(pabstract); a->dothis();
if a
not of type deriveda*
(or more derived), a->dothis()
undefined behavior. , if of type deriveda*
, dynamic_cast
absolutely nothing (guaranteed).
a compiler can, in theory, optimize out other possibility away, if did not change type of a
, , remain conforming behavior. if later checks if a
null, execution of undefined behavior on next line means compiler free not set a
null on dynamic_cast
line.
i doubt given compiler this, wrong.
there compilers detect paths cause undefined behavior (in future), eliminate such possibilities happening backwards in execution point undefined behavior have been set in motion, , "know" code in question cannot in state trigger undefined behavior. can use knowledge optimize code in question.
here example:
std::string foo( unsigned int x ) { std::string r; if (x == (unsigned)-1)) { r = "hello "; } int y = x; std::stringstream ss; ss << y; r += ss.str(); return r; }
the compiler can see y=x
line above. if x
overflow int, conversion y=x
undefined behavior. happens regardless of result of first branch.
in short, if first branch runs, undefined behavior result. , undefined behavior can anything, including time travel -- can go in time , prevent branch being taken.
so the
if (x == (unsigned)-1)) { r = "hello "; }
branch can eliminated optimizer, legally in c++.
while above toy case, gcc optimizations this. there flag tell not do.
(unsigned
-1
defined behavior, overflowing int
not, in c++. in practice, because there platforms in signed int overflow causes problems, , c++ doesn't want impose costs on them make conforming implementation.)
Comments
Post a Comment