D2, array.reverse property has a side-effect. orz
Tech 2011/07/12 17:29속도를 위한 최적화는 별로 없고, 그냥 무난하면서 Out-of-memory를 띄우지 않을 정도의 코드만 만들고 끝내야지 ~ 했는데, 테스트가 계속 실패한다. 각 Row에서 퀸의 위치를 Bit flag로 나타내는 식으로 보드를 저장하고 있었고, 실패하는 코드는 "현재 Queen의 위치 리스트" + "이번 Row에 놓고 싶은 Queen의 위치" 를 받아서 유효한지를 돌려주는 함수 부분이다.
테스트는 그냥 가볍게 이번에 놓고 싶은 Queen의 위치 - Row, Col - 에서 위로 한칸씩 올라가며 3개씩 확인하는 방식으로 했다.
(Row-2, Col), (Row-2, Col-2), (Row-2, Col+2)
...
(Row-k, Col), (Row-k, Col-k), (Row-2, Col+k)
이렇게 지금까지 놓인 Queen의 위치 리스트를 역으로 올라가면서 테스트를 하고 싶어서 이런 코드를 만들었다.
bool validate(in uint[] cur, in uint c) {
uint l=c, r=c;
foreach(uint _c; cur.reverse) {
if (_c&c | _c&(l<<=1) | _c&(r>>=1))
return false;
}
return true;
} |
cur.reverse 가 뒤집힌 녀석을 리턴하는건지, 스스로를 뒤집는건지 잘 모르겠지만 cur 에 변화가 있다면 저기 달아놓은 in qualifier 가 못한다고 말해주겠지 - 라고 생각했다. in 은 const 를 강제하니까. 그리고 이녀석은 컴파일이 된다. 헤헤 안심 ~하고 다음으로 넘어가보자 했는데 ... 계속 테스트가 실패하네?
알아보니 reverse는, 1. 스스로를 뒤집고, 2. 그 뒤집은걸 리턴, 도 하는 녀석이다. 배열의 property 를 참조하면 배열 자체가 뒤집혀 버리는 상황. -_-; 뭐 이래? 거기까지면 괜찮은데 왜 컴파일이 된거야?. 어이가 없어서 위의 in 을 immutable 로 고치고 테스트 했는데, 역시 컴파일이 되고 실행도 된다. 아놔... ;; 결국 side-effect가 있는 property는 immutable, const 를 그냥 씹어 드신다는 뜻.
짧게 정리하면,
import std.stdio;
int main() {
immutable uint[] a=[1,2,3]; writeln(a); a.reverse; writeln(a);
return 0;
} |
이 코드가 컴파일+실행된다는 사실을 발견. ... 실행하면 [1, 2, 3] [3, 2, 1] 을 차례로 찍는다. 뭐라굽쇼? property 에 대해서는 수정 불가 조건을 검사하지 않는 것 같은데, 그 property가 side-effect 만땅 ... 이라는 암울한 상황이다. IRC에 가서 물어봤더니 돌아오는 대답은,
- Looks like a bug
- Those properties like reverse, sort will be deprecated.
였다. 으으, 아직 D 두번째 스펙이 불안정하다고는 하지만 이건 좀 지나친 거 아닌가 싶기도 하고.
-----
D 2.053, 2.054 에서 확인.
'Tech' 카테고리의 다른 글
| D2, array.reverse property has a side-effect. orz (8) | 2011/07/12 |
|---|---|
| Thrift in D (0) | 2011/05/15 |
| fix: ugly gitweb page (2) | 2010/12/12 |
| (1/2) Programming in clojure (4) | 2010/08/08 |
| 자바스크립트로 벽돌깨기를 만들어보고 싶은데 ... ... (5) | 2010/07/24 |
| Bit count with CUDA (T_T) (2) | 2010/05/16 |


