为什么在编译时没有捕获数组文字大小不匹配?

Sco*_*ter 7 d

我有以下代码:

import std.stdio;

int main(string[] args)
{
   int[3] my_array = [1, 2];
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

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]
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*der 9

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

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

void foo(int[] xs)
{
    int[3] ys = xs;
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

同样,编译器避免分配,但DMD至少不会在目前的版本(2.060).


Vla*_*eev 7

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

简单地说:编译器根本不够智能.