简体   繁体   English

C ++转换内存分配

[英]C++ cast memory allocation

I'm wondering if the following operation results in a memory allocation: 我想知道以下操作是否会导致内存分配:

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

If it does, are there any compiler optimizations that take care of this on the fly, or does this result in a standalone cast followed by the addition? 如果是这样,是否有任何编译器优化可以即时解决这一问题,或者是否导致了独立的强制转换,然后进行了添加?

The answer is: it depends. 答案是:这取决于。 There is absolutely no requirement on the compiler to perform memory allocation if the the behaviour of the program does not depend on it. 如果程序的行为不依赖于它,则绝对不需要编译器执行内存分配。 Specifically C++14 n3797 S1.9: 特别是C ++ 14 n3797 S1.9:

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. 本国际标准中的语义描述定义了参数化的不确定性抽象机器。 This International Standard places no requirement on the structure of conforming implementations. 本国际标准对一致性实现的结构没有要求。 In particular, they need not copy or emulate the structure of the abstract machine. 特别是,它们不需要复制或模拟抽象机的结构。 Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below. 相反,需要遵循的实现来(仅)模拟抽象机的可观察行为,如下所述。

This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. 该规定有时被称为“假设”规则,因为只要可以从可观察到的行为中确定结果,就可以无视本国际标准的任何要求,而该实现可以自由地执行。该程序。 For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced. 例如,如果实际实现可以推断出未使用其值并且不会产生影响程序可观察行为的副作用,则无需评估表达式的一部分。

In this case: 在这种情况下:

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

The compiler is absolutely free to rewrite this function as: 编译器绝对可以将函数重写为:

long long f() {
  return 1;
}

In doing so it may simply load immediate values into registers and never perform any memory access at all. 这样做可能只是将立即值加载到寄存器中,而根本不会执行任何内存访问。 Depending on the calling context it may even inline this function so it completely disappears from view. 根据调用上下文的不同,它甚至可以内联此函数,以便它完全从视图中消失。

If the variables are local variables inside a function, then the compiler will make sure that there is enough space for them on the stack. 如果变量是函数内部的局部变量,则编译器将确保堆栈上有足够的空间供它们使用。 If they are global variables, then there will be space reserved in the executable file for the variables, and it will be "allocated" by the runtime loader of your operating system. 如果它们是全局变量,则在可执行文件中将为变量保留空间,并且将由操作系统的运行时加载器对其进行“分配”。

There is no dynamic memory allocation going on, ie there's nothing allocated on the heap. 没有正在进行的动态内存分配,即堆上没有任何分配。 The space is reserved by the compiler, so it's already taken cared of by the compiler "on the fly". 该空间由编译器保留,因此它已经由编译器“即时”处理。

I don't know if I fully understand your question, but I'll do my best to offer my 2 cents. 我不知道我是否完全理解您的问题,但我会尽力提供2美分。 In case you are not aware, initializing the way are , is not the most efficient way of doing so. 如果您不知道,初始化的方式不是最有效的方法。 For example: 例如:

int x = 0;

is calling the default int constructor, which uses the default allocator - reserves memory in the data segment - then puts the default int value in it which is 0, then uses the assignment operator - which uses the copy constructor - which in turn calls the destructor for the first int x , then finally int x = 0; 正在调用默认的int构造函数,该构造函数使用默认的分配器-在数据段中保留内存-然后将默认的int值放入0,然后使用赋值运算符-使用复制的构造函数-依次调用析构函数对于第一个int x ,然后最终int x = 0; . In other words int x(0); 换句话说int x(0); is better, though it doesn't really matter for ints. 更好,尽管对int并不重要。 Also the compiler will optimize this for you, I was just pointing this out to help you make decisions in your programming style. 编译器也会为您优化此过程,我只是指出这一点是为了帮助您以编程风格做出决策。

With the long long y = x + 1; long long y = x + 1; similar constructor calls and copy constructors are being called, but the addition portion is trivial. 调用了类似的构造函数调用和复制构造函数,但是加法部分微不足道。

I think that your question is really whether a temporary variable is constructed holding the value of x as a long long so that it can be added to 1. 我认为您的问题实际上是是否构造了一个临时变量,将x的值保留得很long long以便可以将其加到1。

The answer is no. 答案是不。 Both 1 and x are of type int , so the arithmetic will be performed as int arithmetic and the result will then be cast to long long and stored in y . 1x均为int类型,因此该算术将作为int算术执行,然后将结果转换为long long并存储在y

If you were adding x to something else of type long long then yes, x would be cast to long long before the arithmetic was done. 如果要在long longx添加到其他类型的对象上long long那么可以,在进行算术运算之前, x将被强制转换为long long时间。 In general, there is no requirement on how the compiler handles this sort of thing, but in practice, on almost any architecture you're likely to come across, it will happen in CPU registers, not in memory. 通常,对编译器如何处理这种情况没有要求,但是实际上,在您可能会遇到的几乎任何体系结构上,它都会发生在CPU寄存器中,而不是内存中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM