[완료]#define 문에 관련된 질문입니다.

chsuk의 이미지

안녕하세요.
구글등에 열심히 찾았으나... 검색능력이 딸리는것인지.. 무식해서 그런건지..
찾아지지가 않네요. 실제 테스트를 해봤지만 에러만 뜨고.... 답답해서 질문을 드립니다.
혹시 아시는 분이 계시면 알려주시면 감사드리겠습니다.

#define aa(X,Y) X/**/Y

이런구문을 보신적이 있으신지요.
어떤 코드를 분석중인데 그 코드에 이런 구문이 있더군요.
이것은 어떤 용도로 사용하는지 당최 모르겠습니다. 단순히 미스 프린트라 하기엔..좀...
주석을 달려다 만것 같지도 않고..

현재는 X##Y 식으로 사용을 하지만 ifdef으로 예전 버전에는 위의 구문을 사용한 흔적이 있더군요.
저런식의 define문은 처음 본 뿐더러 한번 알아보고자 했으나 계속 에러만 뜨네요.

그럼..

수고하세요.

brucewang의 이미지

정말 목적을 파악하기가 힘든 매크로네요.

X##Y 처럼 string concatenation 을 의도로 하는것도 아니고..
실수가 아니라 일부러 한것이라고 가정하면, 아시는 바처럼
위 매크로는 파라미터로 전달된 expression 자체를 컴파일타임에
무조건 확장시켜 놓겠죠.

그러니까 심지어

int i;
aa(i, =3);

이렇게 하면 i에는 3이 입력될 것이고...

--> 지금 테스트를 해보니 결과는 X##Y와 완전히 동일한 결과가 나오네요..
printf( aa("aa", "bb" ) ); --> aabb

-------------------------------------------------
$yes 4 8 15 16 23 42

cppig1995의 이미지

X##Y는 string concatenation을 의도로 하는 게 아닙니다. token pasting입니다.
X/**/Y는 주석이 ""로 치환된다는 것을 가정하고(X/**/Y -> XY) 작성한 pre-ANSI token pasting 방법입니다. (구식이죠.)
하지만 ANSI C에서는 주석이 " "로 치환되기 때문에(X/**/Y -> X Y) token pasting이 되지 않습니다.
질문자님께서 사용하신 컴파일러는 아마 ANSI C 호환일 것이므로, 당연히 오류가 날 것입니다.

그리고, "aa""bb" = "aabb"이며 "aa" "bb" = "aabb"이고 "aa"와 "bb" 사이에 공백 문자가 몇 개 들어가든
문자열 리터럴은 알아서 붙습니다. ANSI C 표준에 명시돼 있죠. 따라서 brucewang님의 테스트는 잘못된 것입니다.
--
임수서룬뫼 윤희수 {cppig1995/돼지군}

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

brucewang의 이미지

아, 맞습니다 죄송합니다.

string concatenation이 아니라 Token concatenation 이었습니다.
(용어를 제대로 사용해야 겠다는 반성을 또 한번.. <-- 추가)

결국 /**/ 은 token 구분을 위한 의도로 사용되었군요.
"aa" "bb" = "aabb" 말씀은 알고 있는데 정말 잘못된 테스트 였네요.

-------------------------------------------------
$yes 4 8 15 16 23 42

Hyun의 이미지

오아... 도대채 희수군의 정체는...?

cppig1995의 이미지

지난번 어떤 인터프리터냐는 질문에 대한 답인데, 이전 스레드 끌어올리기 싫어서 여기 좀 빌립니다.
Squirrel(http://squirrel-lang.org)입니다. Lua랑 조금 비슷한데, 모습은 C/C++를 닮았죠.
요즘 프로그래밍 언어 하나 설계하고 실력 쌓은 다음 구현할 생각을 하고 있어서,
이것저것 스크립팅 언어들을 배워보고 있습니다.
--
임수서룬뫼 윤희수 {cppig1995/돼지군}

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

cppig1995의 이미지

예제 하나 첨부합니다.

#if defined(__STDC__)
# define PASTE(X, Y) X##Y
#else
# define PASTE(X, Y) X/**/Y
#endif
 
char *a1 = "a1", *a2 = "a2", *a3 = "a3", *ai = "ai";
printf("%s %s %s\n", PASTE(a, 1), PASTE(a, 2), PASTE(a, 3)); // a1 a2 a3
for(int i = 1; i <= 3; ++i) puts(PASTE(a, i)); // ai ai ai

--
임수서룬뫼 윤희수 {cppig1995/돼지군}

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

munamuna의 이미지

임수서룬뫼님의 답글을 보고서야

"아.. 이런 기능이 있었구나" 라는 기억을 떠올렸는데요..

이 기억과 함께.. 당시에 "이런거 뭐에쓰지?"라는 기억도 함께 떠올렸습니다.

고수님들이 계시는 이 기회에 질문 드립니다.

억지 예제를 만들자면 못만들 것은 없겠지만..

이러한 token pasting 이라는 기능이 "정말로 유용하게" 필요한 경우가 어떤 경우인가요?

정말 궁금합니다.

chsuk의 이미지

역시.. 무식하면 손발이 고생이라고..^^;;
한참을 고민했습니다.
덕분에 많이 배웠습니다.

감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.