Container_of 매크로
Linux 소스 스터디 입문을 했습니다.
"리눅스 커널과 디바이스드라이버 실습2" 라는 책을 구입 후 보는 중인데,
리눅스에서 주로 사용하는 자료구조 쪽을 공부하다보니,
(기준 리눅스 커널 버젼은 2.6.31 이라고 합니다.)
소스 내에 container_of(ptr, type, member) 이라는 매크로를 소개하네요..
이름만 봐서는 argument들의 container.. 즉, C언어이니 구조체를 리턴해줄 것으로 보이는데,
container의 주소값을 얻는데 사용하는 것 같습니다.
첫 느낌은 뭔가 디게 복잡하게 주소값을 얻어오는 기분입니다만.. 이게 최선인가;;
매크로는 아래와 같습니다.
#define offsetof(TYPE, MEMBER) ((unsigned long) & ((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *_mptr = (ptr); \
(type *)( (char *)_mptr - offsetof(type, member) ); })
실제로 console로 결과값을 돌려보고, 머리를 굴려봐도 머리에 잘 안들어오네요 ㅜㅜ
검색하다가 리뷰가 잘되어있는 주소 링크합니다.
http://rootfriend.tistory.com/197
http://kldp.org/node/58409
주요내용은 아래에 따로 펌~
gcc C 언어 확장 기능으로, (즉, 표준이 아니며, 다른 컴파일러에서 지원하지 않는..) compound statement (중괄호로 둘러싼 여러 statement)를 expression으로 해석하는 기능이 있습니다. 예를 들면:
({ int y = foo(); int z;
if (y > 0) z = y;
else z = - y;
z; })
로 쓴 것처럼, foo() 리턴 값의 절대값을 얻는 코드를 위와 같이 작성할 수 있습니다. 이 것은 C99 표준에서 inline function이 나오기 전에 매우 유용하게 썼던 기능입니다. expression에서 switch, for 등의 statement를 쓸 수 있는 등의 장점을 얻을 수 있었습니다. 실제로 GNU C library에 포함되어 있는 obstack에 관계된 대부분의 함수가 이 compound-statement expression을 써서 macro로 구현되어 있습니다. 물론 맨 마지막 statement의 값이, 이 compound statement의 값이 됩니다.
그런데, 이 기능은 현재 C++에서 쓸 경우, 임시 변수의 destructor가 불리는 순서가 바뀌는 등의 단점이 있기 때문에, C++로 쓸 우려가 있는 코드에서는 이 compound statement expression을 쓰지 말라고 권하고 있습니다.
개인적으로 간단한 수식으로 나올 수 있는 것이 아니라면 do { ... } while (0)을 써서 macro로 만들고, 어떤 값을 리턴할 필요가 있는 macro라면 inline function을 쓰는 것이 좋다고 생각합니다.
'나는 프로그래머다! > Linux' 카테고리의 다른 글
Linux - 시그널 Signal (Ctrl+c, Ctrl+z) (0) | 2018.05.13 |
---|---|
Linux - 디렉토리 용량 확인 (0) | 2018.05.13 |
임베디드 리눅스 시스템 스터디 (0) | 2017.09.26 |
top 명령어 (실시간 CPU 사용률 체크) (0) | 2017.08.04 |
쓰레드 함수 (pthread) 알아 보기 (2) | 2017.08.01 |
grep 명령어 - 문자열 패턴 검색 (0) | 2017.07.07 |
vi 편집기 기본 명령어 (0) | 2017.07.07 |
리눅스 기본 명령어 정리 (0) | 2017.07.07 |