【发布时间】:2017-02-27 00:37:43
【问题描述】:
在我的 D 程序中,我有一个固定长度的只读数组,我希望按枚举类型索引该数组。
如果我这样做
static const my_struct_t aray[ my_enum_t ] = ... whatever ...;
my_enum_t index;
result = aray[ index ];
那么 GDC 生成的代码是巨大的,在数组被索引时充满了对运行时的调用。所以看起来好像数组被视为可变长度或关联数组(哈希表)或其他东西,无论如何都远离具有直接索引的固定长度的轻量级 C 样式数组。由于枚举具有固定的基数并且不能增长,并且我的值范围适中(我没有滥用关键字 enum 只是为了定义大量随机常量),所以我不知道为什么会发生这种情况。
我通过将行改为
解决了这个问题static const my_struct_t aray[ my_enum_t.max + 1 ]
据我了解,这意味着方括号中的值只是整数类型的已知常量。由于索引现在根本不是枚举,我现在有一个由整数索引的数组,所以我失去了类型检查,我可以用任何随机整数类型变量索引它,而不是确保只有正确的(强)类型是用过。
我该怎么办?
在更一般的情况下,(愚蠢的例子)
static const value_t aray[ bool ] = blah
例如,我有一个在语义上完全合理的索引类型,但不仅仅是无类型的 size_t/int/uint,我想我会遇到同样的问题。
我不想说这是一个编译器设计问题。这当然是次优行为的情况。但是为了对编译器公平起见,究竟是什么告诉它数组是固定长度还是可变的,是稀疏的还是密集的?我想要两件事;索引和非可变长度的类型检查。实际上,在这种特殊情况下,数组是 const (我也可以放不可变的),所以它显然不能是可变长度的。但是对于具有可修改内容但长度固定的数组,您需要能够声明它是固定长度的。
【问题讨论】:
-
这个数组的初始化确实是在compile-type完成的,声明行有一个rhs初始化列表,里面装满了已知的编译时常量值。
-
事实上,作为缺乏类型检查的坏处的一个例子,最初我忘记了方括号中的+1,所以我得到的数组大小太小了。碰巧碰巧发现了这一点,因为我正在查看生成代码并看到了一条线索,因为为静态对象生成的名称。因此,我放入了一些静态断言,但对我来说没有什么可以自动化。
-
我在用 Pascal (Ada?) 术语思考。
-
专业做了大量的asm和C,现在慢慢从D开始。