为什么可变长度数组不属于C ++标准?

本文翻译自:Why aren't variable-length arrays part of the C++ standard?

I haven't used C very much in the last few years. 在过去的几年中,我很少使用C。 When I read this question today I came across some C syntax which I wasn't familiar with. 今天,当我阅读此问题时 ,遇到了一些我不熟悉的C语法。

Apparently in C99 the following syntax is valid: 显然,在C99中 ,以下语法有效:

void foo(int n) {
    int values[n]; //Declare a variable length array
}

This seems like a pretty useful feature. 这似乎是一个非常有用的功能。 Was there ever a discussion about adding it to the C++ standard, and if so, why it was omitted? 是否曾有关于将其添加到C ++标准的讨论,如果是,为什么将其省略?

Some potential reasons: 一些潜在的原因:

  • Hairy for compiler vendors to implement 编译器厂商难以实施
  • Incompatible with some other part of the standard 与标准的其他部分不兼容
  • Functionality can be emulated with other C++ constructs 可以使用其他C ++结构来模拟功能

The C++ standard states that array size must be a constant expression (8.3.4.1). C ++标准声明数组大小必须是一个常量表达式(8.3.4.1)。

Yes, of course I realize that in the toy example one could use std::vector<int> values(m); 是的,我当然知道在玩具示例中可以使用std::vector<int> values(m); , but this allocates memory from the heap and not the stack. ,但这会从堆而不是堆栈分配内存。 And if I want a multidimensional array like: 如果我想要像这样的多维数组:

void foo(int x, int y, int z) {
    int values[x][y][z]; // Declare a variable length array
}

the vector version becomes pretty clumsy: vector版本变得非常笨拙:

void foo(int x, int y, int z) {
    vector< vector< vector<int> > > values( /* Really painful expression here. */);
}

The slices, rows and columns will also potentially be spread all over memory. 切片,行和列也可能会散布到整个内存中。

Looking at the discussion at comp.std.c++ it's clear that this question is pretty controversial with some very heavyweight names on both sides of the argument. 看一下comp.std.c++上的讨论,很明显这个问题引起了很大争议,在参数的两边都有一些非常重量级的名称。 It's certainly not obvious that a std::vector is always a better solution. 显然, std::vector总是更好的解决方案。


#1楼

参考:https://stackoom.com/question/7uv3/为什么可变长度数组不属于C-标准


#2楼

C99 allows VLA. C99允许VLA。 And it puts some restrictions on how to declare VLA. 并且对如何声明VLA施加了一些限制。 For details, refer to 6.7.5.2 of the standard. 有关详细信息,请参阅标准的6.7.5.2。 C++ disallows VLA. C ++禁止使用VLA。 But g++ allows it. 但是g ++允许它。


#3楼

In my own work, I've realized that every time I've wanted something like variable-length automatic arrays or alloca(), I didn't really care that the memory was physically located on the cpu stack, just that it came from some stack allocator that didn't incur slow trips to the general heap. 在我自己的工作中,我已经意识到,每当我想要可变长的自动数组或alloca()之类的东西时,我都不在乎内存实际上位于cpu堆栈上,而是因为它来自一些不会导致缓慢访问普通堆的堆栈分配器。 So I have a per-thread object that owns some memory from which it can push/pop variable sized buffers. 因此,我有一个每个线程对象,该对象拥有一些内存,可以从中推入/弹出可变大小的缓冲区。 On some platforms I allow this to grow via mmu. 在某些平台上,我允许它通过mmu扩展。 Other platforms have a fixed size (usually accompanied by a fixed size cpu stack as well because no mmu). 其他平台具有固定大小(通常还附带固定大小的cpu堆栈,因为没有mmu)。 One platform I work with (a handheld game console) has precious little cpu stack anyway because it resides in scarce, fast memory. 我使用的一个平台(手持游戏机)无论如何都具有宝贵的cpu堆栈,因为它位于稀缺的快速内存中。

I'm not saying that pushing variable-sized buffers onto the cpu stack is never needed. 我并不是说永远不需要将可变大小的缓冲区推入cpu堆栈。 Honestly I was surprised back when I discovered this wasn't standard, as it certainly seems like the concept fits into the language well enough. 老实说,当我发现这不是标准时,我感到很惊讶,因为它看起来确实很适合该语言。 For me though, the requirements "variable size" and "must be physically located on the cpu stack" have never come up together. 但是对我而言,“可变大小”和“必须物理上放置在cpu堆栈上”的要求从来没有提出来。 It's been about speed, so I made my own sort of "parallel stack for data buffers". 这与速度有关,所以我做了自己的“数据缓冲区并行堆栈”。


#4楼

Seems it will be available in C++14: 似乎它将在C ++ 14中可用:

https://en.wikipedia.org/wiki/C%2B%2B14#Runtime-sized_one_dimensional_arrays https://zh.wikipedia.org/wiki/C%2B%2B14#Runtime-sized_one_Dimension_arrays

Update: It did not make it into C++14. 更新:它没有进入C ++ 14。


#5楼

You need a constant expression to declare an array in C/C++. 您需要一个常量表达式才能在C / C ++中声明一个数组。

For dynamic size arrays, you need to allocate memory on heap, then manage the liftime of this memory. 对于动态大小数组,您需要在堆上分配内存,然后管理此内存的有效期。

void foo(int n) {
    int* values = new int[n]; //Declare a variable length array
    [...]
    delete [] values;
}

#6楼

Use std::vector for this. 为此使用std :: vector。 For example: 例如:

std::vector<int> values;
values.resize(n);

The memory will be allocated on the heap, but this holds only a small performance drawback. 内存将在堆上分配,但这只带来了很小的性能缺陷。 Furthermore, it is wise not to allocate large datablocks on the stack, as it is rather limited in size. 此外,明智的做法是不要在堆栈上分配大数据块,因为它的大小受到限制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章