简体   繁体   English

将数学计算写成变量初始化中的常量表达式的值会增加计算量吗?

[英]Writting a mathematical calculation as the value of a constant expression in a variable inicialization increases the computational work?

In C++, does a mathematical declaration in a constant variable initialization costs some extra processing? 在C ++中,在常量变量初始化中进行数学声明是否会花费一些额外的处理时间? Or modern compilers would automatically put the result of the mathematical calculation inside the variable when creating the .exe file? 还是现代编译器会在创建.exe文件时自动将数学计算的结果放入变量中?

So eg: 所以例如:

MyClass::MyClass()
{
    const qint32 defaultX = 20;

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,20);

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,80);
    //...
}

is a example of a code that uses a constant variable (defaultX) across a method usage (the constructor in this case). 是一个代码示例,该代码在方法用法(在这种情况下为构造函数)中使用常量变量(defaultX)。 Now sometimes it's better for the developer to tell where the value came from: 现在,有时最好让开发人员告诉您价值来自何处:

MyClass::MyClass()
{
    const qint32 defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,20);

    poButton1 = new PushButton(this);
    poButton1->move(defaultX,80);
    //...
}

Of course he could just put that inside a comment, but let's suppose he wants to do it this way (eg: he is dumb). 当然,他可以将其放在评论中,但让我们假设他想这样做(例如:他很笨)。 The question would then be: when a object of that class is being initialized, does that whole mathematical expression is calculated (costing extra processing) or when the .exe is created by modern compilers it already contains the optimized code seen in the first MyClass code? 问题是:当初始化该类的对象时,是否会计算整个数学表达式(花费额外的处理时间),或者当现代编译器创建.exe时,它已经包含了第一个MyClass代码中看到的优化代码。 ?

It is not guaranteed but most modern compilers will indeed fold the constant expression , the draft C++ standard has a note that says constant expressions could be evaluated during translation, from section 5.19 Constant expressions : 不能保证,但是大多数现代编译器的确会折叠常量表达式C ++标准草案中有一条注释,指出常量表达式可以在翻译时从5.19常量表达式求值

[ Note: Constant expressionscan be evaluated during translation.—end note ] [注意:常量表达式可以在翻译过程中求值。

but we can run an experiment on godbolt with the following code: 但是我们可以使用以下代码在Godbolt上进行实验:

#include <iostream>
int func()
{
    const  int defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!

  return defaultX ;
}

int main()
{
  std::cout << func() ;
}

and see it does indeed fold it to the following: 并确实将其折叠为以下内容:

func():
  movl  $20, %eax   #,
  ret

In C++11 you can always use constexpr to make sure it is evaluated at compile time: 在C ++ 11中,您始终可以使用constexpr来确保在编译时对其进行评估:

constexpr  int defaultX = 800/2 - 244 + 12 + 32 - 180;

The standard does make one important note with respect to floating point constant expressions. 该标准确实对浮点常量表达式做了一个重要说明。 Since there is a lack of specification on the accuracy of floating point operations it is possible that evaluations at run-time and compile-time could produce different results: 由于缺乏对浮点运算精度的规范,因此在运行时和编译时进行评估可能会产生不同的结果:

[ Note: Although in some contexts constant expressions must be evaluated during program translation, others may be evaluated during program execution. [注意:尽管在某些情况下必须在程序转换期间对常量表达式进行求值,但其他表达式可能在程序执行期间进行求值。 Since this International Standard imposes no restrictions on the accuracy of floating-point operations, it is unspecified whether the evaluation of a floating-point expression during translation yields the same result as the evaluation of the same expression (or the same operations on the same values) during program execution.84 Example: 由于此国际标准对浮点运算的精度没有任何限制,因此未确定翻译过程中对浮点表达式的求值是否与对相同表达式的求值(或对相同值的相同运算)产生相同的结果。 )在程序执行期间。84示例:

  bool f() { char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime return sizeof(array) == size; } 

It is unspecified whether the value of f() will be true or false. 不确定f()的值是true还是false。 —end example ] —end note ] -结束示例]-结束注释]

If it can be collapsed into a single value, which it must be in the case of a simple assignment, the compiler should take care of condensing it down to a singular value, though this may depend on your compiler's optimization flags. 如果可以将其折叠为单个值(在简单赋值的情况下必须这样做),则编译器应注意将其压缩为单个值,尽管这可能取决于编译器的优化标志。 You may want to look at the instructions emitted by your compiler to be sure. 您可能需要查看编译器发出的指令才能确定。

One way to express this more clearly is to declare the constant outside of the class itself but local to the implementation and use that within the class: 一种更清楚地表达这一点的方法是,在类本身外部声明常量,但在实现本地进行定义,并在类内部使用该常量:

const qint32 myClassDefaultX = 800/2 - 244 + 12 + 32 - 180;

MyClass::MyClass() { ... }

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

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