以下是 C 定义的语法是什么?

huangapple go评论58阅读模式
英文:

What's the syntax of following c define?

问题

#define sigemptyset(set) (*(set) = 0, 0) 中的 , 0) 是执行两个操作:首先将 set 指向的值设为0,然后返回0。

英文:

Following snippet is from mac sdk signal.h:

#define	sigemptyset(set)	(*(set) = 0, 0)

just wonder what does , 0) do?

答案1

得分: 3

宏展开为逗号表达式:首先评估左操作数,将set指向的对象设置为0,然后评估右操作数,其值为整个表达式的值,因此是:0

换句话说,该宏的行为类似于始终成功的函数,成功由返回值0表示。

除了类型检查外,该宏等效于:

#include <signal.h>;

int sigemptyset(sigset_t *set) {
    *set = 0;
    return 0;
}

请注意,&lt;signal.h&gt;头文件还包含此函数的原型:

int sigemptyset(sigset_t *);

在您的代码中,调用 sigemptyset(&amp;sigset) 调用了该宏,但您可以通过编写 (sigemptyset)(&amp;sigset) 或者取函数指针的方式强制引用库函数。该宏允许在不改变原型的情况下进行内联扩展。clang可以在链接时对小函数进行内联扩展,但对动态库中定义的函数则不行。

相同的技巧也适用于头文件中的其他函数,对于这些函数来说,需要 , 0) 以使表达式以 int 类型评估为 0

#define sigaddset(set, signo)   (*(set) |= __sigbits(signo), 0)
#define sigdelset(set, signo)   (*(set) &= ~__sigbits(signo), 0)
#define sigemptyset(set)        (*(set) = 0, 0)
#define sigfillset(set)         (*(set) = ~(sigset_t)0, 0)
英文:

The macro expands to a comma expression: the left operand, evaluated first, sets the object pointed to by set to 0, then the right operand is evaluated and its value is the value of the whole expression, hence: 0.

In other words, the macro behaves like a function that always succeeds, success indicated by the return value 0.

Except for the type checking, the macro is equivalent to:

#include &lt;signal.h&gt;

int sigemptyset(sigset_t *set) {
    *set = 0;
    return 0;
}

Note that the &lt;signal.h&gt; header file also contains a prototype for this function:

int sigemptyset(sigset_t *);

In your code, a call sigemptyset(&amp;sigset) invokes the macro, but you can force a reference to the library function by writing (sigemptyset)(&amp;sigset) or by taking a pointer to the function. The macro allows for inline expansion without a change of prototype. clang can perform inline expansion at link time for small functions, but not for functions defined inside dynamic libraries.

The same trick is used for other functions in the header file, for which the , 0) is necessary for the expression to evaluate to 0 with type int:

#define sigaddset(set, signo)   (*(set) |= __sigbits(signo), 0)
#define sigdelset(set, signo)   (*(set) &amp;= ~__sigbits(signo), 0)
#define sigemptyset(set)        (*(set) = 0, 0)
#define sigfillset(set)         (*(set) = ~(sigset_t)0, 0)

答案2

得分: 1

在这个表达式中

(*(set) = 0, 0)

使用了逗号操作符。

表达式的结果是0。

作为副作用,指针 set 指向的对象被设为了0。

根据C标准(6.5.17 逗号操作符)

2 逗号操作符的左操作数被评估为一个void表达式;它的评估和右操作数之间有一个序列点。然后评估右操作数;结果具有它的类型和值。

英文:

In this expression

(*(set) = 0, 0)

there is used the comma operator.

The result of the expression is 0.

As a side effect the object pointed to by the pointer set is set to 0.

From the C Standard (6.5.17 Comma operator)

> 2 The left operand of a comma operator is evaluated as a void
> expression; there is a sequence point between its evaluation and that
> of the right operand. Then the right operand is evaluated; the result
> has its type and value.

huangapple
  • 本文由 发表于 2023年2月13日 22:49:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75437469.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定