将一个数学计算写成一个变量中常量表达式的值,这会增加计算工作量吗? 在C++中,常数变量初始化中的数学声明是否需要额外的处理?或者现代编译器在创建.exe文件时会自动将数学计算结果放入变量中
例如:将一个数学计算写成一个变量中常量表达式的值,这会增加计算工作量吗? 在C++中,常数变量初始化中的数学声明是否需要额外的处理?或者现代编译器在创建.exe文件时会自动将数学计算结果放入变量中,c++,compiler-optimization,constant-expression,C++,Compiler Optimization,Constant Expression,例如: MyClass::MyClass() { const qint32 defaultX = 20; poButton1 = new PushButton(this); poButton1->move(defaultX,20); poButton1 = new PushButton(this); poButton1->move(defaultX,80); //... } 是在方法用法(本例中为构造函数)中使用常量变量(defa
MyClass::MyClass()
{
const qint32 defaultX = 20;
poButton1 = new PushButton(this);
poButton1->move(defaultX,20);
poButton1 = new PushButton(this);
poButton1->move(defaultX,80);
//...
}
是在方法用法(本例中为构造函数)中使用常量变量(defaultX)的代码示例。现在,有时开发人员最好告诉您价值来自何处:
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);
//...
}
当然,他可以把它放在评论中,但让我们假设他想这样做(例如:他是个哑巴)。问题是:当初始化该类的对象时,是否计算整个数学表达式(需要额外的处理),或者当.exe由现代编译器创建时,它已经包含第一个MyClass代码中看到的优化代码?如果可以将其压缩为单个值,在简单赋值的情况下,编译器应该注意将其压缩为一个奇异值,尽管这可能取决于编译器的优化标志。您可能希望查看编译器发出的指令,以确定是否正确 更清楚地表达这一点的一种方法是在类本身之外声明常量,但在实现本地声明常量,并在类内使用该常量:
const qint32 myClassDefaultX = 800/2 - 244 + 12 + 32 - 180;
MyClass::MyClass() { ... }
如果可以将其压缩为单个值(在简单赋值的情况下必须如此),编译器应注意将其压缩为单个值,尽管这可能取决于编译器的优化标志。您可能希望查看编译器发出的指令,以确定是否正确 更清楚地表达这一点的一种方法是在类本身之外声明常量,但在实现本地声明常量,并在类内使用该常量:
const qint32 myClassDefaultX = 800/2 - 244 + 12 + 32 - 180;
MyClass::MyClass() { ... }
这是不能保证的,但大多数现代编译器确实会折叠,其中有一条注释说,常量表达式可以在翻译过程中进行计算,参见第
5.19节constant expressions:
[注:在翻译过程中可以计算常量表达式。-结束注]
但我们可以使用以下代码在上运行一个实验:
#include <iostream>
int func()
{
const int defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!
return defaultX ;
}
int main()
{
std::cout << func() ;
}
在C++11中,您始终可以使用以确保在编译时对其进行计算:
constexpr int defaultX = 800/2 - 244 + 12 + 32 - 180;
该标准确实对浮点常量表达式做了一个重要的说明。由于缺乏关于浮点运算精度的规范,运行时和编译时的求值可能会产生不同的结果:
[注意:尽管在某些上下文中,常量表达式必须是
在程序翻译过程中进行评估,其他人可能在程序翻译过程中进行评估
程序执行。由于本国际标准规定
对浮点运算精度的限制,它是
未指定是否对浮点表达式进行求值
在翻译过程中产生的结果与对
过程中的相同表达式(或对相同值的相同操作)
程序执行。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;
}
未指定f()的值是真是假。-结束示例]-结束注释]
这是不能保证的,但大多数现代编译器确实会折叠,其中有一条注释说,常量表达式可以在翻译过程中进行计算,参见第5.19节constant expressions:
[注:在翻译过程中可以计算常量表达式。-结束注]
但我们可以使用以下代码在上运行一个实验:
#include <iostream>
int func()
{
const int defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!
return defaultX ;
}
int main()
{
std::cout << func() ;
}
在C++11中,您始终可以使用以确保在编译时对其进行计算:
constexpr int defaultX = 800/2 - 244 + 12 + 32 - 180;
该标准确实对浮点常量表达式做了一个重要的说明。由于缺乏关于浮点运算精度的规范,运行时和编译时的求值可能会产生不同的结果:
[注意:尽管在某些上下文中,常量表达式必须是
在程序翻译过程中进行评估,其他人可能在程序翻译过程中进行评估
程序执行。由于本国际标准规定
对浮点运算精度的限制,它是
未指定是否对浮点表达式进行求值
在翻译过程中产生的结果与对
过程中的相同表达式(或对相同值的相同操作)
程序执行。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;
}
未指定f()的值是真是假。-结束示例]-结束注释]
只要表达式是常量,一个好的编译器就会对它进行优化,并用表达式的结果替换defaultX。在C++11中,您可能希望使用constexpr
,理论上,这两个方向都没有保证。事实上,你能找到的每一个半途而废的编译器都会在编译时进行编译。为什么你认为这样做很愚蠢?可能有理由澄清如何构造值,或者希望在公式中使用其他常量表达式。不,这不会损害运行时性能,编译器将在编译时正确计算所有内容,就像启动袖珍计算器一样。@πάνταῥεῖ 我提出了一个“愚蠢”的解释,因为一旦有可能在注释中编写公式,而只将结果放入代码中,同时有可能“损害”运行时性能,就没有合理的理由这样做:)只要表达式是常量,一个好的编译器将对其进行优化,并用表达式的结果替换defaultX。在C++11中,您可能希望使用constexpr
,理论上,这两个方向都没有保证。事实上,你能找到的每一个半途而废的编译器都会在编译时完成它。为什么你认为它对d来说是愚蠢的呢