我知道在C ++文件的开头定义的是Preprocessor directives所以“预处理器在代码的实际编译开始之前执行,因此预处理器在语句生成任何代码之前摘要所有这些指令[ 1]”。
现在如果我有这个简单的例子怎么办:
#define PRINT(function) printFnctionName(#function)
void printFnctionName(string name)
{
cout << name;
}
void test(){};
int main(int argc, char *argv[])
{
PRINT(test);
}
所以现在我的问题是预编译器如何知道将传递哪些函数?如何进行预编译/链接/编译?
另外,我使用define而不是常规函数的原因,是因为我无法找到复制此功能的方法`#function来检索函数的名称
答案 0 :(得分:2)
所以现在我的问题是预编译器是如何知道的 功能会被传递?怎么样? 预编译/链接/编译真的发生了吗?
预处理器不知道任何事情。它只是用定义的值替换文本,并将传入的值字符串化。
所以编译器会看到它:
void printFnctionName(string name)
{
cout << name;
}
void test(){};
int main(int argc, char *argv[])
{
printFnctionName("test");
}
答案 1 :(得分:1)
预处理器执行文本替换。在您的情况下,您的代码将转换为:
int main(int argc, char *argv[])
{
printFnctionName("test");
}
之前的预处理器其余的编译过程开始。一些预处理器指令很简单,其他更复杂(例如,变量arity预处理器指令)。
当然,它要求您包含正确的头文件等。
答案 2 :(得分:0)
对于这个特殊情况,答案分为两部分。一部分是C预处理器对被调用的函数一无所知,它只是文本替换。
第二部分是“字符串”,#function
实际上用test
替换PRINT
作为"test"
的输入。当然,它不一定是一个函数 - 只是因为它被称为printfunction,你可以这样做:
PRINT(a+b);
你会得到代码:
printFnctionName("a+b");
或
PRINT(a-*&1,78^%j)
并获得:
printFnctionName("a-*&1,78^%j");
[为什么u
在printFnctionName中错过了?]
如果您有类似
的内容,则字符串化运算符非常有用#define ASSERT(x) do { if (!x) fail_assert(#x, __FILE__, __LINE__); } while(0)
void fail_assert(const char *expr, const char *file, int line)
{
cerr << "Assertion (" << expr << ") failed at " << file << ":" << line << endl;
}
....
ASSERT(ptr != NULL);
现在你在myprog.cpp:112上收到一条错误消息“Assertion failed(ptr!= NULL)”,这可能非常有用。