调用方法的#defines的内部工作

时间:2013-01-19 23:25:26

标签: c++ c-preprocessor

我知道在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来检索函数的名称

3 个答案:

答案 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)”,这可能非常有用。