C中没有定义的宏

时间:2013-03-06 19:19:19

标签: macros c-preprocessor

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

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

可以在头文件/usr/include/asm/msr.h

中的Linux系统中找到此宏

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

#define _M(x) x

唯一的理由是我可以考虑定义这种宏来使代码统一。就像#define SOMETHING (1 << 0)一样。是否有其他隐藏(更好)的使用这种宏?

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

5 个答案:

答案 0 :(得分:11)

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

#define _M(x) x

是为只支持C的原始K&amp; R方言的编译器提供向后兼容性,这种方言早于现在普遍存在的ANSI C方言。在该语言的原始K&amp; 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&amp; R方言的编译器现在很少(或已经灭绝),但是当需要支持这两种编译器时,编写了很多软件,并且宏提供了一种简单的方法来支持这两种编译器。还有很多标题可以提供这种向后兼容性。

为了向K&amp; 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()

答案 1 :(得分:3)

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

#ifdef DEBUG
#define ASSERT(x) if(!(x)) { abort(); }
#else
#define ASSERT(x) /* nothing */
#endif

答案 2 :(得分:3)

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

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

(1)Why do I see THROW in a C library?
用于在C和C ++之间共享头文件。宏名称为_THROW(x)

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

(2) to eliminate warnings when a function parameter isn't used:
这个用法适用于c ++。在C中,它会导致an error too few arguments但在C++ it works with no error :( 键盘连接

#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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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

 #define debug() INT3()

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

 #define debug()

这看起来像是类似的东西

在某些情况下,某些系统上的代码需要进行调用 - 例如在某个CPU架构或操作系统上。但是在你的系统上它只是没有开启。