일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 게임
- resource management class
- Smart Pointer
- 언리얼
- 참조자
- implicit conversion
- 다형성
- 상속
- 암시적 변환
- 비교 함수 객체
- 루아
- 영화 리뷰
- UE4
- reference
- 반복자
- Vector
- exception
- more effective c++
- virtual function
- effective stl
- Effective c++
- 티스토리챌린지
- lua
- 오블완
- 예외
- c++
- operator new
- 스마트 포인터
- 영화
- 메타테이블
Archives
- Today
- Total
스토리텔링 개발자
[Effective STL] 6. 컴파일러의 분석 오류 본문
728x90
항목 6. C++ 컴파일러의 어이없는 분석 결과를 조심하자
파일에 들어있는 int의 list를 복사하려는 예시
ifstream dataFile("ints.dat");
// 잘못 짜여진 코드
list<int> data(istream_iterator<int>(dataFile),
istream_iterator<int>());
- 컴파일은 잘 된다. 하지만, 런타임에 아무 일도 하지 않는다.
- 파일에서 데이터를 전혀 읽지 않으며,
- 심지어 리스트조차 만들지도 않는다.
- 사실 위의 코드는 list 객체를 선언하지도 않았고, 생성자를 호출하지도 않았다!
함수 선언문
// 아래는 모두 함수 선언문이다.
int f(double d);
int f(double (d)); // d를 둘러싼 괄호는 무시
int f(double); // 매개변수 이름이 빠진 버전
// 다른 형태의 함수 선언문 세 가지
int g(double (*pf)()); // pf라는 함수 포인터를 매개 변수로 받는다.
int g(double pf()); // pf에 포인터 표시(*)가 빠진 버전(유효한 문법이다.)
int g(double ()); // 매개변수 이름이 빠진 버전
- 위 두 가지 버전의 괄호 용법을 비교해보면..
- 매개 변수를 둘러싼 괄호는 무시해도 되는 괄호이다.
- 그냥 괄호는 함수의 매개 변수 리스트가 있음을 나타내는 것이다.
- 즉, 함수의 포인터임을 알리는 것이다.
처음 코드를 다시 해석해보자
// 이는 사실, 리스트 객체가 아니라 data라는 이름의 함수를 선언한 것이다.
list<int> data(istream_iterator<int>(dataFile),
istream_iterator<int>());
// 즉, 아래 형태와 동일하다.
list<int> data(istream_iterator<int> dataFile,
istream_iterator<int> (*noname_param)())
- 위와 비슷한 실수..
class Widget { ... };
Widget w(); // 함수 w를 선언한 것으로 해석된다..
동작하도록 수정하는 방법
list<int> data((istream_iterator<int>(dataFile)), // 첫 매개변수에 괄호가 추가되었다.
istream_iterator<int>());
- 하지만 위 코드도 모든 컴파일러에 통용되는 것은 아니었다..
- 몇몇 컴파일러는 심지어 맨 처음 코드처럼 틀리게 선언해야 동작했다.
- 당연히 이는 코드의 이식성을 떨어뜨린다.(컴파일러가 잘못한 것!)
- 이제는... 웬만한 컴파일러들은 괜찮지 않을까?
더 좋은 방법
- istream_iterator들을 익명(annoymous) 객체 선언 하지 말고 이름을 만들어준다.
ifstream dataFile("ints.dat");
istream_iterator<int> dataBegin(dataFile);
istream_iterator<int> dataEnd;
list<int> data(dataBegin, dataEnd);
- 이 방법은 STL 프로그래밍 스타일에 어울리는 방법은 아니지만..
- 컴파일러와 프로그래머 모두에게 혼란을 주는 코드보다는 낫다.
728x90
'개발 > Effective STL' 카테고리의 다른 글
[Effective STL] 8. auto_ptr 금지 (0) | 2024.11.12 |
---|---|
[Effective STL] 7. 컨테이너 요소 new, delete 짝 맞춤 문제 (0) | 2024.11.11 |
[Effective STL] 5. 범위 멤버 함수(Range Member Function) (0) | 2024.11.07 |
[Effective STL] 4. 빈 컨테이너인지 확인하기 (0) | 2024.11.04 |
[Effective STL] 3. 컨테이너 요소 복사 (0) | 2024.10.31 |
Comments