우리가 흔히 아는 문법인 do while은 잘 사용하지 않은 문법입니다.
하지만 라이브러리를 개발할 시에 do while 0 문은 아주 안정한 라이브러리 개발을 위해 반드시 사용해야할 usage가 있습니다.
지금부터 그것을 소개 해볼게요~
C나 C++로 작성된 라이브러리에서 많이 볼수 있는데
라이브러리 코드 내에서 매크로 함수의 사용성은 아주 많습니다.
라이브러리안 매크로 함수와 라이브러리를 사용하는 사용자의 코드간 문제를 한번 다뤄 보겠습니다.
#include <stdio.h>
#define SWAP(X, Y, T) { T t = X; X = Y; Y = t; }
int main()
{
int a = 10, b = 20;
if (true)
SWAP(a, b, int); // 별 문제 없을 것 같았지만, 여기서 문제가 생긴다!!!
else ;
}
사용자가 괄호가 없는 if 문을 사용 할수 있습니다.
그 내부에서 매크로 함수를 호출 했고, 여느 때와 같이 세미콜론을 찍었습니다.
하지만 저 코드에서 컴파일 에러가 납니다. 매크로 함수를 원형대로 치환해보겠습니다.
#include <stdio.h>
#define SWAP(X, Y, T) { T t = X; X = Y; Y = t; }
int main()
{
int a = 10, b = 20;
// if (true)
// SWAP(a, b, int);
// else// ;
// 위 문장들은 아래 코드로 치환된다.
if (true)
{
int t = a;
a = b;
b = t;
};
else ;
}
문제가 보이십니까?
if를 끝내고 else가 시작하기전에 괄호를 닫고 세미콜론이 하나 있습니다.
#include <stdio.h>
#define SWAP(X, Y, T) { T t = X; X = Y; Y = t; }
int main()
{
int a = 10, b = 20;
// if (true)
// SWAP(a, b, int);
// else// ;
// if (true)
// { int t = a; a = b; b = t; };
// else// ;
// 약간 정리해보면..
if (true)
{
int t = a;
a = b;
b = t;
} ; // <----------------- 여기!!!!!!!!!!!!!!!!!
else ;
// 이렇게 치환되는데..
// 이게 왜 문제냐면..
// if (true) 블럭이 끝나자마자 세미콜론(;)이 있기 때문입니다!
}
사용자는 매크로함수의 이름만 보고 호출할 것이고 사용자는 충분히 괄호 없는 if를 사용할수 있습니다.
이때 빛을 발휘하는 것이 do while 0 문 입니다.
위 코드를 do while 0 문으로 바꿔 보겠습니다.
#include <stdio.h>
int main()
{
int a = 10, b = 20;
// 아래 코드에서는 문제가 발생하지 않는다!
if (true)
do {
int t = a;
a = b;
b = t;
} while (0);
else ;
}
이 것을 다시 매크로 함수로 바꿔보겠습니다.
#include <stdio.h>
// 중괄호를 매크로 함수로 묶는 것보다... 아래처럼 do while로 정의할 것..!
// Linux kernel code를 보면 아래와 같은 구문이 상당히 많다고 합니다!
#define SWAP(X, Y, T) \
do { \
T t = X; X = Y; Y = t; \
} while (0) // <------ 마지막에 세미콜론(;)을 붙이지 않습니다!
int main() {
int a = 10, b = 20;
// 아래 코드에서는 문제가 발생하지 않습니다!
if (true)
SWAP(a, b, int); // <------ 여기는 세미콜론(;)을 붙입니다!
else
;
}
리눅스 커널의 커널 라이브러리에 위와같은 매크로 함수가 굉장히 많다고 합니다.
[typedef] About typedef in Function Pointer (0) | 2023.07.25 |
---|---|
[함수 호출 규약] __cdecl, __clrcall, __stdcall, __fastcall, __thiscall ,__vectorcall (0) | 2023.07.25 |
[C] printf 구현하기 (0) | 2023.07.17 |