2018년 3월 19일 월요일

stringify


linux 소스를 보던중 stringify 매크로 함수가 나와서 신기하다고 생각되어 정리해 보았습니다.

정의는 아래와 같이 되어있습니다.


/* Indirect stringification.  Doing two levels allows the parameter to be a
 * macro itself.  For example, compile with -DFOO=bar, __stringify(FOO)
 * converts to "bar".
 */

/include/linux/stringify.h
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)

자세한 설명은 아래링크를 참고 하면 됩니다.
https://en.wikipedia.org/wiki/C_preprocessor C 매크로 중 #에 대한 처리입니다. Token stringification 부분을 보면 됩니다.

매크로 내에서 # 기능

# 는 인자로 받은 토큰을 문자열로 만듭니다.

예제)
#include <stdio.h>

#define str(s) #s

main()
{
 printf(str(abc));

}

출력
abc

소스를 치환하여 printf(#abc); 라고 하면 오류가 발생합니다.
----------------------------------------------------

예제)
#include <stdio.h>

#define str(s) #s

main()
{
 printf("Hello\n");
 printf(str(p = "foo\n";)); // outputs "p = \"foo\\n\";"
}

출력
Hello
p = "foo\n";

----------------------------------------------------

__stringify

처음으로 다시 돌아오면
__stringify매크로는 두번의 매크로 구성으로 되어있습니다. 결과는 기본적으로 위의 예와 동일합니다. 하지만 두번을 거치면서 새로운 기능이 생기게 됩니다.
예제)
#include <stdio.h>

#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)

main()
{
 printf(__stringify(abc));

}

결과
abc

----------------------------------------------------

매크로 안의 값의 정의가 한번더 있다면 풀어서 매크로 string으로 변환하는 작업을 합니다.
예제)
#include <stdio.h>

#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)

#define abc 123

main()
{
 printf(__stringify(abc));

}

결과
123


매크로 내에서 ... 기능

추가로 매크로 내의 ... 의 기능적 차이점을 예를 들어 알아보겠습니다.
... 를 사용하게되면 함수 인자로 구별하기위한 "," 또한 문자열로 전달이 됩니다.
예제)
#include <stdio.h>

#define str1(s) #s
#define str2(s...) #s

#define abc 123

main()
{
 printf(str1(abc)"\n");
 printf(str2(abc)"\n");
 printf(str1(a b c)"\n");
 printf(str2(a b c)"\n");
 //printf(str1(a,b,c)"\n"); => 에러발생
 printf(str2(a,b,c)"\n");

}

결과
abc
abc
a b c
a b c
a,b,c

댓글 없음:

댓글 쓰기