所以我正在学习C,我遇到了这个
#ifndef _dbg_h_
#define _dbg_h
#include<stdio.h>
#include<errno.h>
#ifdef NDEBUG
#define debug(M,...)// I do not know why M is an argument here
#else
#define debug(M,...)fprintf(stderr,"DEBUG %s:%d: " M "\n",\
_FILE_,_LINE_,##_VA_ARGS_)
#endif
#define clean_errno()(errno==0?"None":strerror(errno))
#define log_err(M,...)fprintf(stderr,\"[ERROR](%s:%d: errno: %s)" M "\n"
_FILE_,_LINE_ ,\clean_errno(),##_VA_ARGS_)
...
#define check(A,M,...)if(!(A)){\ /*why is A an arg here */
log_err(M,##_VA_ARGS_);errno=0;goto error;}
为什么这些需要M和A作为参数以及它们在哪里被声明/初始化
答案 0 :(得分:2)
名称M
和A
对预处理器没有特别的意义。
M
是debug
宏的第一个参数的名称。名称M
,当它出现在debug
宏的定义中时,将被调用debug
时传递的第一个参数的值替换。
...
表示它是一个可变参数宏,可以使用可变数量的参数。
一个更简单的例子:
#define MY_MACRO(ARG) (2*(ARG))
printf("%d\n", MY_MACRO(10));
在调用MY_MACRO(10)
中,名称ARG
被10
替换,导致整个宏调用扩展为(2*(10))
。 (额外的括号是为了避免运算符优先级问题。)