I like the top answer in

Both are unsafe casts and could hit run time errors, but RC is more unsafe. RC turns off compiler error checking, so you are on your own in the dark forest.

I feel RC is the last resort, when you have control on the bit representation of raw data , with documented assurance this bit representation won’t change.

In a real example — a raw byte array comes in as a char array, and you RC it into (pointer to) a packed struct. The compiler has no reason to believe the char array can be interpreted as that struct, so it skips all safety checks. If the raw data somehow changes you get a undefined behavior at run time. In this case SC is illegal — will not pass compiler.


reinterpret_cast{int}( somePtr): practical use shows a real use case of reinterpret_cast from pointer to integer, and reinterpret_cast back to pointer.

What if I serialized an object to xml and the object contains a pointer field (reference field is less common but possible)? Boost::serialization would unwrap the pointer and serialize the pointee object.

MyType a=77 what if conversion constructor is explicit


  explict MyType(int); // would disallow
  MyType a = 77; has a solution:

  MyType a = (MyType) 77; // Static cast would invoke the explicit conversion constructor!

Most custom types should make conversion constructors explicit to avoid hidden bugs, but smart pointer need an implicit conversion constructor, to support

  SmartPtr<int> myPtr = new int(77);

–A real example from CFM quant code

 FwdCurve::const_iterator iter = find( key ); //non-const itr

 QL_ASSERT( iter != ((FwdCurve * const) this)->end(), "not found" ); // original code probably before "explicit". 

// I had to change it to
 FwdCurve_iterator endItr = ((FwdCurve * const) this)->end();
 QL_ASSERT( iter != FwdCurve_const_iterator(endItr), "not found" ); //call the conversion ctor explicitly

[[safeC++]] discourages implicit conversion via OOC/cvctor

See other posts about OOC and cvctor. I am now convinced by [[safeC++]] that it’s better to avoid both. Instead, Use AsXXX() method if converting from YYY to XXX is needed. Reason is type safety. In an assignment (including function input/output), it is slightly hacky if LHS is NOT a base type of RHS. Implicit conversion is like Subversion of compiler’s type enforcement — Given a function declared as f(XXX), it should ideally be illegal to pass in a YYY. However, The implicit converters break the clean rule, from the back door.

As explained concisely on P8 [[safeC++]], The OOC is provided specifically to support implicit conversion. In comparison, The cvctor is more likely to be a careless mistake if without “explicit”.

Favor explicit conversion rather than implicit conversion. Some manager in Millennium pointed out that c++ syntax has too many back doors and is too “implicit”. Reading a piece of code you don’t know what it does, unless you have lots of experience/knowledge about all the “back-doors”.

why dynamic_cast returns NULL on pointers shows that dynamic_cast of a pointer returns NULL upon failure. Why not throw exception?

A: for efficient test-down-cast. dynamic_cast is the only solution. If it throws exception, the test would have to incur the cost of try/catch.

See P59 [[beyond c++ standard lib]]

10 implicit translations by c++ compiler

See also posts on the “same” topic.

Note many inefficient implicit conversions are selectively, optionally “optimized away” by various compiler options. This adds even more complexity.

# proxy classes (like in [[more effC++]]) rely heavily on implicit translations
# smart pointer are drop-in replacement for raw pointers, and always relies on implicit compiler translations.
# “–any literal string–” anywhere in source code is implicitly converted to a char*const
# unnamed temporary object creation by compiler. [[more eff c++]]
# [[c++ primer]] here are 3 identical func declarations because all array params are implicitly converted to ptr param. This is still very relevant because arrays are far more widely used than vectors (C is widespread) —
  void f(int * )
  void f(int[] )
  void f(int[5] )

#51 [[effC++]] Item 19 points out that if your Rational class overloads operator* with a Rational argument, then “aRational * 2” still works because compiler converts it first into
  aRational.operator*(2); // then it needs to convert 2 to a Rational object, so it converts the call into

  const Rational temp(2);

#50) if f() declares a param of type Animal, you can pass in a Shape variable, if there’s a converter. (See effC++ Item 26). Applies to any LHS=RHS expression like

** Type5 var2 = var3ofUnrelatedType // you get either a Type5 conversion ctor or a conversion method in UnrelatedType, 

#10) overloading the arrow operator ie “->”. See P19/23 [[boost]]. IBM explains — The statement x->f() is interpreted as (x.operator->())->f()

smart pointer casts – using shared_ptr for illustration

Smart pointers are the infrastructure of infrastructures for a quant library.

Minor performance issues become performance critical in this foundation component. One example is the allocation of the reference count. Another example is the concurrent update of the reference count. But here my focus is yet another performance issue — the lowly pointer-cast. (I don’t remember why performance is a problem … but I believe it is.)

C++ support 4 specific casts but smart pointers need to -efficiently- implement const_cast and dynamic_cast, in addition to the implicit upcast.

Q1: why can’t I assign a smartPtr-of-int instance to a variable declared as smartPtr of Dog?
A: compiler remembers the type of each pointer variable.

Q2: in that case, should c++ compiler allow me to assign a SP-of-Derived instance to a variable declared as SP of Base?
%%A: I don’t think so. I don’t think every smart pointer automatically supports upcast, but boost shared_ptr does, by design. See below.

For Boost, a Barcap expert said there’s an implicit cast from shared_ptr of T (RHS) to (LHS) shared_ptr of const T. See the special casting methods in

Specifically, boost says shared_ptr can be implicitly converted to shared_ptr whenever T* can be implicitly converted to U*. This mimics the behavior of raw pointers. In particular, shared_ptr is implicitly convertible to shared_ptr (i.e. add constness), to shared_ptr where U is an public/protected base of T (i.e. upcast), and to shared_ptr.I believe this is the same “member template” magic in the smart pointer chapter of [[more effC++]]

Allow me to explain the basics — in basic C++, a raw-ptr-to-T instance can be assigned to these variables —
T const *  my_ptr_to_const_T;
U * my_ptr_to_a_T_parent_class_U;
void * my_ptr_to_void;

Therefore a raw ptr supports these 3 (among others) casts implicitly. So does shared_ptr.

clever use of enum(char?) in demanding c++ app

class Der: public Base {…..}

Requirement — we need to down cast a Base pointer. dynamic_cast has overhead.

Der* returnVal = static_cast (new Base) // will compile but is potentially disastrous, because the returnVal can be a partially wild pointer.

Q: without incurring the overhead of vtbl lookup, how do I decide if a pointer to Base given to me actually points to a Base or Der instance?

%%A: type_info still uses vtbl.
%%A: use a Base field to indicate the type. Both ctor will set the field, so the Der ctor will overwrite.
A: enum. If sizeof(aBase) is a tiny 2 bytes, then adding an enum field adds just 1 byte. Adding vptr would add 4 bytes. Big difference if we instantiate billions of this class. I guess enum can be configured to take 1 byte, but you can also use a char, which is always 1 byte.

user-defined implicit type conversion – uptake in C#

Q: in real c# applications, do folks really create user-defined conversion in their own classes? Is this a rarely “used” feature like java vararg, java nested interfaces, java annotations, java dynamic proxy..? By “rarely used” i mean java developers seldom _create_ such features in their classes, though they may use these features in “off-the-shelf” libraries.

A c# veteran answered — “It would likely be used primarily if you are creating an app framework ((library? not the same thing)), which occurs quite often still in each application silo .. We have a framework ((wrapping)) around Sql Server Analysis Services with Silverlight UI.  There are calculation engines which deal with Matrices and Vectors of data, so these types of structures would include some type conversion for the people using the framework.”

((everything in double paranthses are my annotations))