a = ({b = 3; b + 4;})

tombraid의 이미지

a = ({b = 3; b + 4;})

리눅스 커널에 있는 container_of 라는 매크로를 풀어 보니 대략 이런 류의 코드가 되네요.

대략 어떻게 되는거다 라는건 알겠는데..

이거 원래 C 문법에 맞는 코드 인가요?

어떤 식의 처리가 되는거죠?

익명 사용자의 이미지

원형을 함께 보여주셔야 용도를 설명해 드릴 수 있을 것 같습니다.

cinsk의 이미지

tombraid의 이미지

감사합니다.

조회해보면 답이 있을것도 같았는데..

뭐라고 조회해야할지 키워드가 안떠오르더라구요...^^;;

익명 사용자의 이미지

a = ({b = 3; b + 4;})

{} 함수라고 생각하시고
b+4는 return값이라고 생각하면 되지 않을까요?
결과적으로 a = 7; 과 같은 코드 아닌가요?

tombraid의 이미지

같은 매크로에 대한 이야기라서 그냥 여기다 질문을 추가 합니다.

container_of 라는 매크로가 있는데요. 다음과 같습니다.

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

/* 아래는 프리프로세서 해석한 것입니다. */
dev = ({const typeof( ((struct scull_dev *)0)->cdev) *__mptr = (inode->i_cdev); \
      (struct scull_dev *)( (char *)__mptr - ((size_t) &((struct scull_dev *)0) -> cdev) );})

매크로 내용은 보면 아시겠지만, 어떤 구조체 내에 있는 변수의 포인터를 이용하여 구조체의 포인터를 구하는 것입니다.

그런데 이때 왜 __mptr 이라는 변수를 굳이 선언해서 사용하는지 모르겠습니다.

변수 선언을 하지 않고 그냥 두번째 스테이트먼트만 으로 충분할 것 같거든요.

또, const typeof( ((type *)0)->member ) * 도 그냥 void * 면 충분할 것 같은데 왜 이렇게 썼을까요?

익명 사용자의 이미지

전통적으로 리턴값은 accumulator register(x86의 경우, AX/EAX)에 넣어 리턴하는게 보편적입니다.
위 수식의 경우, EAX에 있었던 최종값을 리턴했다고 볼 수 있고,
최종수식의 결과값이 될것으로 예측됩니다. 문장이 몇개 더 있다고 가정했을때도, 최종 결과(EAX의)가 리턴된다고 보는게 맞을 것이라는...
이 값이 보편적이겠지만, 믿을 수야 없겠지요. 이런 문장을 기술하는 것은 그리 좋아 보이지 않습니다.

doldori의 이미지

tombraid wrote:
그런데 이때 왜 __mptr 이라는 변수를 굳이 선언해서 사용하는지 모르겠습니다.

변수 선언을 하지 않고 그냥 두번째 스테이트먼트만 으로 충분할 것 같거든요.

또, const typeof( ((type *)0)->member ) * 도 그냥 void * 면 충분할 것 같은데 왜 이렇게 썼을까요?


제 생각에 처음 문장은 필요없는 것으로 보입니다. ptr의 형이
typeof( ((type *)0)->member )* 라는 것은 반드시 만족해야 할 전제조건이거든요.
그렇지 않으면 매크로의 의미가 없어지니까요. 처음 문장이 있다고 해서 더 안전해지는
것도 아니고요. 다음 코드로 충분할 듯 합니다.
#define container_of(ptr, type, member)                      \
       ( (type *)( (char *)(ptr) - offsetof(type,member) ) )

댓글 달기

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