C++宏解析问题
C++ macro parsing issue
我正在尝试使用宏在 ostringstream 中本地排队单个日志行,然后在该行结束时转储该 ostringstream 的全部内容。但是,我仍想使用流插入语法。所以我想像这样打开一个日志行:
std::cerr << "Some error in my function. Code is " << errCode << " exiting" << std::endl;
...进入这个
SERR("Some error in my function. Code is " << errCode << " exiting);
我有一些简单但效果很好的东西。也就是说,直到我将其放入 if-else 语句中。显然我的微距不好,但我不知道该怎么做。
这里是一个小的示例程序,用来说明问题。:
#include <iostream>
#include <sstream>
#define SERR(x) { std::ostringstream _s; ; _s << x << std::endl; std::cerr << _s.str(); }
int main()
{
std::cout << "Hello World!\n";
bool val = false;
if (val)
SERR("No error");
else
SERR("Error");
}
我在这个示例中从编译器得到的错误信息是:
1>c:\users\joe\source\repos\consoleapplication5\consoleapplication5\consoleapplication5.cpp(15):
error C2181: illegal else without matching if
知道我这里有什么问题吗?
(请注意,我现在不在可以使用第 3 方日志记录解决方案的地方,所以它必须像这样简单。我可以让所有这些保持正常 std::cerr
/std::cout
/std::clog
消息,如果必须的话,但我更喜欢一些简单的东西,以尽量减少我的多线程应用程序中日志消息交织的机会。)
试着展开它,看看你会得到什么:
#include <iostream>
#include <sstream>
int main()
{
std::cout << "Hello World!\n";
bool val = false;
if (val)
{ std::ostringstream _s; ; _s << "No error" << std::endl; std::cerr << _s.str(); };
else
{ std::ostringstream _s; ; _s << "Error" << std::endl; std::cerr << _s.str(); };
}
注意 { }
块如何以 ;
终止?
如果您需要宏,您应该始终使用 do { } while (0)
编写它,如下所示:
#define SERR(x) \
do { \
std::ostringstream _s; \
_s << (x) << std::endl; \
std::cerr << _s.str(); \
} while (0)
这不仅解决了您的问题,而且还强制在宏后添加 ;
。否则人们可以通过两种方式使用它:
SERR("foo") // without ;
...
SERR("bar"); // with ;
我正在尝试使用宏在 ostringstream 中本地排队单个日志行,然后在该行结束时转储该 ostringstream 的全部内容。但是,我仍想使用流插入语法。所以我想像这样打开一个日志行:
std::cerr << "Some error in my function. Code is " << errCode << " exiting" << std::endl;
...进入这个
SERR("Some error in my function. Code is " << errCode << " exiting);
我有一些简单但效果很好的东西。也就是说,直到我将其放入 if-else 语句中。显然我的微距不好,但我不知道该怎么做。
这里是一个小的示例程序,用来说明问题。:
#include <iostream>
#include <sstream>
#define SERR(x) { std::ostringstream _s; ; _s << x << std::endl; std::cerr << _s.str(); }
int main()
{
std::cout << "Hello World!\n";
bool val = false;
if (val)
SERR("No error");
else
SERR("Error");
}
我在这个示例中从编译器得到的错误信息是:
1>c:\users\joe\source\repos\consoleapplication5\consoleapplication5\consoleapplication5.cpp(15): error C2181: illegal else without matching if
知道我这里有什么问题吗?
(请注意,我现在不在可以使用第 3 方日志记录解决方案的地方,所以它必须像这样简单。我可以让所有这些保持正常 std::cerr
/std::cout
/std::clog
消息,如果必须的话,但我更喜欢一些简单的东西,以尽量减少我的多线程应用程序中日志消息交织的机会。)
试着展开它,看看你会得到什么:
#include <iostream>
#include <sstream>
int main()
{
std::cout << "Hello World!\n";
bool val = false;
if (val)
{ std::ostringstream _s; ; _s << "No error" << std::endl; std::cerr << _s.str(); };
else
{ std::ostringstream _s; ; _s << "Error" << std::endl; std::cerr << _s.str(); };
}
注意 { }
块如何以 ;
终止?
如果您需要宏,您应该始终使用 do { } while (0)
编写它,如下所示:
#define SERR(x) \
do { \
std::ostringstream _s; \
_s << (x) << std::endl; \
std::cerr << _s.str(); \
} while (0)
这不仅解决了您的问题,而且还强制在宏后添加 ;
。否则人们可以通过两种方式使用它:
SERR("foo") // without ;
...
SERR("bar"); // with ;