Sponsored By

In-depth: All the nuances of static_cast (and others)

In this reprinted <a href="http://altdevblogaday.com/">#altdevblogaday</a> in-depth piece, Crytek technical lead Jaewon Jung offers some clarifications on C++ cast operators, and several conclusions based on his analysis.

Game Developer, Staff

March 16, 2012

2 Min Read
Game Developer logo in a gray background | Game Developer

[In this reprinted #altdevblogaday in-depth piece, Crytek technical lead Jaewon Jung offers some clarifications on C++ cast operators, and several conclusions based on his analysis.] Recently I noticed my knowledge about C++ cast operators had been far from complete. For instance, I had thought static_cast is only for static upcasts (or downcasts also?) in an inheritance hierarchy. And for some legitimate casts between primitive types(like between int and float or between int and unsigned int), I used the C-style cast, still. I was not sure about how new cast operators are precisely mapped to the old C-style, either. So here is my shot at finally clarifying all these. Categories Errors possible

  • Es : compile error

  • Er: run-time check failure

    • an exception when casting a reference

    • returing nullptr when casting a pointer

  • Ec : run-time crash when using the converted

Conversions supported

  • Cprim: between primitive types : int <-> float, int <-> unsigned int

    • built-in conversion rules apply

  • pointer(reference) types

    • Cbase: pointer to a linearly related type(upcast/downcast) : CDerived* <-> CBased*

      • a proper pointer arithmetic applies if a multiple inheritance used

    • Cvoid : void pointer : void* <-> int*

    • Cconst : removing const/volatile type qualifiers : const int* <-> int*

    • Cetc : Any other cases : int* <-> float*

Casts static_cast<>

  • Cprim, Cbase, Cvoid

  • Es if Cconst, Cetc tried

  • A possible Ec if an invalid downcast tried e.g. CBase* pB = new CBase(); CDerived* pD = static_cast(pB);

reinterpret_cast<>

  • Cbase, Cvoid, Cetc

  • Es if Cprim, Cconst tried

  • A possible Ec if Cbase tried(because a proper point arithmetic isn't applied)

dynamic_cast<>

  • Cbase

  • Es if Cprim, Cvoid, Cconst, Cetc

  • A possible Er if a downcast of Cbase tried and its run-time check fails

const_cast<>

  • Cconst

  • Es if Cprim, Cbase, Cvoid, Cetc

C-style cast

  • A C-style cast is defined as the first of the following which succeeds:

    • const_cast

    • static_cast

    • static_cast, then const_cast

    • reinterpret_cast

    • reinterpret_cast, then const_cast

Conclusion

  • Never use the C-style cast any more. You can use one among (or an combo of) const_cast, static_cast, reinterpret_cast depending on your exact need at that time.

  • dynamic_cast is a complete new thing in C++ and use it sparingly since it has a run-time cost and a need for it might be a symptom of some bad underlying design(though this aspect of it has not been discussed in this article).

  • C++ is too deep (for a mere mortal to figure all its nooks and crannies).

References

[This piece was reprinted from #AltDevBlogADay, a shared blog initiative started by @mike_acton devoted to giving game developers of all disciplines a place to motivate each other to write regularly about their personal game development passions.]

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like