参考 - sizeof是否返回实际内存大小?

时间:2016-01-29 15:01:15

标签: c++ reference sizeof

我知道这个问题可能会以多种不同的方式提出,但我加入了自己的问题,因为这对我来说仍然不清楚。

考虑以下代码:

long double q = 1.2;
long double &p = q;
cout << sizeof(p) << endl;`

long double在我的机器上是12个字节,代码的输出符合预期12,因为标准说:

  

当应用于引用或引用类型时,结果为   引用类型的大小。 (ISO C ++ $ 5.3.3 / 2)

但是你很可能都知道,参考实现是免费的,因此,正如标准所说:

  

未指明引用是否需要存储(3.7)。

所以看来明天我可以提出我自己的引用实现,需要200个字节,并确保sizeof运算符返回正确的对象大小(而不是返回我的真实实现大小)参考)

所以我的问题实际上非常简单:

我们可以依赖sizeof运算符来返回包含类的实际内存占用,特别是引用成员吗?

3 个答案:

答案 0 :(得分:6)

比较和对比:

struct container {
  long double& dbl;
};

std::cout << sizeof(container::dbl) << '\n';
std::cout << sizeof(container)      << '\n';

Live on ideone

一行告诉您引用对象的大小。另一个告诉你包含引用的结构的大小。

这种行为不是偶然的。它是由标准定义的,是的,你可以依赖它。

这个问题背后似乎有一个假设,即带有引用或引用类型的sizeof运算符的行为在某种程度上是任意的和常规的。事实并非如此;它不符合通常适用于参考文献的相同逻辑。

如果我有

long double dbl;

然后在其范围内使用dbl是左值,也就是说引用。这是必要的,以便可以将值赋给dbl。因此,dbl的类型(例如decltype(dbl)所显示的)是long double&,而不是long double

sizeof(dbl)返回引用本身的大小而不是引用对象的大小是荒谬的。

一旦你将参考文献放入一个结构中,就会有一个完全不同的野兽。 作为对象的一部分,引用会占用空间,除非可以优化掉包含它的整个对象,否则无法对其进行优化。

答案 1 :(得分:0)

如果您怀疑是否可以依赖以下类型的sizeof

struct A
{
   int& r;
};

然后是 - 您可以在包含引用的结构中依赖sizeof

E.g。这段代码是安全的:

   char* buffer = new char[sizeof(A)];
   int value;
   A* valueRef = new (buffer) A{value};

缓冲区中有足够的字节来存储A对象。

答案 2 :(得分:0)

struct S {
    long double& d;
};

static_assert(sizeof(S::d) == sizeof(long double));
static_assert(sizeof(S) != sizeof(S::d));  // true on most platforms

编译器非常聪明,可以知道S的大小,它不会混淆并认为它是sizeof(S::d),因为那将是愚蠢的。