C언어 매크로 함수 관련하여 궁금한점 있습니다

stock9343의 이미지

안녕하세요 C언어의 매크로 함수를
아래와 같이 사용하였습니다.

#define str(x) #x
#define trans(x) str(x)

#define list cell_a cellb
out = trans(list) ;

결과는 cell_a cell_b
가 나옵니다.
list의 값이 출력됨

추가적으로 trans매트로를 안쓰고
out=str(list)로 해버리니
결과는 list라는 변수명이
그대로 나옵니다.당연히 #라는 토큰때문에
문자 그대로 뽑힙니다

하지만, 위의 trans(x)조합시에는
값이 출력되는 원리가 궁금하네요.

김정균의 이미지

trans(x) 는 아래처럼 변경될 거고요.

out = trans(list);
-> out = trans(cell_a cellb);
-> out = str(cell_a cellb);
-> out = "cell_a cellb";

str(x) 는

out = str(list);
-> out = "list";

와 같이 변경 됩니다. "#" 은 문자열로 변환을 시킨다는 점에 주의 하셔야 합니다.

https://norux.me/22 참고 해 보시면 도움이 될 듯 싶습니다.

stock9343의 이미지

이해가 되었습니다

익명 사용자의 이미지

C preprocessor의 미묘한 동작 덕분입니다.

1. function-like macro의 macro replacement에서, 각 argument는 argument substitution 직전에 macro replaced 됩니다.

즉,

out = trans(list);
-> out = str(cell_a cellb); // trans(list)의 macro replacement 과정에서 list가 x 자리에 들어가기 전에
// 먼저 macro replaced 진행됨
-> out = "cell_a cellb";

2. 그런데 function-like macro의 parameter가 # operator의 뒤에 있는 경우는 예외가 됩니다. 이 때 argument는 macro replacement 없이 바로 string literal로 변환됩니다.

out = str(list)
-> out = "list"; // replacement-list에서 x가 # 뒤에 있었기 때문에,
// list는 cell_a cellb로 변환되지 않고 바로 string literal이 됨.

이런 특성을 활용하면 아래와 같은 코드를 작성할 수 있지요.

#include <stdio.h>
 
#define PRINT_INT(x) printf(#x " = %d\n", x)
#define short_name really_really_really_really_long_name
 
int main(void){
    int really_really_really_really_long_name = 1337;
 
    PRINT_INT(short_name);
    // 위 매크로는 아래와 같이 치환됨.
    // printf("short_name" " = %d\n", really_really_really_really_long_name)
    // 따라서 출력 결과는 "short_name = 1337"
    return 0;
}

stock9343의 이미지

덕분에 완전히 이해했습니다

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.