2

I was going through the lustre source code and was stuck at the macro definition:

#define ldlm_namespace_proc_unregister(ns)      ({;})  
#define ldlm_namespace_proc_register(ns)        ({0;})

defined in the file lustre/ldlm/ldlm_resource.c.
What does this macro definition signify?

2 Answers2

4

Macros are a plain text replacement. This macro means that a piece of code ldlm_namespace_proc_register(x) will be transformed to ({0;}). Nothing more and nothing less.

If you are also wondering about the meaning of the code ({;}) and ({0;}) then these are GCC expression statements.

According to that documentation, ({0;}) should be exactly the same as 0, and ({;}) is an expression of type void.


Speculation follows: the purpose of these macros might be to support the user of the library writing code like this:

int result = ldlm_namespace_proc_register(x);
// ...
ldlm_namespace_proc_unregister(x);

but also that depending on compiler switches or other configuration, this code may either actually call a function, or in the case where your lines are enabled, actually do nothing.

M.M
  • 130,300
  • 18
  • 171
  • 314
  • Thanks @M.M, one more question, so does it relate in any way to the return value of the function? – Bhagyesh Dudhediya Nov 24 '15 at 05:05
  • @bhagyeshdudhediya what function? – M.M Nov 24 '15 at 05:16
  • return value of `ldlm_namespace_proc_register();` – Bhagyesh Dudhediya Nov 24 '15 at 05:36
  • @bhagyeshdudhediya macros don't have return values . When these macros are active there is no function, the code `ldlm_namespace_proc_register(x);` is equivalent to the code `0;` – M.M Nov 24 '15 at 05:37
  • In the same file I have function definition for : `int ldlm_namespace_proc_register(struct ldlm_namespace *ns)` and also the macro `#define ldlm_namespace_proc_register(ns) ({0;})` and the call to function is `rc = ldlm_namespace_proc_register(ns);` That's why there is confusion about how would be the flow? – Bhagyesh Dudhediya Nov 24 '15 at 05:52
  • @bhagyeshdudhediya the macro is a text replacement. You probably do not actually have both of those things activated at once in the same file. There will be `#ifdef` or `#if` lines which select one or the other. You could inspect the result of preprocessing if your compiler supports it (e.g. for gcc use the `gcc -E` switch). – M.M Nov 24 '15 at 06:52
1

@bhagyesh: whatever M.M said is correct and If you see lustre/ldlm/ldlm_resource.c, In line 74 you have

74 #ifdef LPROCFS
   .......
   .......
 385 #undef MAX_STRING_SIZE
 386 #else /* LPROCFS */
 387
 388 #define ldlm_namespace_proc_unregister(ns)      ({;})
 389 #define ldlm_namespace_proc_register(ns)        ({0;})
 390

 391 #endif /* LPROCFS */

So here these functions are getting manipulated depending on defination of LPROCFS. I think It is visible now.

And about your question..

Thanks @M.M, one more question, so does it relate in any way to the return value of the function? –

Here is small experiment in which it is clear...

#include<stdio.h>

#ifdef LPROCFS
int my_register(int x)
{
        int y = x*x;
        printf("In my_register val=%d\n", x);
        return y;
}

void my_unregister(int x)
{
        printf("In my_unregister val=%d\n", x);
}

#else

#define my_register(x) ({0;})
#define my_unregister(x) ({;})

#endif

int main ()
{
        printf("In main\n");
        int rc = my_register(2);
        my_unregister(3);
        printf("after returning rc=%d\n", rc);
        return 0;
}

When LPROCFS not defined..

[root@ashish-203 lustre-wc-rel]# ./test_directives
In main
after returning rc=0

When LPROCFS is defined...

[root@ashish-203 lustre-wc-rel]# ./test_directives
In main
In my_register val=2
In my_unregister val=3
after returning rc=4
[root@ashish-203 lustre-wc-rel]#
Ashish Maurya
  • 111
  • 1
  • 4