[완료] linux/list.h 에서 list_entry() 설명 부탁드립니다.

jtylor의 이미지

리눅스에서 사용하는 list 구조체를 보다가
이해가 가지 않아 질문여쭙습니다.

#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

list_entry()가 위와 같이 define이 되어있는데 무슨뜻인지 모르겠습니다.

자세한 것은 다음 링크를 봐주시기 바랍니다.
http://lxr.kelp.or.kr/source/include/linux/list.h?v=2.4.35#L187

추가적으로 아랫것도 설명 부탁드립니다.

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

clique의 이미지

embedding list를 구현할때 사용하는 기법(?)입니다.(BSD의 sys/queue.h에서 처음 등장했고요, Linux는 몇가지 다른 버전이 있더군요)

흔히 보통의 자료구조 교재에서 접하는 linked list등의 구현 방법은, 구조체에 다음 노드의 "시작"점을 포인팅하게 구현하죠.
이 방법은 직관적이고 이해하기 쉽지만, 일반 타입에 대해서 만들려면 노가다가 필요합니다.(c++ 등은 템플릿이 있어서 상관없고요)

그래서 나온 또 다른 방법이, link 정보를 구조체 안에 있는 변수에 넣어두고(위에 예제에선 member), 이 변수들이 다른 구조체에 접근할 수 있도록 하는 것입니다. 이렇게 하면.. 실제로 리스트에서는 다음 노드의 링크 변수에만 접근할 수 있습니다.(member)

그러나 우리가 원하는 것은 링크 변수가 아닌, 링크 변수를 가진 구조체의 시작점이죠. 이 구조체의 시작점을 계산하는 매크로가 list_entry입니다. gcc extension에서는 offsetof라는 연산자를 지원하기도 하는데, 그렇지 않을 경우에는 가상의 구조체 만든 후(0을 구조체 타입으로 캐스팅했죠) 링크 변수의 주소에서 링크 변수의 구조체 시작점에서의 오프셋을 뺍니다. 이렇게 계산하면 실제 구조체의 시작점 주소가 반환되겠죠.

jtylor의 이미지

설명 보고 쉽게 이해했습니다.
감사합니다.

bootmeta의 이미지

C++ 처럼 C에서 object를 구현할 때, 애용되는 기법입니다.
위 매크로를 사용하면 실제 구현 list의 node type과 상관없이 code 재사용이 가능합니다.
즉 node type마다 관련 method를 따로 구현할 필요가 없습니다.

예를 들어

/* pseduo code */
 
struct string_node {
   char *data;
   struct string_node *next;
};
 
struct int_node {
   int data;
   struct int_node *next;
};
 
 
struct string_node s_node;
struct string_node i_node;
 
...
...
 
struct string_node s_next = list_entry(s_node, string_node, next);
struct int_node i_next = list_entry(i_node, int_node, next);

댓글 달기

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