Johannes Schaub - litb Johannes Schaub - litb - 4 months ago 10
C++ Question

Weird use of `?:` in `typeid` code

In one of the projects I'm working on, I'm seeing this code

struct Base {
virtual ~Base() { }

struct ClassX {
bool isHoldingDerivedObj() const {
return typeid(1 ? *m_basePtr : *m_basePtr) == typeid(Derived);
Base *m_basePtr;

I have never seen
used like that. Why does it do that weird dance with
, instead of just doing
? Could there be any reason?
is a polymorphic class (with a virtual destructor).

EDIT: At another place of this code, I'm seeing this and it appears to be equivalently "superfluous"

template<typename T> T &nonnull(T &t) { return t; }

struct ClassY {
bool isHoldingDerivedObj() const {
return typeid(nonnull(*m_basePtr)) == typeid(Derived);
Base *m_basePtr;


I think it is an optimisation! A little known and rarely (you could say "never") used feature of typeid is that a null dereference of the argument of typeid throws an exception instead of the usual UB.

What? Are you serious? Are you drunk?

Indeed. Yes. No.

int *p = 0;
*p; // UB
typeid (*p); // throws

Yes, this is ugly, even by the C++ standard of language ugliness.

OTOH, this does not work anywhere inside the argument of typeid, so adding any clutter will cancel this "feature":

int *p = 0;
typeid(1 ? *p : *p); // UB
typeid(identity(*p)); // UB

For the record: I am not claiming in this message that automatic checking by the compiler that a pointer is not null before doing a dereference is necessarily a crazy thing. I am only saying that doing this check when the dereference is the immediate argument of typeid, and not elsewhere, is totally crazy. (Maybe is was a prank inserted in some draft, and never removed.)

For the record: I am not claiming in the previous "For the record" that it makes sense for the compiler to insert automatic checks that a pointer is not null, and to to throw an exception (as in Java) when a null is dereferenced: in general, throwing an exception on a null dereference is absurd. This is a programming error so an exception will not help. An assertion failure is called for.