C ++转换内存分配

时间:2014-08-26 02:17:57

标签: c++ memory-management

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

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

如果是的话,是否有任何编译器优化可以动态处理这个问题,或者是否会导致单独的强制转换,然后再添加?

4 个答案:

答案 0 :(得分:3)

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

  

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

     

这项规定有时被称为“假设”规则,因为只要结果好像符合要求,实施可以自由地忽视本国际标准的任何要求,只要可以从程序的可观察行为。例如,如果可以,实际实现不需要评估表达式的一部分   推断其价值未被使用,并且不会产生影响程序可观察行为的副作用。

在这种情况下:

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

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

long long f() {
  return 1;
}

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

答案 1 :(得分:1)

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

没有动态内存分配正在进行,即堆上没有分配任何内容。这个空间由编译器保留,所以它已经被编译器“动态”地关注了。

答案 2 :(得分:0)

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

int x = 0;

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

正在调用long long y = x + 1;类似的构造函数调用和复制构造函数,但添加部分很简单。

答案 3 :(得分:0)

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

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

如果您要将x添加到long long类型的其他内容中,那么在算术完成之前,x将被投射到long long。一般来说,没有要求编译器如何处理这类事情,但实际上,在几乎任何你可能遇到的架构上,都会发生在CPU寄存器中,而不是在内存中。