c++ - 具有智能数组分配(堆或堆栈)的语言
问题描述
我正在为(有趣和)科学应用程序编写一个小型玩具语言/编译器。核心设计原则是简单和高效(如果你愿意,可以使用某种“现代”Fortran)。该语言将具有内置数组,看起来像这样:
let x: Real[5] = {1.0, 2.0, 3.0, 4.0, 5.0}
let n = get_runtime_value()
let y: Integer[100,n] = ...
在上面的语句中,用户没有明确说明数组应该分配在栈上还是堆上。如果可能的话,我宁愿不把它暴露给用户(我的理由是大多数工程师不知道区别,也不应该关心。他们还有其他问题要担心。)。
从技术上讲,我可以写如下内容:
if (some input parameter cannot be known at compile time)
allocate on the heap
else # candidate for the stack
if (the array is not returned by the function && the allocated size is smaller than some threshold)
allocate on the stack
else
allocate on the heap
然而,这个设计让我害怕有几个原因:
- 增加了复杂性,更长的编译时间?
- 在 C++ 中,编译器可以执行 RVO 并直接在堆栈上返回一个值。我想我可以使算法更复杂以检测这种情况,但这会使整个事情变得更复杂/错误/编译缓慢。
- 数组大小的微小变化可能会导致从堆栈切换到堆。这可能会让用户感到困惑。定义这个阈值也需要一些小心。
- 我需要检查是否没有返回对该数组的某些引用(以及引用的引用等)。我想追踪它可能会很昂贵。
请注意,我不想以我的语言公开指针或引用。数组将始终在引擎盖下通过引用传递。
文献中有没有解决这个问题的巧妙方法?以前用现有的语言做过吗?我知道的所有语言都要求用户指定他们想要数据的位置:Fortran 有::allocatable
、C++ 有std::vector
和std::array
等。我也可以做一些类似 llvm 的事情SmallVector
,并且总是在移动到堆之前在堆栈上分配一些元素。我的方法有任何意义吗?我正在使用这个项目来了解更多关于编译器和语言设计的信息。有什么我应该注意的吗?
解决方案
该选项实际上取决于您,但如果我是您,我会让用户选择是在堆上分配还是在堆栈上分配。如果没有,它很可能会让您和用户感到非常困惑。如果您仍想实现该功能,我有一些提示。
- 与其检查是否在编译时无法知道,不如检查在编译时可以知道的内容——它将简化事情。
- 默认情况下在堆或堆栈上定义所有内容——这将使您更容易处理需要从堆栈切换到堆(反之亦然)的情况(这更容易,因为假设何时
append
调用您可以切换到堆)。
总之,我建议您让用户明确声明堆栈或堆上的数组。
推荐阅读
- swift - VLCKit (iOS) mediaPlayer 突然停止播放
- python - 熊猫 DF 问题:
- excel - 编写 VBA 以过滤 OLAP 数据透视表字段
- c++ - 为什么 ADL 不适用于在命名空间之外定义的函数?
- r - 未加入数据框中的单独观察
- bert-language-model - 从变压器导入 TFBertModel、BertConfig、BertTokenizerFast
- javascript - 将 Openlayers 地图另存为 PDF(离线版)
- python-3.x - Django 智能选择无法正常工作
- arrays - C - 不同数组的成员共享指针
- audiokit - AudioKit 将增益应用于单声道 PCM 缓冲区