fprintf() 的跨平台宏包装器
Cross-platform macro wrapper for fprintf()
是否有一种跨平台的方法来包装 fprintf()
这样我就可以有一个简单的日志记录功能来将日志转储到文件或控制台,并使用简单的 C printf()
风格格式化字符串和参数列表?
现在,我正在做这样的事情:
#define logIssue(fmt, ...) do { \
fprintf(stderr, "MY_PREFIX:%s:%s:%d > " fmt "\n", __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
} while(0);
这在 GCC 中有效,如果我删除前导 ##
,它在 GCC and Visual Studio 2005 中有效(是的,我必须这在 VS2005 上工作到 2015 年),但它在 2012 年之前的 Visual Studio 版本中失败,当时我实际上没有可变参数列表,即:
logIssue("Problem with test#%d.", iTestID); // Succeeds
logIssue("General problem."); // Fails
我已详细阅读此问题,包括以下内容:
- Standard alternative to GCC's ##VA_ARGS trick?
- MSVC doesn't expand VA_ARGS correctly
- the problem about different treatment to VA_ARGS when using VS 2008 and GCC
这些提供了潜在的解决方案,但我似乎无法将它们与我的 fprintf()
宏集成。
有没有什么直接的方法可以通过宏技巧让这个包装器宏在 Linux (GCC) 和 Windows(MSVC 2005 及更高版本)中工作?
谢谢。
不需要扩展:
#define logIssue(...) do {
fprintf(stderr, "MY_PREFIX:%s:%s:%d > ", __func__, __FILE__, __LINE__);
fprintf(stderr, __VA_ARGS__ );
fputs( "", stderr);
} while(0)
这适用于两个调用,并且符合 C99:
logIssue("Problem with test#%d.", iTestID);
logIssue("General problem.");
是否有一种跨平台的方法来包装 fprintf()
这样我就可以有一个简单的日志记录功能来将日志转储到文件或控制台,并使用简单的 C printf()
风格格式化字符串和参数列表?
现在,我正在做这样的事情:
#define logIssue(fmt, ...) do { \
fprintf(stderr, "MY_PREFIX:%s:%s:%d > " fmt "\n", __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
} while(0);
这在 GCC 中有效,如果我删除前导 ##
,它在 GCC and Visual Studio 2005 中有效(是的,我必须这在 VS2005 上工作到 2015 年),但它在 2012 年之前的 Visual Studio 版本中失败,当时我实际上没有可变参数列表,即:
logIssue("Problem with test#%d.", iTestID); // Succeeds
logIssue("General problem."); // Fails
我已详细阅读此问题,包括以下内容:
- Standard alternative to GCC's ##VA_ARGS trick?
- MSVC doesn't expand VA_ARGS correctly
- the problem about different treatment to VA_ARGS when using VS 2008 and GCC
这些提供了潜在的解决方案,但我似乎无法将它们与我的 fprintf()
宏集成。
有没有什么直接的方法可以通过宏技巧让这个包装器宏在 Linux (GCC) 和 Windows(MSVC 2005 及更高版本)中工作?
谢谢。
不需要扩展:
#define logIssue(...) do {
fprintf(stderr, "MY_PREFIX:%s:%s:%d > ", __func__, __FILE__, __LINE__);
fprintf(stderr, __VA_ARGS__ );
fputs( "", stderr);
} while(0)
这适用于两个调用,并且符合 C99:
logIssue("Problem with test#%d.", iTestID);
logIssue("General problem.");