C++ 编译时内存的内联分配

C++ 编译时内存的内联分配,c++,allocation,constexpr,compile-time,c++11,c++14,c++17,C++,Allocation,Constexpr,Compile Time,C++11,C++14,C++17,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"

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

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


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

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

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

静态
将:

在编译时分配内存

这表明了一种误解。定义如下:

对象的存储在程序开始时分配,在程序结束时解除分配。该对象只存在一个实例。在名称空间范围(包括全局名称空间)中声明的所有对象都具有此存储持续时间,加上使用
static
extern
声明的对象

了解静态存储持续时间对于解决此问题至关重要

基于这种理解,我们可以看到构造指向变量的
static
指针(例如
static unique_ptr x(new int(13)))对性能没有好处
相反,如果需要,最好只使用
value\u后面的地址

同样的情况也适用于分配具有静态存储持续时间的阵列。您可以使用一个容器,例如如果您需要数组的容器封装:
静态数组x_array={0,1,2,3,4,5,6,7,8,9}
,但一般来说,随着对范围访问和容器访问的改进,我建议您坚持:

static const x_array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
编辑:

正如您所知,还有静态存储持续时间,这意味着您的存储持续时间不是“在编译时分配的”。事实上,C++使用的除了静态存储持续时间之外,只有:

  • 自动存储持续时间。对象在封闭代码块的开头分配,并在结尾取消分配。所有本地对象都具有此存储持续时间,但声明为
    静态
    外部
    或线程本地的对象除外
  • 线程存储持续时间。对象在线程开始时分配,在线程结束时解除分配。每个线程都有自己的对象实例。只有声明为thread_local的对象具有此存储持续时间。螺纹_local可与
    static
    extern
    一起出现,以调整联动装置
  • 动态存储持续时间。通过使用动态内存分配函数,每个请求分配和取消分配对象
所以不,在运行之前没有分配或初始化。我也不希望出现这样的情况,因为这需要一个基本的C++思想改变和某种程度上的计算机体系结构的改变。

< P> >代码>静态< /代码>: 在编译时分配内存

这表明了一种误解。定义如下:

对象的存储在程序开始时分配,在程序结束时解除分配。该对象只存在一个实例。在名称空间范围(包括全局名称空间)中声明的所有对象都具有此存储持续时间,加上使用
static
extern
声明的对象

了解静态存储持续时间对于解决此问题至关重要

基于这种理解,我们可以看到构造指向变量的
static
指针(例如
static unique_ptr x(new int(13)))对性能没有好处
相反,如果需要,最好只使用
value\u后面的地址

同样的情况也适用于分配具有静态存储持续时间的阵列。您可以使用一个容器,例如如果您需要数组的容器封装:
静态数组x_array={0,1,2,3,4,5,6,7,8,9}
,但一般来说,随着对范围访问和容器访问的改进,我建议您坚持:

static const x_array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
编辑:

正如您所知,还有静态存储持续时间,这意味着您的存储持续时间不是“在编译时分配的”。事实上,C++使用的除了静态存储持续时间之外,只有:

  • 自动存储持续时间。对象在封闭代码块的开头分配,并在结尾取消分配。所有本地对象都具有此存储持续时间,但声明为
    静态
    外部
    或线程本地的对象除外
  • 线程存储持续时间。对象在线程开始时分配,在线程结束时解除分配。每个线程都有自己的对象实例。在…上