我有一个看起来像这样的宏:
#define coutError if (VERBOSITY_SETTING >= VERBOSITY_ERROR) ods()
其中ods()是一个行为与cout类似的类,VERBOSITY_SETTING是一个全局变量。其中有一些用于不同的详细程度设置,它允许代码看起来像这样:
if (someErrorCondition)
{
// ... do things relating to the error condition ...
coutError << "Error condition occurred";
}
此框架中有功能可以设置详细程度等。但是,在不使用大括号时,明显的模式会中断:
void LightSwitch::TurnOn()
{
if (!PowerToSwitch)
coutError << "No power!";
else
SwitchOn = true;
}
因为宏,会变成这个:
void LightSwitch::TurnOn()
{
if (!PowerToSwitch)
if (VERBOSITY_SETTING >= VERBOSITY_ERROR)
ods() << "No power!";
else
SwitchOn = true;
}
这不是if语句的预期功能。
现在,我理解一种正确修复此宏的方法,因此它不会导致此问题,但我想对代码运行审核并找到具有“if(...”模式的任何地方)coutError&lt;&lt; ...; else“以确定是否有任何其他情况发生这种情况以确保在修复宏时,它确实是正确的功能。
我可以使用任何语言/工具来找到这个,我只想知道最好的方法。
答案 0 :(得分:2)
您可以尝试 - 暂时 - 将宏修改为类似的内容,并查看无法编译的内容......
#define coutError {} if (VERBOSITY_SETTING >= VERBOSITY_ERROR) ods()
'else'条款现在应该出错。
答案 1 :(得分:2)
不要试图找到代码中发生逻辑错误的所有位置 - 从源头解决问题!更改宏,以便不会出现错误:
#define coutError if(VERBOSITY_SETTING < VERBOSITY_ERROR); else ods()
请注意,我在这里所做的是反转测试,为then
子句添加一个空语句,并将输出对象放在else
子句中。这仍允许您在宏之后使用<< foo << bar
,如果您有一个属于不同else
语句的尾随if
子句,它将正确匹配,因为它会像这样扩展:
if(foo)
coutError << bar;
else
baz();
变为
if(foo)
if(VERBOSITY_SETTING < VERBOSITY_ERROR)
;
else
ods() << bar;
else
baz();
答案 2 :(得分:1)
我认为宏的所有良好用法都以'{'或';'。
开头所以试试这个正则表达式:
[^{;]\s*coutError
您需要启用多行匹配并搜索整个文件。
您可能需要获取更多内容,以便找到有问题的行: - )
如果我们能够解决一些失败的问题,那么改变宏是一个很好的想法。可能是一个块后跟条件运算符:
#define coutError {} (VERBOSITY_SETTING >= VERBOSITY_ERROR)?(ods()):(nullstream())
(但确实需要实现一个nullstream()运算符。)
(或者完全暂时删除条件 - 正如你的建议是对另一个答案@Roddy(目前是选定的答案)的评论)。
P.S。我知道你没有问,但是用一个do {} while(false)
循环来包装宏以保证其安全的简单方法。
答案 3 :(得分:1)
我在上面的评论中看到你正在考虑在宏中使用模板,我还不能发表评论(我只差9分),所以......
阻止你做什么
#define CoutError(s) { if (VERBOSITY_SETTING >= VERBOSITY_ERROR){ ods(s); } }
然后
void LightSwitch::TurnOn()
{
if (!PowerToSwitch)
CoutError("No power!");
else
SwitchOn = true;
}
重新定义ods以接纳字符串,或者如果你不能,则只需定义一个OdsHelper函数,它接受一个字符串,其主体只是ods&lt;&lt; inString?
我不会尝试使用宏来模仿&lt;&lt;语法,如果没有明确的收益。至少使用模拟函数语法的宏我们更常用,我们知道我们必须编写块以防止出现奇怪的问题。
你真的需要&lt;&lt;语法?
你真的需要为这个简单的行为引入一个模板吗?
哦,最后一件事 - 不要使用宏。
答案 4 :(得分:0)
我认为真正的问题是使用宏 - 而不是预处理的代码。但我不认为这是你正在寻找的答案。
我会找到一种方法来完成它而不使用宏 - 如果你使用条件编译,你可以在调用ods()时这样做 - 取决于一些#define它可以使用你想要的任何功能。 / p>
只是我的$ .02
答案 5 :(得分:0)
正则表达式搜索?