티스토리 뷰

개발/Linux

offsetof 매크로

Jaeyeon Baek 2011. 12. 5. 19:03



구조체의 offset을 구할때 유용한 매크로. 일단 man page를 살펴봅시다.

OFFSETOF(3)                Linux Programmer’s Manual               OFFSETOF(3)

NAME
       offsetof - offset of a structure member

SYNOPSIS
       #include 
       size_t offsetof(type, member);

DESCRIPTION
       The  macro offsetof() returns the offset of the field member from the start of the structure
       type.

       This macro is useful because the sizes of the fields  that  compose  a  structure  can  vary
       across  implementations, and compilers may insert different numbers of padding bytes between
       fields.  Consequently, an element’s offset is not necessarily given by the sum of the  sizes
       of the previous elements.

       A  compiler error will result if member is not aligned to a byte boundary (i.e., it is a bit
       field).

RETURN VALUE
       offsetof() returns the offset of the given element within the given type, in units of bytes.

EXAMPLE
       On  a  Linux/x86  system,  when compiled using the default gcc(1) options, the program below
       produces the following output:

           $ ./a.out
           offsets: i=0; c=4; d=8 a=16
           sizeof(struct s)=16

       #include 
       #include 
       #include 

       int main()
       {
           struct s {
               int i;
               char c;
               double d;
               char a[];
           };

           /* Output is compiler dependent */

           printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
                   (long) offsetof(struct s, i),
                   (long) offsetof(struct s, c),
                   (long) offsetof(struct s, d),
                   (long) offsetof(struct s, a));
           printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));

           exit(EXIT_SUCCESS);
       }

CONFORMING TO
       POSIX.1-2001.

GNU                               2006-05-23                       OFFSETOF(3)
(END)


위와 같이 <stddef.h>를 include 하게 되면 사용할 수 있으며, 특정 구조체 멤버의 offset을 구할 수 있습니다. 위 manpage의 예제 같은 경우 compiler에 따라 약간씩 차이가 있을 수 있겠지만, 32bit compiler 의 경우 보통 아래와 같은 결과를 얻을 수 있을 것입니다.

offsets: i=0; c=4; d=8 a=16
sizeof(struct s)=16

이유는 이전 포스팅에서도 수차례 언급되었지만, ALIGN에서 오는 차이. linux-3.0.4 Kernel 의 경우 offsetof를 따라가면 아래와 같이 정의되어 있습니다.

#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
필요할때 적절하게 사용하도록 합시다.


'개발 > Linux' 카테고리의 다른 글

gdb 옵션  (0) 2011.12.20
function kernel_thread()  (0) 2011.12.15
Kernel ipt_get_entries struct .. size  (0) 2011.12.04
__alignof__, aligned 매크로  (0) 2011.12.02
Kernel Netfilter socket option (getsockopt, setsockopt)  (2) 2011.12.02
댓글
최근에 올라온 글
최근에 달린 댓글
글 보관함
Total
Today
Yesterday