在编译时内联分配内存

时间:2017-01-18 14:57:23

标签: c++ allocation constexpr compile-time

C / C ++ 有多种方法可以在编译时分配内存。例如,我可以添加全局变量或静态变量。存储值的内存在编译时分配:

int x;
// -- or --
void f() {
    static int y;
}
// -- or --
class C {
    static int z;
};
int C::z;

但是这个解决方案不能用于分配“内联”内存。是否有可能在一行中执行以下操作?

static int value_behind_x; // does not need to be "named"
int * const x = &value_behind_x;

我的意思是这样的:

int * const x = static_new int;
// -- or --
int * const x_array = static_new int[10];

我知道C / C ++中有一件事允许这样的东西:字符串文字。但是,它们必须是常量,并且不允许将大小指定为数字。

如果没有这种方式,是否有理由或将来可能实施?这样会很好,因为它可以实现像constexpr这样的std::vector版本的容器。

3 个答案:

答案 0 :(得分:2)

static

Your statement

  

在编译时分配内存

这表明存在误解。 Static Storage Durration已定义:

  

对象的存储在程序开始时分配,并在程序结束时解除分配。只存在一个对象实例。在命名空间范围内声明的所有对象(包括全局命名空间)都具有此存储持续时间,以及使用staticextern声明的持续时间。

了解静态存储持续时间对于对抗"static initialization fiasco"

至关重要

通过这种理解,我们可以看到构造指向变量的static指针没有性能优势,例如 static unique_ptr<const int> x(new int(13)); 而只是使用地址{{ 1}}如果需要是可取的。

同样的事情适用于分配具有静态存储持续时间的阵列。如果需要对数组进行容器封装,可以使用array之类的容器: value_behind_x 但一般来说,{{3提供的范围访问和容器访问的改进在中{}},我建议你坚持:

static array<int, 10> x_array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

修改

您知道,iterator library也有静态存储持续时间,这意味着您不会“在编译时分配”。实际上除了C ++使用的静态存储持续时间之外,只有string literals

  
      
  • 自动存储持续时间。该对象在封闭代码块的开头分配,并在最后解除分配。除了声明为static const x_array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; static或thread_local的那些外,所有本地对象都有此存储持续时间。
  •   
  • 线程存储持续时间。线程开始时分配对象,线程结束时分配对象。每个线程都有自己的对象实例。只有声明为thread_local的对象才具有此存储持续时间。 thread_local可以与externstatic一起显示以调整链接。
  •   
  • 动态存储持续时间。通过使用动态内存分配函数为每个请求分配和释放对象。
  •   

所以不,在运行时之前没有分配或初始化。我也不希望有这种情况,因为这需要一个基本的C ++意识形态改变在某种程度上改变计算机体系结构。

答案 1 :(得分:1)

首先,具有静态持续时间的变量的内存在编译时并未真正分配。它在链接时或甚至在启动时分配。虽然差异微妙,但在某些情况下很重要。

其次,您正在寻找的是一种分配自动或静态持续时间的数据块的方法。传统上,它使用C样式数组std::array完成,并在可用时使用VLA扩展作为VLA数组。

答案 2 :(得分:0)

所请求的功能已部分计划用于 C ++ 20 。现在仅允许临时分配。

这意味着new在编译时将有效。但是,当前不允许在编译时分配的内存泄漏到运行时。可以在P0784中找到此限制的原因。将来的版本中可能会添加对非临时分配的支持。