像宏这样的函数需要强制括号吗?参考 GCC cpp 手册后我很困惑
Do function like macros need a mandatory parentheses? I am confused after referring the GCC cpp manual
这是让我困惑的地方:
To define a function-like macro, you use the same '#define' directive, but you put a pair of parentheses immediately after the macro name.
我相信这是为了让代码在程序作者以外的人面前脱颖而出。与宏名称的其他 CAPS 规则一样。但以下是我感到困惑的地方:
A function-like macro is only expanded if its name appears with a pair of parentheses after it. If you write just the name, it is left alone.
看完后立马不同意。并且 gcc -E 在下面的代码中验证了
#define FUNC display()
void display()
{
printf("Display\n");
}
int main()
{
FUNC;
return 0;
}
预处理后的输出显示 main() 函数的内容符合预期:
int main()
{
display();
return 0;
}
那么我在这里缺少什么?预处理器用于标记源,宏扩展是一个标记,上面的代码就是这样处理的,预处理器不应该检查任何东西或验证任何东西,它只是转储标记。在那种情况下,gcc 手册试图传达什么。
我正在学习C编程,所以我可能对它有很多误解,因为它经常发生,我搜索了适当的解释,最后求助于这里。请帮我解决这个问题。
当你定义:
#define FUNC display()
FUNC
不是类似函数的宏;它是一个类似对象的宏,可扩展为函数调用。
类似函数的宏如下所示:
#define FUNC() display()
现在您必须编写 FUNC()
来调用它。或者,更常见的是,它会有参数:
#define MIN(x, y) ((x) > (y) ? (x) : (y))
并且可以通过以下方式调用:
int min = MIN(sin(p), cos(q));
注意参数展开的次数。
另见 。它包括标准的解释,为什么不带左括号的类似函数的宏的简单名称是 not 扩展很重要,这就是 GCC 手册中的引述你.
定义类函数宏时,左括号必须'touch'宏名:
#define function_like(a) …
#define object_like (…)
因为 object_like
之后有一个 space,左括号是替换文本的一部分,而不是参数列表的开头。调用类函数宏时,宏名和参数列表之间可能有space:
function_like (x) // Valid invocation of function_like macro.
但是,如果您写道:
int (function_like)(double a) { return asin(a) + 2 * atanh(a); }
这不是函数式宏的调用,因为 function_like
之后的标记不是左括号。
有两种宏。它们的主要区别在于使用时的外观。
类对象宏在使用时类似于数据对象,类函数宏类似于函数调用。
您可以将任何有效的标识符定义为宏,即使它是 C 关键字。预处理器对关键字一无所知。如果您希望从不理解它的旧编译器中隐藏诸如 const 之类的关键字,这将很有用。但是,预处理运算符永远不能定义为宏,C++ 的命名运算符在编译 C++ 时也不能是宏。
这是让我困惑的地方:
To define a function-like macro, you use the same '#define' directive, but you put a pair of parentheses immediately after the macro name.
我相信这是为了让代码在程序作者以外的人面前脱颖而出。与宏名称的其他 CAPS 规则一样。但以下是我感到困惑的地方:
A function-like macro is only expanded if its name appears with a pair of parentheses after it. If you write just the name, it is left alone.
看完后立马不同意。并且 gcc -E 在下面的代码中验证了
#define FUNC display()
void display()
{
printf("Display\n");
}
int main()
{
FUNC;
return 0;
}
预处理后的输出显示 main() 函数的内容符合预期:
int main()
{
display();
return 0;
}
那么我在这里缺少什么?预处理器用于标记源,宏扩展是一个标记,上面的代码就是这样处理的,预处理器不应该检查任何东西或验证任何东西,它只是转储标记。在那种情况下,gcc 手册试图传达什么。
我正在学习C编程,所以我可能对它有很多误解,因为它经常发生,我搜索了适当的解释,最后求助于这里。请帮我解决这个问题。
当你定义:
#define FUNC display()
FUNC
不是类似函数的宏;它是一个类似对象的宏,可扩展为函数调用。
类似函数的宏如下所示:
#define FUNC() display()
现在您必须编写 FUNC()
来调用它。或者,更常见的是,它会有参数:
#define MIN(x, y) ((x) > (y) ? (x) : (y))
并且可以通过以下方式调用:
int min = MIN(sin(p), cos(q));
注意参数展开的次数。
另见
定义类函数宏时,左括号必须'touch'宏名:
#define function_like(a) …
#define object_like (…)
因为 object_like
之后有一个 space,左括号是替换文本的一部分,而不是参数列表的开头。调用类函数宏时,宏名和参数列表之间可能有space:
function_like (x) // Valid invocation of function_like macro.
但是,如果您写道:
int (function_like)(double a) { return asin(a) + 2 * atanh(a); }
这不是函数式宏的调用,因为 function_like
之后的标记不是左括号。
有两种宏。它们的主要区别在于使用时的外观。
类对象宏在使用时类似于数据对象,类函数宏类似于函数调用。
您可以将任何有效的标识符定义为宏,即使它是 C 关键字。预处理器对关键字一无所知。如果您希望从不理解它的旧编译器中隐藏诸如 const 之类的关键字,这将很有用。但是,预处理运算符永远不能定义为宏,C++ 的命名运算符在编译 C++ 时也不能是宏。