【问题标题】:Are compound statements lvalue (or rvalue) in C?复合语句是 C 中的左值(或右值)吗?
【发布时间】:2025-12-26 06:35:12
【问题描述】:

当我检查 Linux 内核中 container_of 宏的定义时, 我看到复合语句是一个宏定义,

#define container_of(ptr, type, member) ({                      \
    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) );})

但是,在我看来,不清楚的问题是哪个语句被视为右值。 显然最后一条语句的结果被用作右值,但是为什么呢?

(type *)( (char *)__mptr - offsetof(type,member) );

例如,下面的代码示例在 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;
}

复合语句中变量的赋值规则是什么?

【问题讨论】:

    标签: c compound-assignment


    【解决方案1】:

    ({}) 是 C 的 GNU 扩展,称为 语句表达式

    http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

    在 C 中,复合语句是一个语句,并且语句不能在表达式中使用。

    【讨论】:

      【解决方案2】:

      您看到的是语句表达式,而不是复合语句。 语句表达式是标准 C 语言中不存在的 GCC 扩展。

      在 GCC 中,语句表达式“按值”返回它们的结果,这意味着它们的结果是右值。这实际上与 C 语言的一般“哲学”一致:在 C 中,几乎任何对左值对象的操作都会使它们迅速失去左值性并变成右值。 (在这方面,C 与 C++ 几乎相反。C++ 试图尽可能长时间地保持左值性。)

      【讨论】: