C++ 如何使用#pragma message()使消息指向文件(lineno)?
为了在代码中添加“todo”项,我想在编译器输出中添加一条消息。C++ 如何使用#pragma message()使消息指向文件(lineno)?,c++,visual-studio-2010,pragma,line-numbers,predefined-macro,C++,Visual Studio 2010,Pragma,Line Numbers,Predefined Macro,为了在代码中添加“todo”项,我想在编译器输出中添加一条消息。 我希望它看起来像这样: c:/temp/main.cpp(104): TODO - add code to implement this 为了利用VisualStudio生成输出功能,可以通过双击导航到相应的行 但是\uuuu行\uuuu宏似乎扩展为int,这不允许写入 #pragma message( __FILE__ "("__LINE__"): ..." ) 还有别的办法吗?使用。我在下面发布了一个来自MSDN的示例:
我希望它看起来像这样:
c:/temp/main.cpp(104): TODO - add code to implement this
为了利用VisualStudio生成输出功能,可以通过双击导航到相应的行
但是\uuuu行\uuuu
宏似乎扩展为int
,这不允许写入
#pragma message( __FILE__ "("__LINE__"): ..." )
还有别的办法吗?使用。我在下面发布了一个来自MSDN的示例:
// collisions.h
#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#define __LOC__ __FILE__ "("__STR1__(__LINE__)") : Warning Msg: "
// collisions.cpp
#pragma message(__LOC__"Need to do 3D collision testing")
现在,我刚刚启动了这个,它肯定比我以前使用
#error
:D的解决方案要好
#define _STR(x) #x
#define STR(x) _STR(x)
#define TODO(x) __pragma(message("TODO: "_STR(x) " :: " __FILE__ "@" STR(__LINE__)))
你可以随时根据自己的需要修改它。
其用法示例如下:
//in code somewhere
TODO(Fix this);
控制台窗格中的输出:
1>TODO: Fix this :: c:\users\administrator\documents\visual studio 2008\projects\metatest\metatest\metatest.cpp@33
唯一的缺点是,您无法使用
\uuu pragma
跳转到这一行(通过双击控制台窗格中的消息)(但使用\pragma
测试似乎无论如何都不是这样…这里有一个允许您单击输出窗格的选项:
(这里还有其他一些不错的建议)
定义后,请使用类似的方法:
#pragma message(Reminder "Fix this problem!")
这将创建如下输出:
C:\Source\Project\main.cpp(47):提醒:修复此问题
对于那些觉得每次需要在代码中添加书签时都要输入
#pragma
指令很乏味的人来说,这是答案的补充:你可以通过启动一个宏来为你节省一些击键!一般来说,宏中不能有#pragma
指令,但MS C/C++编译器2008及更高版本确实支持一个特殊的供应商特定扩展名u pragma
,该扩展名可与宏一起使用。看
我每天使用类似于以下内容的东西:
#define STR2(x) #x
#define STR1(x) STR2(x)
#define LOC __FILE__ "("STR1(__LINE__)") : Warning Msg: "
#define WARNING_BUILDER(x) __FILE__ "("STR1(__LINE__)") : Warning Msg: " __FUNCTION__ " requires " #x
#define WREVIEW WARNING_BUILDER(review)
#define WUT WARNING_BUILDER(unit-testing)
#ifdef SPECIAL_WARNINGS
#ifdef SPECIAL_WARNINGS_REVIEW
#define MARK_FOR_REVIEW() do { \
__pragma(message( WREVIEW )) \
} while (0)
#else
#define MARK_FOR_REVIEW
#endif
#ifdef SPECIAL_WARNINGS_UNIT_TEST
#define MARK_FOR_UNIT_TEST() do { \
__pragma(message( WUT )) \
} while (0)
#else
#define MARK_FOR_UNIT_TEST
#endif
#endif
// uncomment/set in build-environment to enable special warnings
//#define SPECIAL_WARNINGS
#ifdef SPECIAL_WARNINGS
// uncomment/set in build-environment if you want only code review warnings
//#define SPECIAL_WARNINGS_REVIEW
// uncomment/set in build-environment if you want only unit-test warnings
//#define SPECIAL_WARNINGS_UNIT_TEST
#endif
int main()
{
MARK_FOR_REVIEW();
MARK_FOR_UNIT_TEST();
}
您可以轻松地扩展它以满足您的需要,并添加更多警告。拥有这样一个系统的好处在于,您可以有选择地打开(例如,只打开代码审阅项),而不必通过在构建设置中设置适当的宏来担心其他任何事情。这一功能允许在不使用杂注的情况下使用它(我认为是特定于Microsoft的)当你点击它时,它会把你带到那一行,因为它会显示文件和行号,就像一条常规的错误/警告消息一样,因为其他消息似乎都不会这样做。这在没有_pragma的情况下可以正常工作,但msvc的新版本需要它。我从90年代开始使用它。我使用Visual Studio 2013
#define MacroStr(x) #x
#define MacroStr2(x) MacroStr(x)
#define Message(desc) __pragma(message(__FILE__ "(" MacroStr2(__LINE__) ") :" #desc))
例如:
Message("Need to add unit testing here")
输出:
1>C:\Struts包含MiTracIsPr.h(180):“需要在这里添加单元测试”< P>在VisualC++中,您可以做< /P>
#pragma message(__FILE__ "(" _CRT_STRINGIZE(__LINE__) ")" ": warning: [blah]")
\u CRT\u STRINGIZE
通常已在某些标头中定义,但如果未定义,则可以定义它:
#define _CRT_STRINGIZE_(x) #x
#define _CRT_STRINGIZE(x) _CRT_STRINGIZE_(x)
这并不是那么简单,在将其转换为string@Necrolis:找到了有关此的MSDN KB文章并发布了一个代码段Microsoft有权使用双下划线定义符号,但您应该避免使用双下划线。标准为编译器制造商创建的标识符保留了它们。@Martinho:请参见我对Jacobs回答的评论只是一个注释,
\uu pragma()
在VS2010之前不存在。。。幸运的是,这个问题被标记为2010年,但我想知道为什么它不起作用。@John:有趣的是,MSDN列出了它从2008年开始提供(),但a)MSDN被认为是错误的&b)他们从未声明它是否需要服务或电源组…我看到某处说2010年,但我使用2005年,所以没有检查2008年。。。我认为你更有可能是对的@R.MartinhoFernandes如果您只执行\uuuuuuuuuuuuuuuuuuuuuu
操作,则会在警告中得到字符串“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?我正盯着美元符号看。@VinnieFalco看到我在VS中找不到宏允许标记的任何来源,所以我猜它支持它。删除反斜杠,否则它将无法编译。(或者像链接中的原文一样在多行上重新格式化。)(我的编辑被拒绝。)告诉你不能放“错误”或“警告”的声明在您的消息中,至少可以说是可疑的…这些调整允许将其用作简单宏,并在错误列表中显示警告,错误代码为“TODO”,可以进行排序和筛选。在vs2017上测试:'code'#define TODO(x)pragma(message('u_FILE“(“$Line”):warning TODO:“#x”)示例用法(如果参数包含在双引号中仍然有效):TODO(修复此代码)是消息的格式决定它在VS中是否“可点击”。实际上,\u pragma
,带有两个前导下划线,是特定于工具链的。最重要的是,#pragma
,虽然不是标准的,但大多数工具链(gcc、clang、vs.)也支持它。要“可点击”,行号必须介于()
#define _CRT_STRINGIZE_(x) #x
#define _CRT_STRINGIZE(x) _CRT_STRINGIZE_(x)