没有定义的宏功能有什么用途/适用性:
#ifndef __SYSCALL
#define __SYSCALL(a, b)
#endif
可以在头文件/usr/include/asm/msr.h
我也注意到以下类型的宏。
#define _M(x) x
唯一的理由是我可以考虑定义这种宏来使代码统一。就像#define SOMETHING (1 << 0)一样。是否有其他隐藏(更好)的使用这种宏?
以示例回答将非常有帮助。也 有人可以给我一个文本/链接来阅读这个。
答案 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
逻辑设置),那么您将获得所需的行为:
int f(int x, double y)
。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
答案 3 :(得分:1)
这意味着使用该宏的代码将有条件地预处理为空。
作为简单示例,请考虑调试代码,日志记录或断言。
答案 4 :(得分:1)
这可能是调试宏或平台宏。例如,假设我有一个附加到INT3的调试器。我正在调试时可能会有这个
#define debug() INT3()
然后为了安全起见,我会将其添加到生产代码中(以确保我将它们全部拿出来)
#define debug()
这看起来像是类似的东西
在某些情况下,某些系统上的代码需要进行调用 - 例如在某个CPU架构或操作系统上。但是在你的系统上它只是没有开启。