因为我们组中有人讨厌异常(我们不在这里讨论这个问题),所以我们倾向于在c++项目中使用错误检查宏。在使用带有两个类型参数的模板化函数时,我遇到了一个奇怪的编译失败。下面有一些错误,但我认为根本原因是一个警告:
warning C4002: too many actual parameters for macro 'BOOL_CHECK_BOOL_RETURN'
最好用代码来解释:
#include "stdafx.h"
template<class A, class B>
bool DoubleTemplated(B & value)
{
return true;
}
template<class A>
bool SingleTemplated(A & value)
{
return true;
}
bool NotTemplated(bool & value)
{
return true;
}
#define BOOL_CHECK_BOOL_RETURN(expr)
do
{
bool __b = (expr);
if (!__b)
{
return false;
}
} while (false)
bool call()
{
bool thing = true;
// BOOL_CHECK_BOOL_RETURN(DoubleTemplated<int, bool>(thing));
// Above line doesn't compile.
BOOL_CHECK_BOOL_RETURN((DoubleTemplated<int, bool>(thing)));
// Above line compiles just fine.
bool temp = DoubleTemplated<int, bool>(thing);
// Above line compiles just fine.
BOOL_CHECK_BOOL_RETURN(SingleTemplated<bool>(thing));
BOOL_CHECK_BOOL_RETURN(NotTemplated(thing));
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
call();
return 0;
}
当有问题的行没有被注释掉时,下面是错误:
1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>Compiling...
1>test.cpp
1>c:junktemptesttesttest.cpp(38) : warning C4002: too many actual parameters for macro 'BOOL_CHECK_BOOL_RETURN'
1>c:junktemptesttesttest.cpp(38) : error C2143: syntax error : missing ',' before ')'
1>c:junktemptesttesttest.cpp(38) : error C2143: syntax error : missing ';' before '{'
1>c:junktemptesttesttest.cpp(41) : error C2143: syntax error : missing ';' before '{'
1>c:junktemptesttesttest.cpp(48) : error C2143: syntax error : missing ';' before '{'
1>c:junktemptesttesttest.cpp(49) : error C2143: syntax error : missing ';' before '{'
1>c:junktemptesttesttest.cpp(52) : error C2143: syntax error : missing ';' before '}'
1>c:junktemptesttesttest.cpp(54) : error C2065: 'argv' : undeclared identifier
1>c:junktemptesttesttest.cpp(54) : error C2059: syntax error : ']'
1>c:junktemptesttesttest.cpp(55) : error C2143: syntax error : missing ';' before '{'
1>c:junktemptesttesttest.cpp(58) : error C2143: syntax error : missing ';' before '}'
1>c:junktemptesttesttest.cpp(60) : error C2143: syntax error : missing ';' before '}'
1>c:junktemptesttesttest.cpp(60) : fatal error C1004: unexpected end-of-file found
1>Build log was saved at "file://c:junktemptesttestDebugBuildLog.htm"
1>test - 12 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
任何想法?谢谢!
预处理器不懂c++ !它只是执行词法替换。
声明多参数宏时,参数之间用逗号分隔。因为在宏调用中有一个逗号,所以调用宏时使用了多个参数,尽管声明它只接受一个参数。
圆括号被PP理解为形成一个令牌组,因此一组圆括号内的所有内容都是一个大令牌。
宏不知道语言,只使用词法标记。一个宏的参数之间用逗号分隔,因此下面的代码试图用两个参数"调用"这个宏:
BOOL_CHECK_BOOL_RETURN(DoubleTemplated<int, bool>(thing));
DoubleTemplated<int
和bool>(thing)
。这就是您看到的警告,也是其他错误的原因。以下是防止模板参数列表中出现,
的正确方法:
BOOL_CHECK_BOOL_RETURN((DoubleTemplated<int, bool>(thing)));
在未编译的行中,该逗号被预处理器解释为宏参数的分隔符。
在C99标准中(我手头没有c++标准,但它将非常相似),我们在6.10.3节中看到以下内容:
以最外层为界的预处理令牌序列匹配的圆括号构成了类函数的参数列表宏。列表中的各个参数用逗号分隔预处理记号,但预处理记号之间用逗号匹配内括号不能分隔参数。