140 likes | 338 Views
No #define. With C++. 과 목 명 : 객체지향프로그래밍 II 교 수 명 : 정 훈 영 학 생 명 : 박상욱 , 오윤석 , 한상우 학 과 명 : 게임프로그래밍 2B 제 출 일 : 2013 / 09 / 10. * Index *. 1. #define 매크로 상수화의 문제 2. const 를 이용한 상수화 대안과 유의할 점 2 -1) const 상수 포인터 2-2) 클래스 정적 멤버 변수 초기화
E N D
No #define With C++ 과 목 명 : 객체지향프로그래밍II 교 수 명 : 정 훈 영 학 생 명 : 박상욱,오윤석,한상우 학 과 명 : 게임프로그래밍 2B 제 출 일 : 2013 / 09 / 10
* Index* 1. #define 매크로 상수화의 문제 2. const를 이용한 상수화 대안과 유의할 점 2-1) const 상수 포인터 2-2) 클래스 정적 멤버 변수 초기화 2-3) 이 것은 의미가 있는가? 3. enum을 이용한 상수화 대안 3-1) 열거형 자료는 int형 공간에 저장가능하다. 3-2) 나열자 둔갑법(enum hack) 3-3) #define과 동작 방식이 비슷하다? 4. 매크로 함수와 inline 함수 5. 상우’s 탈탈탈~
1. #define 매크로 상수화의 문제 1) 매크로란? 한 번 정의하고 나면 계속 사용 가능한 것 2) 문제점 - 디버깅 시 사용자 정의 심볼이 아닌 숫자로 표기되어 의미 확인이 힘들다. - 전 처리 시점에 코드가 치환 되어 목적코드(obj)의 용량이 늘어난다. - 유효 범위가 없어 강제로 전역 공개 됨.
2. const를 이용한 상수화 대안과 유의할 점 • const 상수 포인터 - 포인터 변수의 값(내용)을 고정 시킴-> 상수화 ex> char * const str = "흐흐흐“; - 포인터 변수의 자료형을 고정 시킴 ex> const char * str3 = "흐흥";
2. const를 이용한 상수화 대안과 유의할 점 2) 클래스 정적 멤버 변수 초기화 - 정의 영역에서는 정적 정수형(char, bool등) 혹은 열거형타입외에는 초기화 할 수 없다. From Working Draft, Standard for Programming Language C++ Class kku { //const static float fl = 3.5f; <- 컴파일 에러 const static int in = 3; <- 컴파일 성공 }; Const intkku::fl = 3.5f; <- 위의 에러 해결 방법
2. const를 이용한 상수화 대안과 유의할 점 3) 이 것은 의미가 있는가? #define PREPROCESSOR_DEFINE 3 Class kku { const static int in1 = PREPROCESSOR_DEFINE; }; Void main() { int a = kku::in1; int b = PREPROCESSOR_DEFINE; }
3. enum을 이용한 상수화 대안 • 열거형자료는 int형 공간에 저장 가능하다. - 열거형 자료는 int형인가? 그렇게 취급해도 차이는 없는가? 컴파일러의 기호테이블에 등록이 안될 수도 있다. 디버깅에서 차이가 난다. 2) 나열자 둔갑법(enum hack) - 1)이 성립하기에 가능한 방법 - 컴파일러가 상수화에 대하여 제약 조건이 많아도 거의 가능하다. Class kku { Enum{ ENUM_HACK = 5 }; IntiArr[ENUM_HACK ]; <- 이런 식의 정의가 성립함 };
3. enum을 이용한 상수화 대안 3) #define과 동작 방식이 비슷하다? - 두 방법 모두 데이터 영역의 상수이므로 주소를 받아오는 것이 금지 되어있다. - const 상수와 달리 런타임 시 메모리 공간을 따로 차지 하지 않음(코드 영역 제외) - 컴파일러 차원에서 기호 테이블에 사용자 정의 심볼이 등록된다는 점은 다르다.
4. 매크로 함수와 inline 함수 1) 매크로 함수 (1) 매크로 함수를 쓰는 이유? - 함수 호출 오버헤드(function call)로 인한 비용을 감소 시키기 위한 목적 호출 지점 일시 중지 -> 함수 포인터로 해당 함수 영역 탐색 -> 해당 함수의 스택 영역 생성 -> 해당 함수의 코드 실행 -> 반환형 처리 -> 호출 지점 복귀 (2) 단순 치환이기 때문에 의도하지 않은 연산 결과가 나올 수 있다. - 파라미터로 넣을 곳에 연산자 잘못 넣거나 하면…. (3) 매크로 함수는 디버깅이 불가능하다. (4) 데이터 형을 별도로 지정할 수가 없다. (함수 시그니쳐가 없음)
5. 매크로 함수와 inline 함수 2) inline 함수 (1) 특성? - 컴파일러 차원에서 호출 지점에 inline 함수의 내용을 그대로 붙여넣음. -> 이로 인해 function call이 발생하지 않아 빠르다. 대신 용량 UP (2) 엄연히 함수이기 때문에 시그니쳐가 존재 - 일반 함수 처럼 유효 범위를 가질 수 있다. (단, 매크로 함수도 자신이 포함된 구현부 파일기준으로는 별도로 취급하므로 같은 이름의 다른 기능으로 활용할 수는 있다. ) - 디버깅을 통해 탐색 가능하다. - 시그니쳐 지정이 가능하다.
인라인함수!= 매크로함수 #define MAX(a, b) Picasso((a) > (b) ? (a) : (b)) void Picasso(int temp) { printf("큰수: %d\n", temp); } inline void Max(int a, int b) { Picasso(a > b ? a : b); } void max(int a, int b) { Picasso(a > b ? a : b); }
매크로 함수 MAX(++a, b); movedx, DWORD PTR _a$[ebp] add edx, 1 mov DWORD PTR _a$[ebp], edx moveax, DWORD PTR _a$[ebp] cmpeax, DWORD PTR _b$[ebp] jle SHORT $LN3@main movecx, DWORD PTR _a$[ebp] add ecx, 1 mov DWORD PTR _a$[ebp], ecx movedx, DWORD PTR _a$[ebp] mov DWORD PTR tv70[ebp], edx jmp SHORT $LN4@main $LN3@main: moveax, DWORD PTR _b$[ebp] mov DWORD PTR tv70[ebp], eax $LN4@main: movecx, DWORD PTR tv70[ebp] push ecx call ?Picasso@@YAXH@Z; Picasso add esp, 4 인라인 함수 Max(++a, b); movecx, DWORD PTR _a$[ebp] add ecx, 1 mov DWORD PTR _a$[ebp], ecx movedx, DWORD PTR _a$[ebp] cmpedx, DWORD PTR _b$[ebp] jle SHORT $LN7@main moveax, DWORD PTR _a$[ebp] mov DWORD PTR tv85[ebp], eax jmp SHORT $LN8@main $LN7@main: movecx, DWORD PTR _b$[ebp] mov DWORD PTR tv85[ebp], ecx $LN8@main: movedx, DWORD PTR tv85[ebp] push edx call ?Picasso@@YAXH@Z; Picasso add esp, 4
일반 함수 max(++a, b); movedx, DWORD PTR _a$[ebp] add edx, 1 mov DWORD PTR _a$[ebp], edx moveax, DWORD PTR _b$[ebp] push eax movecx, DWORD PTR _a$[ebp] push ecx call ?max@@YAXHH@Z; max add esp, 8 moveax, DWORD PTR _a$[ebp] cmpeax, DWORD PTR _b$[ebp] jle SHORT $LN3@max movecx, DWORD PTR _a$[ebp] mov DWORD PTR tv65[ebp], ecx jmp SHORT $LN4@max $LN3@max: movedx, DWORD PTR _b$[ebp] mov DWORD PTR tv65[ebp], edx $LN4@max: moveax, DWORD PTR tv65[ebp] push eax call? Picasso@@YAXH@Z; Picasso add esp, 4 ; 18 : }