5

没有定义的宏功能的用途/适用性是什么:

#ifndef __SYSCALL
#define __SYSCALL(a, b)
#endif

可以在 Linux 系统的头文件中找到这个宏/usr/include/asm/msr.h

我还注意到以下类型的宏。

#define _M(x) x

并且唯一的理由是定义这种我认为使代码统一的宏。就像在#define SOMETHING (1 << 0)中一样。这种宏还有其他隐藏(更好)的用途吗?

带有示例的答案将非常有帮助。也有人可以给我一个文本/链接来阅读这个。

4

5 回答 5

13

这种形式的宏最常见的情况之一:

#define _M(x) x

是为仅支持 C 的原始 K&R 方言的编译器提供向后兼容性,该方言早于现在无处不在的 ANSI C 方言。在该语言的原始 K&R 方言中,声明函数时未指定函数参数。1989 年,ANSI 对该语言进行了标准化并进行了许多改进,包括声明参数类型数量的函数原型。

int f(int x, double y); /* ANSI C. K&R compilers would not accept this */

int f(); /* Function declared in the original K&R dialect */

虽然现在支持 C 的原始 K&R 方言的编译器很少(或已绝迹),但当需要支持这两种编译器时编写了很多软件,而宏提供了一种支持这两种编译器的简单方法。仍然有很多提供这种向后兼容性的标头。

为了为 K&R 编译器提供向后兼容性,许多头文件具有以下内容:

#if ANSI_PROTOTYPES
#  define _P(x) x
#else
#  define _P(x) ()
#endif

...

int f _P((int x, double y));

如果ANSI_PROTOTYPES定义已正确设置(由用户或某些先前的#ifdef逻辑),那么您将获得所需的行为:

  • 如果定义了 ANSI_PROTOTYPES,则定义扩展为int f(int x, double y).
  • 如果未定义 ANSI_PROTOTYPES,则定义扩展为int f()
于 2013-03-06T21:34:09.537 回答
4

这通常与条件表达式一起使用,通过将宏预处理为空来禁用宏。例如(简化):

#ifdef DEBUG
#define ASSERT(x) if(!(x)) { abort(); }
#else
#define ASSERT(x) /* nothing */
#endif
于 2013-03-06T19:21:34.180 回答
3

只是我的问题的后续行动。

我得到了很好的答案。但我还添加了一些更有用的示例,其中没有定义的宏很有用,将来会发现它很有帮助:

(1) :为什么我在 C 库中看到 THROW?
用于在 C 和 C++ 之间共享头文件。宏名称是_THROW(x)

#ifdef __cplusplus
    #define __THROW(x) throw(x)
#else
    #define __THROW(x)
#endif  

(2) 消除不使用函数参数时的警告:
此用途适用于 c++。在 C 中,参数太少会导致错误但在C++ 中,它可以正常工作:(键盘链接

#define UNUSED(x)
int value = 0;
int foo(int UNUSED(value))
{
    return 42;
}
int main(){
   foo(value);
}

为此我在我的问题中添加了 c++ 标签

另外,
(3):的使用#define _M(x) x如下,只是为了让代码统一排列:

/* Signed.  */
 # define INT8_C(c)      c
 # define INT16_C(c)     c
 # define INT32_C(c)     c
 # if __WORDSIZE == 64
 #  define INT64_C(c)    c ## L
 # else
 #  define INT64_C(c)    c ## LL
 # endif

文件是:/usr/include/stdint.h

于 2013-03-10T18:48:42.043 回答
1

这意味着使用该宏的代码将有条件地预处理为空。

作为简单的示例,请考虑调试代码、日志记录或断言。

于 2013-03-06T19:20:51.203 回答
1

这可能是调试宏或平台宏。例如,假设我有一个附加到 INT3 的调试器。我调试的时候可能有这个

 #define debug() INT3()

然后为了安全起见,我会将其添加到生产代码中(以确保我将它们全部取出)

 #define debug()

这看起来像类似的东西

可能在某些情况下,在某些系统上,此代码需要调用——例如在某个 CPU 架构或操作系统上。但是在您的系统上,它只是没有操作。

于 2013-03-06T19:28:48.977 回答