5
  • Does casting a pointer to an instance of a dervived class to the instances base class have any run-time overhead in C++, or is it resolved at compile-time?

  • If it does have any, what exactly has to be computed in the casting operation?

Example:

class Foo;
class Bar : public Foo;

Bar* y = new Bar;
Foo* x = (Foo*) y;

(I know I should use C++-style casts and that the answer is probably the same for them)

4 Answers4

6

Yes, though it's negligible.

In this case, a C-Style cast is interpreted as a static_cast, which may incur a pointer adjustment.

struct Base {};

struct Derived: Base { virtual ~Derived(); } // note: introduced a virtual method

int main()
{
  Derived derived;
  Base* b = &derived;
  Derived* d = (Derived*) b;

  void* pb = b;
  void* pd = d;

  printf("%p %p", pb, pd);

  return 0;
}

This overhead happens whenever the base subobject is not aligned at the same address that the derived object, which happens when:

  • introducing the first virtual method
  • using multi-inheritance

Of course, pointer adjustment is usually counted as negligible, and the compiler shall be smart enough to eliminate it if it's unnecessary anyway (an adjustment of 0).

Note: this is implementation dependent, not mandated by the standard

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
5
Foo* x = (Foo*) y;

You don't need to cast Bar* to Foo*. Casting from Derived to Base is implicit:

Foo* x = y ; // is enough!

As for polymorphic cast, C-style cast is not equivalent to dynamic_cast. C++ dynamic_cast is completely a new feature added to the language, and has no match in C-style cast.

Does casting a pointer to an instance of a dervived class to the instances base class have any run-time overhead in C++, or is it resolved at compile-time?

Casting from derived to base is resolved at compile-time, if you do as I did above. So it has not runtime overhead.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
3

C casts have no runtime overhead whatsoever. The only cast operation which creates runtime overhead is dynamic_cast<>() as it checks runtime type information.

hkaiser
  • 11,403
  • 1
  • 30
  • 35
  • Are you sure this (i.e. "no runtime overhead") is true even in the case of multiple inheritance? – Oliver Charlesworth Feb 23 '11 at 15:12
  • @Oli: Yes, since only `dynamic_cast` can cast _across_ a multiple inheritance class lattice. `static_cast` can only cast up and down the lattice. – James McNellis Feb 23 '11 at 15:14
  • @James: I very rarely (i.e. basically never) use MI. Are you saying that if `C` derives from `A` and `B`, you can't do e.g. `A *p = new C;`? – Oliver Charlesworth Feb 23 '11 at 15:16
  • @Oli: No, you can do that: you can convert from a `Derived*` to a `Base*` (if the base class is accessible, at least). That conversion only casts up the inheritance lattice. You can't do `A* p; B* q = static_cast(p);` because that would cast _across_ the lattice. You would have to use a pair of `static_cast` casts to convert the `A*` to a `C*` to a `B*`. – James McNellis Feb 23 '11 at 15:18
  • 1
    @James: That's what I thought! Then I think my (implied) original point still stands: Up-casting in multiple inheritance requires a small amount of pointer arithmetic, and so isn't zero overhead. – Oliver Charlesworth Feb 23 '11 at 15:22
  • 1
    @Oli: Oh, well, yes, it depends on the definition of "overhead." By that definition, even `int i = 42; (double)i;` has overhead because the CPU has to convert an `int` to a `double`. I think the usual meaning of "runtime overhead" when discussing casts is "requires some kind of type lookup." – James McNellis Feb 23 '11 at 15:25
1

See the answer to a similar question: regular cast vs static cast vs dynamic cast

Summarized: a C-style cast has no run-time overhead as it tries a bunch of C++ casting methods except dynamic_cast (which incurs a run-time penalty).

Community
  • 1
  • 1
Andrew
  • 738
  • 5
  • 8