libgslutil  1.2.3
Macros
C structure macros

Macros

#define BUILD_ASSERT(cond)   do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
 
#define BUILD_ASSERT_OR_ZERO(cond)   (sizeof(char [1 - 2*!(cond)]) - 1)
 
#define check_type(expr, type)   ((typeof(expr) *)0 != (type *)0)
 
#define check_types_match(expr1, expr2)   ((typeof(expr1) *)0 != (typeof(expr2) *)0)
 
#define ARRAY_SIZE(arr)   (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr))
 
#define container_of(member_ptr, containing_type, member)
 
#define container_off(containing_type, member)   offsetof(containing_type, member)
 
#define container_of_var(member_ptr, container_var, member)   container_of(member_ptr, typeof(*container_var), member)
 
#define container_off_var(var, member)   container_off(typeof(*var), member)
 

Detailed Description

A set of macros for simple, standardised manipulation of C structures.

These macros are taken from CCAN (http://ccodearchive.net/) and are licensed in the public domain.

Macro Definition Documentation

◆ BUILD_ASSERT

#define BUILD_ASSERT (   cond)    do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)

BUILD_ASSERT - assert a build-time dependency.

Parameters
condthe compile-time condition which must be true.

Your compile will fail if the condition isn't true, or can't be evaluated by the compiler. This can only be used within a function.

Example:

 #include <stddef.h>
 ...
 static char *foo_to_char(struct foo *foo)
 {
    // This code needs string to be at start of foo.
    BUILD_ASSERT(offsetof(struct foo, string) == 0);
    return (char *)foo;
 }

◆ BUILD_ASSERT_OR_ZERO

#define BUILD_ASSERT_OR_ZERO (   cond)    (sizeof(char [1 - 2*!(cond)]) - 1)

BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.

Parameters
condthe compile-time condition which must be true.

Your compile will fail if the condition isn't true, or can't be evaluated by the compiler. This can be used in an expression: its value is "0".

Example:

 #define foo_to_char(foo)                   \
     ((char *)(foo)                     \
      + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))

◆ check_type

#define check_type (   expr,
  type 
)    ((typeof(expr) *)0 != (type *)0)

check_type - issue a warning or build failure if type is not correct.

Parameters
exprthe expression whose type we should check (not evaluated).
typethe exact type we expect the expression to be.

This macro is usually used within other macros to try to ensure that a macro argument is of the expected type. No type promotion of the expression is done: an unsigned int is not the same as an int!

check_type() always evaluates to 0.

If your compiler does not support typeof, then the best we can do is fail to compile if the sizes of the types are unequal (a less complete check).

Example:

 // They should always pass a 64-bit value to _set_some_value!
 #define set_some_value(expr)           \
    _set_some_value((check_type((expr), uint64_t), (expr)))

◆ check_types_match

#define check_types_match (   expr1,
  expr2 
)    ((typeof(expr1) *)0 != (typeof(expr2) *)0)

check_types_match - issue a warning or build failure if types are not same.

Parameters
expr1the first expression (not evaluated).
expr2the second expression (not evaluated).

This macro is usually used within other macros to try to ensure that arguments are of identical types. No type promotion of the expressions is done: an unsigned int is not the same as an int!

check_types_match() always evaluates to 0.

If your compiler does not support typeof, then the best we can do is fail to compile if the sizes of the types are unequal (a less complete check).

Example:

 // Do subtraction to get to enclosing type, but make sure that
 // pointer is of correct type for that member. 
 #define container_of(mbr_ptr, encl_type, mbr)          \
    (check_types_match((mbr_ptr), &((encl_type *)0)->mbr),  \
     ((encl_type *)                     \
      ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr))))

◆ ARRAY_SIZE

#define ARRAY_SIZE (   arr)    (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr))

ARRAY_SIZE - get the number of elements in a visible array

Parameters
arrthe array whose size you want.

This does not work on pointers, or arrays declared as [], or function parameters. With correct compiler support, such usage will cause a build error (see build_assert).

◆ container_of

#define container_of (   member_ptr,
  containing_type,
  member 
)
Value:
((containing_type *) \
((char *)(member_ptr) \
- container_off(containing_type, member)) \
+ check_types_match(*(member_ptr), ((containing_type *)0)->member))
#define check_types_match(expr1, expr2)
Definition: gslutil.h:210
#define container_off(containing_type, member)
Definition: gslutil.h:295

container_of - get pointer to enclosing structure

Parameters
member_ptrpointer to the structure member
containing_typethe type this member is within
memberthe name of this member within the structure.

Given a pointer to a member of a structure, this macro does pointer subtraction to return the pointer to the enclosing type.

Example:

 struct foo {
    int fielda, fieldb;
    // ...
 };
 struct info {
    int some_other_field;
    struct foo my_foo;
 };
 static struct info *foo_to_info(struct foo *foo)
 {
    return container_of(foo, struct info, my_foo);
 }

◆ container_off

#define container_off (   containing_type,
  member 
)    offsetof(containing_type, member)

container_off - get offset to enclosing structure

Parameters
containing_typethe type this member is within
memberthe name of this member within the structure.

Given a pointer to a member of a structure, this macro does typechecking and figures out the offset to the enclosing type.

Example:

 struct foo {
    int fielda, fieldb;
    // ...
 };
 struct info {
    int some_other_field;
    struct foo my_foo;
 };
 static struct info *foo_to_info(struct foo *foo)
 {
    size_t off = container_off(struct info, my_foo);
    return (void *)((char *)foo - off);
 }

◆ container_of_var

#define container_of_var (   member_ptr,
  container_var,
  member 
)    container_of(member_ptr, typeof(*container_var), member)

container_of_var - get pointer to enclosing structure using a variable

Parameters
member_ptrpointer to the structure member
container_vara pointer of same type as this member's container
memberthe name of this member within the structure.

Given a pointer to a member of a structure, this macro does pointer subtraction to return the pointer to the enclosing type.

Example:

 static struct info *foo_to_i(struct foo *foo)
 {
    struct info *i = container_of_var(foo, i, my_foo);
    return i;
 }

◆ container_off_var

#define container_off_var (   var,
  member 
)    container_off(typeof(*var), member)

container_off_var - get offset of a field in enclosing structure

Parameters
vara pointer to a container structure
memberthe name of a member within the structure.

Given (any) pointer to a structure and a its member name, this macro does pointer subtraction to return offset of member in a structure memory layout.