Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于具有静态存储持续时间的对象,在编译时可以应用哪些类型的构造函数作为优化?_C++_Optimization_Compiler Construction_Constructor_Initialization - Fatal编程技术网

C++ 对于具有静态存储持续时间的对象,在编译时可以应用哪些类型的构造函数作为优化?

C++ 对于具有静态存储持续时间的对象,在编译时可以应用哪些类型的构造函数作为优化?,c++,optimization,compiler-construction,constructor,initialization,C++,Optimization,Compiler Construction,Constructor,Initialization,以以下两个类及其构造函数为例: class One{ public: One(int a,int b):adad1(a),adad2(b){} private: int adad1; int adad2; }; class Two{ public: Two(int input[]){ for (int i=0;i<10;i++) araye[i]=input[i]; } private: int araye[10]; }; 第一类{ 公众:

以以下两个类及其构造函数为例:

class One{
 public:
  One(int a,int b):adad1(a),adad2(b){}
 private:
  int adad1;
  int adad2;
};
class Two{
 public:
  Two(int input[]){
   for (int i=0;i<10;i++)
    araye[i]=input[i];
  }
 private:
  int araye[10];
};
第一类{
公众:
一(inta,intb):adad1(a),adad2(b){}
私人:
int ADADAD1;
int ADADAD2;
};
二班{
公众:
两个(int输入[]){

对于(int i=0;i编译时没有应用构造函数。事实上,编译时根本没有执行任何代码。

编译时没有应用构造函数。事实上,编译时根本没有执行任何代码。

不能保证在执行任何运行时代码之前,这两个构造函数中的任何一个都是静态初始化的。首先,很容易但这不会发生

class One{
 public:
  int adad1;
  int adad2;
};

// initialized statically, if a and b are constant-expressions
One one = { a, b }; 
正如另一个人所说,C++0x中的
constexpr
允许静态执行构造函数。在您的情况下,这适用于第一种情况,但不适用于第二种情况。对于第二种情况,您必须遵守这一点,标准没有做出任何保证。但标准仍然允许实现在静态初始值下对其进行优化第二阶段。见3.6.2/2

允许实现以静态存储持续时间作为静态初始化来执行命名空间范围的对象的初始化,即使不需要静态完成此类初始化,但前提是

  • 初始化的动态版本不会更改命名空间的任何其他对象的值 在初始化之前具有静态存储持续时间的作用域,以及
  • 如果所有不需要静态初始化的对象都是动态初始化的,则初始化的静态版本会在初始化对象中生成与动态初始化相同的值
如果给定的数组是合适的,那么您的构造函数可能不会违反这些规则。该标准显示了一个示例,我在中对此进行了解释。为了完整起见,示例代码如下所示

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;   // unspecified:
                  // may be statically initialized to 0.0 or
                  // dynamically initialized to 1.0

double d1 = fd(); // may be initialized statically to 1.0

正如您所看到的,如果变量之间存在某种关系,那么提前初始化甚至可以更改初始值。

不能保证在执行任何运行时代码之前,这两个变量中的任何一个都是静态初始化的。不过,对于第一个,很容易实现

class One{
 public:
  int adad1;
  int adad2;
};

// initialized statically, if a and b are constant-expressions
One one = { a, b }; 
正如另一个人所说,C++0x中的
constexpr
允许静态执行构造函数。在您的情况下,这适用于第一种情况,但不适用于第二种情况。对于第二种情况,您必须遵守这一点,标准没有做出任何保证。但标准仍然允许实现在静态初始值下对其进行优化第二阶段。见3.6.2/2

允许实现以静态存储持续时间作为静态初始化来执行命名空间范围的对象的初始化,即使不需要静态完成此类初始化,但前提是

  • 初始化的动态版本不会更改命名空间的任何其他对象的值 在初始化之前具有静态存储持续时间的作用域,以及
  • 如果所有不需要静态初始化的对象都是动态初始化的,则初始化的静态版本会在初始化对象中生成与动态初始化相同的值
如果给定的数组是合适的,那么您的构造函数可能不会违反这些规则。该标准显示了一个示例,我在中对此进行了解释。为了完整起见,示例代码如下所示

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;   // unspecified:
                  // may be statically initialized to 0.0 or
                  // dynamically initialized to 1.0

double d1 = fd(); // may be initialized statically to 1.0

正如您所看到的,如果变量之间存在某种关系,那么提前初始化甚至可以更改初始值。

您所说的“在编译时”是什么意思?所有这些都发生在运行时。如果您“真的”在编译时,您必须等待C++0x附带的
constexpr
。您所说的“在编译时”是什么意思?所有这些都发生在运行时。如果您“真的”意思是在编译时,你必须等待C++0x附带的
constexpr
。非常好的描述,但是为什么你一开始就肯定地说,如果规则仍然允许的话,那么在编译时就不能完成任何情况?@Pooria你不知道实现是否优化了它。我的意思是说你不能依赖它(因此,您必须假设存在静态初始化顺序问题)@Johannes Schaub-litb:毕竟,我怀疑第二种情况是否被该标准所接受,因为这涉及到一些关于for循环和一些东西的代码;第一种情况可能是因为它有一个空的体函数,所以可以转换为常量表达式,你说呢?@Pooria体包含什么并不重要。循环或如果足够好的话,编译器可以优化其他任何东西。我怀疑编译器是否可以这样做,但这是允许的。除非你有“volatile”变量,但在代码中看不到“volatile”:@Johannes Schaub-litb:你能告诉我,在标准中,循环或任何东西都可以被优化掉,因为我觉得这听起来像个UFO!!!描述得很好,但你为什么一开始就肯定地说,如果规则仍然允许的话,没有任何情况可以在编译时完成?@Pooria你不知道实现是否ion优化了它。我的意思是说你不能依赖它(所以你必须假设你有静态初始化顺序问题)@Johannes Schaub-litb:毕竟,我怀疑第二种情况是否被该标准所接受,因为这涉及到一些关于for循环和一些东西的代码;第一种情况可能是因为它有一个空的体函数,所以可以转换为常量表达式,你说呢?@Pooria体包含什么并不重要。循环或如果编译器足够好的话,其他的东西都可以被优化。我怀疑编译器是否能做到,但它是允许的。除非你有“volatile”变量,但在代码中看不到“volatile:)@Johannes Schaub-litb:你能告诉我t在哪里吗