I am studying the Linux container_of
function and I find the use of parentheses of typeof is really confusing.
Here is the code of the function container_of
:
#define container_of(ptr, type, member) ({ \
const typeof( ((type*)0)->member) * __mptr =(ptr);\
(type*)( (char*)__mptr - offsetof(type,member) );})
At the second line, we have
const typeof( ((type*)0)->member) * __mptr =(ptr);
I do not understand why we use parentheses on the right side.
I search it online and find some similar usage. For example, from https://gcc.gnu.org/onlinedocs/gcc/Typeof.html , I found a function max(a,b)
#define max(a,b)
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
In this case, we do have similar usage typeof (a) _a = (a);
Why should we use parentheses on the right side? Can we remove the parentheses on the right side to make it typeof (a) _a = a;
?
Thanks in advance!
Macros created via #define
perform direct token substitution. Because of this, using parenthesis around the arguments of a function-like macro is good practice as it prevents unexpected issues from occurring.
For example:
#define multiply(x, y) x * y
If you were to use this macro here:
int z = multiply(1 + 3, 4 + 5) / 3;
You might expect z
to contain the value 12, but you would be mistaken.
It would expand the above to:
int z = 1 + 3 * 4 + 5 / 3;
Which would result in 14. Using parenthesis avoids this issue. If it was instead defined as:
#define multiply(x, y) ((x) * (y))
Then the above example would expand to:
int z = ((1 + 3) * (4 + 5)) / 3;
Which would give the expected result.