dimanche 22 avril 2018

Reference member variable memory size optimization [duplicate]

This question already has an answer here:

I've encountered interesting issue doing homework assignment for implementing collections with STL-like iterators. Here's minimal example:

class const_iterator {
public:
  const int* const_p = new int();

  const int& operator*()
  {
     return *const_p;
  }
};

class iterator : public const_iterator
{
public:
  int*& p = const_cast<int*&>(const_iterator::const_p);

  int& operator*()
{
  return *p;
  //return const_cast<int&>(*const_iterator::const_p); //-alt solution, no reference member
  }
}; 

It was my understanding that references are a kind of "syntactic sugar" for a programmer - they work like "aliases", take no memory if necessary, and get optimized out. However, running sizeof() it turns out base class takes 4 bytes, and derived iterator - 8 bytes.

Fiddling some more, I've found that reference members always take 4 bytes. Even if - as in this case - they point directly to a member of base class. I don't see a reason why compiler would keep them as a pointer here? If we can access this reference than surely we can access the object it's refering to?

Furthermore, references declared as local variables in function scope also add additional instructions in the disassembly - that was obviously inspected without any optimizations and all debug symbols included. Do those get optimized away in Release builds?

int main() {
    auto& amIAnAliasOrDoIExist(Long::Qualified::Very<Nasty>.Name); 
    return amIAnAliasOrDoIExist; 
}

Is reference ever a "pure alias" (taking no memory in stack/heap)? Under what circumstance can compiler optimize reference variable in such a way? What does standard have to say about it?

Also, since declaring such reference member wastes space (in my homework), is there any performance hit with doing const_casts at every call to operator*()?

Aucun commentaire:

Enregistrer un commentaire