C/C++에서 #define 전처리기 정의를 이용해 매크로 함수를 만든 것을 종종 볼 수 있다.
#define abs(a) (((a) > 0) ? (a) : (-a)) // 절대값 계산
#define max(a,b) (((a) > (b)) ? (a) : (b)) // a, b 중 큰 값을 찾는다.
#define min(a,b) (((a) < (b)) ? (a) : (b)) // a, b 중 작은 값을 찾는다.
#define i2m(i) ((i)*25.4) // 인치 단위로 변환
#define m2i(m) ((m)/25.4) // 밀리미터 단위로 변환
보통 위와 같은 형태로.
그런데, 최근에 암호화 알고리즘 관련해 C로 된 소스 코드를 구해서 C#으로 컨버전을 하다 아무리 해도, 컨버전은 확실히 잘 됐는데, 이상하게도 결과가 맞지 않는 것이 있어 좀 들여다 봤더니...
정말 이상했다.
아래와 같은 매크로 함수가 예상과 다르게 동작하는 것이 아닌가?
아래 예제에서 a와 b의 결과는 어떻게 될까?
#define Func1(A, B) { \
A += B; \
A ^= B; B ^= A; \
}
int main()
{
DWORD a, b;
a = 15;
b = 20;
Func1(a, b);
printf("a: %d, b: %d\n", a, b);
return 0;
}
상식적으로 판단하기엔, DWORD는 unsigned long이므로 값 형식이다. 따라서 함수 호출 시 포인터로 넘겨주지 않았으므로 함수 호출 결과는 원래 DWORD 값에 영향을 미칠 수 없어야 한다.
그런데, 결과를 찍어보면
a: 55, b: 35
이렇게 바뀐 값으로 찍힌다.
아니, 이게 무슨??????
이렇게 생각하면 곤란하다. 나도 저렇게 생각했었다. 털썩;;;
조금만 더 생각해보면,
당연하게도, #define으로 정의된 매크로 함수는 함수가 아니라, 치환될 내용일 뿐이다.
즉, 위 예제를 실제로 실행될 때는 Func1(A, B); 부분이 #define으로 정의된 매크로 함수 내용으로 대체되는 것이다.
int main()
{
DWORD a, b;
a = 15;
b = 20;
{ a += b; a ^= b; b ^= a; }
printf("a: %d, b: %d\n", a, b);
return 0;
}
이렇게.
그러니까 값이 바뀌는 것이 당연.
매크로 함수가 함수처럼 생겼다고 함수로 오해하면 절~~대 안되겠다. 헐.
'Tech: > C·C++' 카테고리의 다른 글
C++ 컴파일 시 LNK 2019, LNK 2001/2005 링커 오류 대처법 (0) | 2013.07.03 |
---|---|
Calling Convention (함수 호출 규약) (0) | 2012.08.22 |
[펌] Win32 API FAQ (1) | 2008.06.26 |
VC++2005 배포 (0) | 2008.06.26 |
C++ 동기화 객체(Critical Section, Mutex, Semaphore, Event) (0) | 2008.06.26 |