7

我有以下代码:

import std.stdio;

int main(string[] args)
{
   int[3] my_array = [1, 2];
   return 0;
}

这编译得很好,然后在执行时中止,给出这个错误:

arrays_init
object.Exception@src/rt/arraycat.d(31): lengths don't match for array copy
----------------
arrays_init(_Dmain+0x64) [0x416bbc]
arrays_init(extern (C) int rt.dmain2.main(int, char**).void runMain()+0x1c) [0x418c5c]
arrays_init(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x2a) [0x4185d6]
arrays_init(extern (C) int rt.dmain2.main(int, char**).void runAll()+0x3b) [0x418ca3]
arrays_init(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x2a) [0x4185d6]
arrays_init(main+0xd1) [0x418561]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f60bc41d30d]

如果数组文字有 3 个项目,这运行良好,因此显然数组文字必须匹配静态数组的大小。但这不应该给出编译错误,因为两者的大小都可以在编译时计算吗?

4

3 回答 3

9

数组字面量属于 类型T[],即它们是动态数组,在编译时不知道它们的大小。

您的代码编译的原因与编译的原因相同:

void foo(int[] xs)
{
    int[3] ys = xs;
    ...
}

编译器根本不知道有多大xs

在您的情况下,编译器可以在编译时知道,因为所有信息都在那里,但它会超出编译器的义务。严格解释代码,没有类型不匹配,所以可以编译。

数组文字是动态数组的另一个副作用是您拥有的代码实际上会分配内存。它在堆上分配动态数组,复制到静态数组中,然后你必须等待一个垃圾回收周期才能回收内存。如果您在紧密循环中初始化这样的数组,这可能会导致性能不佳。

同样,编译器可以避免分配,但 DMD 至少在当前版本 (2.060) 中没有。

于 2012-12-18T14:31:54.063 回答
7

那是因为[1, 2](动态数组) 的类型不保留数组中元素的数量,所以当编译器到达赋值 ( =) 时,它不知道右边的表达式中有多少元素边。

简单地说:编译器根本不够聪明。

于 2012-12-18T12:08:22.727 回答
0

可能是因为这条线:

int[3] my_array = [1, 2];

在左侧,您说的是数组中的 3 个值,即您正在定义static array of 3 ints,但仅分配两个值。

将其更改为:

int[3] my_array = [1, 2, 3];

问题应该得到解决。

于 2012-12-18T11:38:45.280 回答