C++强制转换内存分配

C++ cast memory allocation

本文关键字:内存 分配 转换 C++      更新时间:2023-10-16

我想知道以下操作是否会导致内存分配:

int x = 0;
long long y = x + 1;

如果是,是否有任何编译器优化可以实时处理这一问题,或者这是否会导致在添加之后进行独立的强制转换?

答案是:这取决于情况。如果程序的行为不依赖于它,则绝对没有要求编译器执行内存分配。特别是C++14 n3797 S1.9:

本国际标准中的语义描述定义了一个参数化的不确定性抽象机。本国际标准对一致性实施的结构没有提出任何要求。特别地,它们不需要复制或模拟抽象机器的结构。相反,需要一致的实现来模拟(仅)抽象机器的可观察行为,如下所述。

这一规定有时被称为"好像"规则,因为只要结果是遵守了该要求,只要可以从程序的可观察行为中确定,实施就可以自由无视本国际标准的任何要求。例如,如果可以的话,实际实现不需要计算表达式的一部分推断其值没有被使用,并且没有产生影响程序的可观察行为的副作用。

在这种情况下:

long long f() {
  int x = 0;
  long long y = x + 1;
  return y;
}

编译器可以完全自由地将此函数重写为:

long long f() {
  return 1;
}

在这样做的过程中,它可能只是将立即值加载到寄存器中,而根本不执行任何内存访问。根据调用上下文的不同,它甚至可以内联此函数,使其完全从视图中消失。

如果变量是函数内部的局部变量,那么编译器将确保堆栈上有足够的空间容纳它们。如果它们是全局变量,那么在可执行文件中将为变量保留空间,并且该空间将由操作系统的运行时加载程序"分配"。

没有动态内存分配正在进行,即堆上没有分配任何内存。空间是由编译器保留的,所以它已经由编译器"动态"处理了。

我不知道我是否完全理解你的问题,但我会尽我所能提供我的2美分。如果你不知道,初始化的方式是,不是最有效的方式这样做。例如:

int x = 0;

正在调用默认的int构造函数,该构造函数使用默认分配器-在数据段中保留内存-然后将默认的int值放入其中,即0,然后使用赋值运算符-该运算符使用复制构造函数-依次调用第一个int x的析构函数,最后调用int x = 0;。换句话说,int x(0);更好,尽管它对int来说并不重要。编译器也会为您优化这一点,我只是指出这一点来帮助您在编程风格中做出决策。

long long y = x + 1;中,调用了类似的构造函数调用和复制构造函数,但添加部分很琐碎。

我认为您的问题实际上是,是否构建了一个临时变量,将x的值作为long long,以便将其添加到1。

答案是否定的。1x都属于int类型,因此算术将作为int算术执行,然后结果将被转换到long long并存储在y中。

如果您将x添加到其他类型的long long中,那么是的,在完成运算之前,x将被强制转换为long long。一般来说,编译器如何处理这类事情没有要求,但在实践中,在你可能遇到的几乎任何体系结构上,它都会发生在CPU寄存器中,而不是内存中。