When I examined the definition of the container_of
macro in Linux Kernel,
I saw a compound statement as a macro definition,
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
however the unclear issue in my mind is which statement gets taken into account as rvalue. Apparently result of the last statement is used as rvalue, but why?
(type *)( (char *)__mptr - offsetof(type,member) );
For instance, is the code example below legal in C?
int g_count = 0xFF;
#define GLOBAL_COUNT do {g_count;} while(0)
int main(int argc, char *argv[])
{
int local;
local = GLOBAL_COUNT;
local = 0;
GLOBAL_COUNT = local;
return 0;
}
What is the assignment rule for variables in compound statements?
({})
is a GNU extension to C called a statement expression:
http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
In C a compound statement is a statement and a statement cannot be used in an expression.
What you see is a statement expression, not a compound statement. Statement expression is a GCC extension that does not exist in standard C language.
In GCC statement expressions return their results "by value", meaning that their results are rvalues. This actually is in agreement with general "philosophy" of C language: in C virtually any manipulations over lvalue objects make them to quickly lose their lvalue-ness and turn into rvalues. (In this regard C is virtually opposite of C++. C++ attempts to preserve the lvalue-ness as long as possible.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With