我想知道以下操作是否会导致内存分配:
int x = 0;
long long y = x + 1;
如果是的话,是否有任何编译器优化可以动态处理这个问题,或者是否会导致单独的强制转换,然后再添加?
答案 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。
答案是否定的。 1
和x
都属于int
类型,因此算术将作为int
算术执行,然后结果将转换为long long
并存储在y
。
如果您要将x
添加到long long
类型的其他内容中,那么在算术完成之前,x
将被投射到long long
。一般来说,没有要求编译器如何处理这类事情,但实际上,在几乎任何你可能遇到的架构上,都会发生在CPU寄存器中,而不是在内存中。