爲什麼可變長度數組不屬於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. 此外,明智的做法是不要在堆棧上分配大數據塊,因爲它的大小受到限制。

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