Home > Software design >  How can we give arguments to the token-pasting operator parameter specified in the Macro function?
How can we give arguments to the token-pasting operator parameter specified in the Macro function?

Time:12-09

I'm trying to use systemd's helper macros, but I don't quite understand the working mechanism. Systemd macros as below;

#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func)                 \
        static inline void func##p(type *p) {                   \
                if (*p)                                         \
                        *p = func(*p);                          \
        }

I did not understand how to give the "p" parameter as an argument in the macro I mentioned above. I would like to explain the problem with an example.

First of all, I created udev enumerate object;

struct udev_enumerate* enumerate = udev_enumerate_new(pudev);

When I want to delete this object later, how do I do it using the systemd macro?

DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate*, udev_enumerate_unref);

Type and function are specified according to the macro, but how is the "p" parameter in the macro (ie the object that I produced) specified in the macro?

CodePudding user response:

"p" is not a parameter. It's just a text "p". I guess it is intended to stay for word "pointer". I found the mentioned line at link. It looks that the macro is used to create a wrapper for a given cleanup functions that checks if the given pointer is not NULL and set the pointer to a cleaned object to the empty sentinel. I can guess that the trailing "p" is the naming convention used in this project. After a few cleanup functions created with this macro there are some others like freep() and unmaskp().

For example DEFINE_TRIVIAL_CLEANUP_FUNC(int, myclean) expands as:

static inline void mycleanp(int *p) {
    if (*p)
        *p = myclean(*p);
}

Assuming that the udev_enumerate_unref() is declared as:

struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate);

the wrapped can be created with:

DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate *, udev_enumerate_unref)

And used as:

struct udev_enumerate* enumerate = udev_enumerate_new(pudev);

... do stuff with `enumerate`

udev_enumerate_unrefp(&enumerate);
  • Related