宏可以返回一个对象吗?
#define macro1 {obj1}
由于宏是文本替换,我可以使用像macro1.function1()这样的宏吗?谢谢.
zy1mlcev1#
宏从不返回任何东西。宏返回代码的文本表示,这些代码将粘贴到程序中在编译前使用它的位置。关于C Preprocessor所以:
#define macro1 {obj1} int main() { macro1 }
.将被编译,如果你写
int main() { {obj1} }
它只是文本替换,可以选择参数。如果你使用的是GCC,你可以使用cpp工具来看看程序预处理后的样子:
cpp
# cpp myprog.cpp myprog.cpp_out
一般来说,将宏与对象混合使用是不好的做法,请使用templates。宏在对象方面的一个已知用法是使用它们来访问单例(然而,这通常不是一个好主意):
#define LOGGER Logger::getLogger() ... LOGGER->log("blah");
您还可以使用预处理器在编译时选择要用途:的对象
#ifdef DEBUG # define LOGGER DebugLogger #else # define LOGGER Logger #end // assuming that DebugLogger and Logger are objects not types LOGGER.log("blah");
但是前面提到的模板做得更好。
sqserrrh2#
宏在预处理步骤(编译的七个阶段的一部分)期间触发文本替换。返回值发生在运行时。这个问题没有意义。
rsaldnfx3#
示例中的宏将文本macro1替换为{obj1}。它只是用其他文本替换文本;它不知道对象或类的概念。
macro1
{obj1}
slwdgvem4#
当你定义一个宏(并调用它)时,你总是可以看到编译器做了什么。宏的代码被简单地替换了(就像复制粘贴一样)。使用gcc -E编译。例如,对于此代码
#define macro1 {obj1} int main() { int obj1; macro1 }
在使用gcc-E example.c编译时,我得到以下输出
# 1 "macro.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "macro.c" int main() { int obj1; {obj1} //here your call gets expanded }
slwdgvem5#
函数宏不是C++函数意义上的真实的函数:它们只是预处理指令。你的源文件首先由预处理器读取,宏被处理(扩展,替换等),然后将结果源交给编译器。所以宏只是在源文件中“复制粘贴”文本。所以你可以使用包含return语句的宏,但它只会在你的代码中被替换。另请参见类函数宏
return
ki0zmccv6#
我有一个功能:
bool CheckAndContinue(const bool p_test, const std::string& p_errorMessage) { BOOST_CHECK_MESSAGE(p_test, p_errorMessage.c_str()); return p_test; }
因为BOOST_MESSAGE在一个函数中,所以result总是指向这个函数中的line,而issue实际上是在调用CheckAndContinue的line上。然后我必须做一个宏,它可以做同样的事情,所以线指向的是CheckAndContinue被调用的地方,这导致了下面针对我的特定情况的答案。
CheckAndContinue
({ ... })
#define CHECK_AND_CONTINUE(p_test, p_errorMessage)\ ({\ const bool result = (p_test);\ BOOST_CHECK_MESSAGE(result, p_errorMessage);\ result;\ })
注意,我传递const bool result = (p_test)是因为如果我调用示例const bool success = CHECK_AND_CONTINUE(TimeConsumingFunctionOrFunctionThatModifyAValue(param)),如果我有:
const bool result = (p_test)
const bool success = CHECK_AND_CONTINUE(TimeConsumingFunctionOrFunctionThatModifyAValue(param))
#define CHECK_AND_CONTINUE(p_test, p_errorMessage)\ ({\ BOOST_CHECK_MESSAGE(p_test, p_errorMessage);\ p_test;\ })
由于宏的工作方式,TimeConsumingFunctionOrFunctionThatModifyAValue(param)将被调用两次(在两次p_test使用时),然后时间消耗将消耗两次,如果修改值将修改两次(例如,值的简单增量将增加两次)。
TimeConsumingFunctionOrFunctionThatModifyAValue(param)
p_test
6条答案
按热度按时间zy1mlcev1#
宏从不返回任何东西。宏返回代码的文本表示,这些代码将粘贴到程序中在编译前使用它的位置。
关于C Preprocessor
所以:
.将被编译,如果你写
它只是文本替换,可以选择参数。
如果你使用的是GCC,你可以使用
cpp
工具来看看程序预处理后的样子:一般来说,将宏与对象混合使用是不好的做法,请使用templates。
宏在对象方面的一个已知用法是使用它们来访问单例(然而,这通常不是一个好主意):
您还可以使用预处理器在编译时选择要用途:的对象
但是前面提到的模板做得更好。
sqserrrh2#
宏在预处理步骤(编译的七个阶段的一部分)期间触发文本替换。返回值发生在运行时。这个问题没有意义。
rsaldnfx3#
示例中的宏将文本
macro1
替换为{obj1}
。它只是用其他文本替换文本;它不知道对象或类的概念。slwdgvem4#
当你定义一个宏(并调用它)时,你总是可以看到编译器做了什么。宏的代码被简单地替换了(就像复制粘贴一样)。
使用gcc -E编译。例如,对于此代码
在使用gcc-E example.c编译时,我得到以下输出
slwdgvem5#
函数宏不是C++函数意义上的真实的函数:它们只是预处理指令。
你的源文件首先由预处理器读取,宏被处理(扩展,替换等),然后将结果源交给编译器。
所以宏只是在源文件中“复制粘贴”文本。所以你可以使用包含
return
语句的宏,但它只会在你的代码中被替换。另请参见类函数宏
ki0zmccv6#
上下文
我有一个功能:
因为BOOST_MESSAGE在一个函数中,所以result总是指向这个函数中的line,而issue实际上是在调用
CheckAndContinue
的line上。然后我必须做一个宏,它可以做同样的事情,所以线指向的是
CheckAndContinue
被调用的地方,这导致了下面针对我的特定情况的答案。Answer(由于使用了
({ ... })
,所以我理解为GCC)注意,我传递
const bool result = (p_test)
是因为如果我调用示例const bool success = CHECK_AND_CONTINUE(TimeConsumingFunctionOrFunctionThatModifyAValue(param))
,如果我有:由于宏的工作方式,
TimeConsumingFunctionOrFunctionThatModifyAValue(param)
将被调用两次(在两次p_test
使用时),然后时间消耗将消耗两次,如果修改值将修改两次(例如,值的简单增量将增加两次)。