2012-12-18 4 views
7

나는 다음과 같은 코드를 가지고 :왜 컴파일 타임에 배열 리터럴 크기 불일치가 잡히지 않습니까?

import std.stdio; 

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

이는 잘 컴파일하고 중단 실행될 때이 오류를 제공합니다 :

arrays_init 
[email protected]/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 개 항목이있는 경우이 잘 실행되므로 분명히 배열 리터럴은 정적 배열의 크기와 일치해야합니다. 하지만 컴파일 타임에 양쪽 모두의 크기를 계산할 수 있으므로 컴파일 오류가 발생하지 않아야합니까? 아마 때문에이 라인의

답변

9

배열 리터럴은 T[] 유형입니다. 즉, 컴파일 타임에 크기가 인식되지 않는 동적 배열입니다.

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

컴파일러는 단순히 xs가 얼마나 큰지 알 수 없습니다 :

코드는 다음과 컴파일 같은 이유로 컴파일합니다.

귀하의 경우, 컴파일러 은 모든 정보가 포함되어 있으므로은 컴파일 시간에 알 수 있지만 컴파일러가 수행해야 할 작업을 위주로 수행해야합니다. 코드를 엄격하게 해석하면 유형 불일치가 없으므로 컴파일됩니다.

동적 배열 인 배열 리터럴의 또 다른 부작용은 실제로 갖고있는 코드가 실제로 메모리를 할당한다는 것입니다. 힙에 동적 배열을 할당하고 정적 배열에 복사 한 다음 메모리를 회수하기 전에 가비지 수집주기를 기다려야합니다. 좁은 루프에서 배열을 초기화하면 성능이 저하 될 수 있습니다.

컴파일러 이 할당을 피할 수 있지만 DMD는 적어도 현재 버전 (2.060)에는 없습니다.

+0

+1 : 정답입니다! –

+0

다행히 OP의 코드가 더 이상 할당되지 않도록 계획을 세우는 것이지만 (이 경우 오류가 발생할 수 있음) TODO 목록에서 아직 완료되지 않은 상태입니다 . –

+0

아마 그들은 정적 배열을 초기화하기 위해 C 배열 리터럴 구문을 사용할 수 있습니다. – Scooter

0

: 당신이 static array of 3 ints를 정의하지만이 개 값을 할당하는 즉 왼쪽에

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

당신은 배열에있는 3 개 값을 말하고있다. 에

변경을 :

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

및 문제 해결을하셔야합니다.

+2

완전히 오해하는 방법? –

+0

@CyberShadow : 예, 처음 보았습니다. – Azodious

+2

두 번째로. –

7

[1, 2] (동적 배열)의 유형은 배열의 요소 수를 유지하지 않기 때문에 컴파일러가 할당 (=)에 도달 할 때까지 얼마나 많은 요소가 있는지 알 수 없습니다 오른쪽에있는 표현에서.

간단히 말해서 컴파일러는 단순히 똑똑하지 않습니다.

+1

동적 배열의 .length 속성은 무엇을 말합니까? – Scooter

+1

@Scooter : length 속성은 _dynamic_ 즉 런타임 Thang입니다. 컴파일러는 이론적으로 컴파일 시점에이 모든 정보를 추론 할 수 있습니다. 그러나 그 언어는 그것을 요구하지 않으며 단순히 그렇게하지 않습니다. –

관련 문제