定义预处理器宏

Defining a Preprocessor Macro

本文关键字:处理器 预处理 定义      更新时间:2023-10-16

我对C++还比较陌生,我正在上一堂关于它的课。我们班被分配了一个实验室,我的老师说实验室的内容有点难理解;然而,他并没有对实验室的报告做任何修改。所以,我偶然发现了实验室的这一部分:

定义预处理器宏

长期存在的约定将宏名称大写,并且此宏名称必须是TRACE_FUNC。宏只有一个参数,当您将宏应用于代码时,该符号将被函数名替换。宏的开头看起来是这样的:

#define TRACE_FUNC( symbol )  replacement-text`

并且预处理器将在源代码中存在TRACE_FUNC(sym)字符串的任何地方替换替换文本,并将符号馈送到该替换中。

注意:#define语句必须全部在一个逻辑行上。为了保持长度可控,可以在换行符的末尾用反斜杠转义换行符;这将使预处理器满意,同时允许您跨越多行定义。

对于本练习,替换文本必须是一个完整的语句,包括终止分号。

替换文本必须是一个输出语句,该语句打印后面跟着调用的文本()的符号。以及标准输出的换行符。您可以从warning.cpp源文件中复制和修改其中一个输出语句。

warning.cpp只是我们正在使用的一个文件,TRACE_FUNC被放置在一个头文件中。

所以,我读了几遍,我不能100%确定它在问什么。从某种角度来看,它似乎是在要求我创建一个名为TRACE_FUNC的宏。如果从另一个角度来看,它要求我使用宏TRACE_FUNC。所有这些都很好,但我根本不知道如何使用TRACE_FUNC,我在任何地方都找不到任何文档,也不知道如何创建宏。当我请求帮助时,我的老师只是说。单词,而不是那些非常有用的单词,因为这是一个非常曲折、令人困惑的答案,没有解释TRACE_FUNC到底是什么。

基本上,我的老师所说的只是TRACE_FUNC中的符号需要是源代码中某个函数的名称。举个例子,假设我们在warning中有一个函数foo(),那么根据他的解释,这个符号应该是foo()(或者foo,我也不确定)。此外,在替换文本中,如果我将#放在符号前面,显然名称本身将被替换。我认为这应该表示预处理器指令。为什么我要在这里使用它?

不管怎样,照我老师说的去做几乎没有任何作用。这条线都不是

#define TRACE_FUNC( foo() ) #foo() called. ;

也没有这条线路

#define TRACE_FUNC( foo ) #foo () called. ;

替换任何文本,我很确定这是#define指令的操作。所以我一定是用错误的方式应用了我老师说的话,但我真的不知道为什么是错误的,也不知道如何纠正

所以,我的问题。TRACE_FUNC实际上是一个宏吗?如果是,我能阅读它上的任何文档吗?或者我应该创建TRACE_FUNC吗?如果是,我应该如何做到这一点

哇,真是胡说八道!你应该正确地学习C++,而不是复杂的预处理器。

以下是你应该做的事情,尽管为什么大家都在猜测。

#define TRACE_FUNC(sym) std::cout << #sym << "() calledn"
void foo()
{
  TRACE_FUNC(foo);
  ...
}

我假设warning.cpp中有一些使用std::cout的例子,如果没有,那么你必须将上面的内容改编为warning.cpp.中的任何内容

其思想是,每个函数都从使用TRACE_FUNC宏开始,这样您就可以跟踪代码的执行情况。为什么教授认为这对新手来说是个好主意,我无法理解。即使这是个好想法,你也要自己弄清楚细节,这更愚蠢。

我可以改进上面的宏,但这可能会让我更加困惑,所以我不会。现在,我只是按照教授说的去做,但忽略了它。希望他以后能学到一些值得学习的东西。

这里有一个例子:在库中使用ouput-print函数来替换标准函数printf here

 #define TRACE_FUNC(sym) printf("%s() called", #sym);

将其用作

TRACE_FUNC(printf)

输出应该是

printf() called

您的实际任务是以定义的格式打印出一个符号。所以您需要在#define中使用printf或类似的函数。