다음과 같은 오류가 났다.
cluster_gene_by_robust_region.cpp:99: error: passing ‘const CRobust_Position’ as ‘this’ argument of ‘void CRobust_Position::inc_gene_count(const int&)’ discards qualifiers
환경: GCC 4.4.6 on CentOS 6.3 (Kernel Linux 2.6.32-279.14.1.el6.x86_64)
그 쉽다는 컴파일 에러인데 쉽사리 이해가 되지 않는다. 에러 내용 자체는 const CRobust_Position 을 this 로 void CRobust_Position::inc_gene_count 함수로 넘기면 qualifier 를 버리게 되기 때문에 그렇게 넘길 수 없다는 이야기 이다. qualifer 를 버리게 된다는 것은 결국 const 로 설정한 것을 그대로 유지할 수 없다는 의미일텐데, 문제는 저 함수를 호출하는 것은 결코 const 로 되어 있지 않다. 즉,
92 bool merge_robust_position(const std::set<CRobust_Position>& op1, std::set<CRobust_Position>* op2)
93 {
94
95 std::map<std::pair<int,int>,int> pos2gene1;
96 std::map<std::pair<int,int>,int> pos2call1;
97 robust_position_to_map(op1, &pos2gene1, &pos2call1);
98
99 std::set<CRobust_Position>::iterator aa = op2->begin();
100 (*aa).inc_gene_count(1);
위에서 (디버깅하느로 잡코드가 있다) 보면 op2 는 pointer 로 받았고, 99 번 줄에서 iterator 로 [op2]의 원소들을 순회하고 있다. 따라서 100 번은 const 가 암묵적으로 들어 간 부분이 없다. inc_gene_count 함수는
52 void inc_gene_count(const int& inc) { /*_gene_count += inc;*/}
위처럼 되어 있다. 92, 99, 100 번 줄 어디에서도 inc_gene_count 함수가 const 일 것을 함축하는 부분이 없다. 보통 vector 같은 container 에는 const_iterator 가 iterator 와 따로 제공이 되고, const_iterator 를 사용할 경우 iterator 를 이용한 원소의 값 변경이 안되는 것에 반해 iterator 를 const_ 없이 사용할 경우 (위 99 번 줄 처럼) iterator 를 통한 값의 변경이 가능하다. 지금 위도 정확히 같은 경우인데 이 경우에는 값이 변경이 되지 않고 있다. discards qualifier 라는 에러 메세지에서 추측할 수 있는 것은 inc_gene_count 함수가 const member function 이어야 한다는 것이다. 실제로 그렇게 해서 compile 하면 에러는 없다.
그렇다면 왜 set 의 경우 iterator 를 통한 값의 변경이 안되는 것일까? 이것은 아마도 이럴 것이다. set 은 원소들의 검색을 빠르게 하기 위해 원소를 보통 정렬해서 저장하게 된다. 그런데 iterator 를 통해 원소의 어떤 값을 변경하게 되면 원소의 순서가 바뀌어야만 할 수도 있다. 그런데 성능을 최우선을 했던 STL 이 그렇게 비효율적으로 되어 있지는 않을 것이다. 즉, iterator 를 통한 원소의 값 변경 시 매번 원소를 재정렬해야 한다면 매우 비효율적일테고, 따라서 set 의 경우 비록 이름은 const_iterator 가 아닌 iterator 일지라도 이것을 통한 원소의 값 변경은 불가능한 것이다.
'컴퓨터 > 디버깅' 카테고리의 다른 글
긴 오류 메세지 알아 보기 (0) | 2013.05.22 |
---|---|
오랜 시행 후 프로그램이 멈추는 경우 - GDI 문제 (1) | 2013.01.01 |
less 를 찾을 수 없어서 에러가 난 경우 (0) | 2012.05.20 |
a required resource was unavailable (0) | 2011.08.07 |
cannot convert ... (0) | 2011.06.23 |