Michael
Michael

Reputation: 5939

Does the size of vptr on 64-bit machines **has** to be 64 bits?

I'm curious why the size of vptr seems to take 64 bits on 64 bit machines and whether C++ actually require that.

All vptr need to do is to point to vtables, and since vtables cannot take too much memory and can be grouped together 32 bits ought to be more than enough to address them.

How many classes do you have in your program? 1000? 10000? How many virtual functions they have on average? Maybe 100? If the compiler+linker would place all vtables consecutively they cannot take more than a few MB. Addressing the specific vtable with a 32 bit index into the "array of all vtables" should work.

The reason I'm even talking about that is because of certain small classes with virtual functions; sometimes I see a huge arrays of objects of a class with just 2 words + vptr, and that 64-bit vptr has significant impact on memory usage.

Upvotes: 3

Views: 959

Answers (2)

geza
geza

Reputation: 29970

No, it doesn't have to be 64-bit. But, there are several reasons that it is:

  • There are a possibility, that the first member of the class needs a 64-bit alignment, so there is no benefit in this case
  • Usually, vptrs don't take significant memory
  • And the strongest argument: if vptr would be a 32-bit index, then all virtual function calls will be slower (because of the extra memory reference), and would generate larger code. This simply doesn't worth it.

Note, there is a memory model (ILP32, -mx32 switch for gcc), which is rarely used, where pointers are 32-bits, but 64-bit registers can be used.

Micro-optimizing for memory is not in focus nowadays. For example, the compiler is free to reorder members across access specifiers (so padding could be decreased), but no compiler known by me does this.

Upvotes: 3

MSalters
MSalters

Reputation: 179981

Your suspicion is right, that is indeed allowed by C++. 16 bits might not be realistic, though. And even if all vtables were bigger than 4 GB, they typically wouldn't be 4 billion entries big. A typical stable entry would be 64 bits, so 4 billion entries would take 32 GB.

Upvotes: 1

Related Questions