Can storage for references inside a C++ class be optimized away?

182 views Asked by At

Does the C++ language allow the following code to print e.g. 1 instead of 16? According to other answers I would guess yes but this case specifically doesn't seem to have been covered.

#include "iostream"
#include "cstdlib"
using namespace std;

struct as_array {
    double &a, &b;

    as_array(double& A, double& B)
        : a(A), b(B) {}

    double& operator[](const int i) {
        switch (i) {
        case 0:
            return this->a;
            break;
        case 1:
            return this->b;
            break;
        default:
            abort();
        }
    }
};

int main() {
    cout << sizeof(as_array) << endl;
}
3

There are 3 answers

0
M.M On BEST ANSWER

The Standard says under [dcl.ref]:

It is unspecified whether or not a reference requires storage

Also it is up to the compiler to decide what the size of an object is, so you could get any non-zero number here.

There is also the as-if rule (aka. permission to optimize). So it would be legal for the compiler to use storage for these references if and only if the way the references were used required it.

Having said all that; in the interests of having a stable ABI I would still expect that a compiler assigns storage to these references.

0
Tony Delroy On

The way the compiler implements reference behaviours - including where and how they're stored - is not specified in the C++ Standard. Consequently, some compiler could "print e.g. 1 instead of 16" as you ask.

Separately, you don't need to break after returning.

2
Klaus On

I believe that

cout << sizeof(as_array) << endl;

always returns the required storage for two pointers to double on the given machine, maybe extended with gaps to fulfill packing rules. Optimizing did mot mean to reduce the size of the storage of given data structures. Instead the compiler can optimize your code completely away in a real world scenario. So if you have the code:

double a=100;
double b=200;
as_array arr(&a, &b);
std::cout << arr[0] << std::endl;

can result in optimizing the storage for the struct completely away, because the compiler knows how the values are handled through your code. But the print out of sizeof(arr) still give you the theoretical size of the struct.

Anyway: If you want to get better optimizing results, you should write better code! Make methods const if they are const! If you use c++11 use constexpr if possible.