c++ - 编译器如何处理变长数组

标签 c++ c templates visual-c++ c++11

这似乎是一个初学者的问题,但我对编译器通常创建可变维度数组的方式很感兴趣,就像在下面的程序中一样。

#include<iostream>

int main(){
  int n;
  std::cin>>n;
  int a[n];
}

据我所知,在 C 中,所有初始化值都必须是常量,以便编译器知道在函数内部保留多少内存,通常通过减去堆栈指针以容纳数组的元素数量持有。

这对我来说很有意义。 但是,我不太了解编译器如何处理上述程序,因为它似乎可以与 G++(MinGW) 一起使用,但无法与 Microsoft 的 C++ 编译器 Cl 一起使用。我怀疑 GCC 通过非标准扩展在堆上分配内存,但我不确定这一点。

此外,Microsoft 的编译器并不以符合标准而著称,因此如果它处理上述程序的方式实际上可能是错误的,我也不会感到惊讶。

最佳答案

在 C 标准的 C99 版本中,允许使用可变长度数组。但是,在任何版本的 C++ 中都不允许使用它们;你看到的是 G++ 扩展。请注意,Microsoft 的 C 编译器并不完全支持 C99;由于 G++ 支持 C99,因此很容易将 VLA 支持作为扩展应用于 C++。

至于编译器通常如何实现 VLA,它与 alloca() 相同(除了它必须保持 sizeof 的大小)——编译器保存原始堆栈指针,然后将其向下调整它计算出的所需字节数。缺点是函数进入和退出有点复杂,因为编译器需要存储将堆栈指针重置到的位置,而不是仅仅通过固定常量进行调整。

关于c++ - 编译器如何处理变长数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7627235/

相关文章:

c++ - libcurl curl_easy_perform() 在函数内部移动时导致程序崩溃

c++ - std::shared_ptr 在 Qt 的 getter 函数中被删除

c++ - 为什么 sizeof... 不能使用这个别名模板?

c++ - 成员函数模板是否需要 "inline"

c++ - 定义一个只有标题的类 - 找不到不存在的 cpp

c++ - 使用 cout 时消失的奇怪段错误

c++ - 如何在 C++ 编译时检测结构的成员是否是位域?

c - 海湾合作委员会错误 : expected expression before 'else'

android - 如何在Android中使用C程序来提供来自127.0.0.1的API?

c - 从文件中读取C编程