Search code examples
c++c++11reinterpret-cast

C++ Compiler behavior with re-interpreting template parameter constants


While working on an RAII-style guard object, I ended up encoding some of the guard state in a template parameter. This seems reasonable if, for instance, you want a recursive / nested guard object that's aware of how many levels deep it is but without space overhead (being pedantic, I know) or to eliminate some runtime overheads. This turned into an academic curiosity though...

Something like this would be an example:

template <unsigned depth>
class guard {
    unsigned get_depth() const {return depth;}
};

guard<2> g2;
std::cout << reinterpret_cast< guard<5>* >( &g2 )->get_depth(); // works? crazy? useful?

I cannot for the life of me think of a legitimate reason to do this, but it got me thinking if this is legal C++ and just how the compiler ought to handle something like this (if it can at all) or if it's just silly through and through.

I assume because the cast target needs to be known at compile time, that the relevant template is instantiated for the cast. Has anyone found something like this useful, assuming it does work and has uses at all, and if so where could this be utilized?

The general question I guess is can reinterpret_cast alter constant template parameters? If so is this just a type hack (for want of a better term) and g2 in this case would always return 2 (after casting)? Or should it return 5 (after casting)?


Solution

  • This is undefined but not because of the strict aliasing rule. The call to get_depth neither reads nor modifies the value of any object (a template non-type parameter isn't an object), so it doesn't access (as defined in [defns.access]) anything within the meaning of the strict aliasing rule.

    This is controlled instead by [class.mfct.non-static]/2:

    If a non-static member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined.