C++ 如何使用#pragma message()使消息指向文件(lineno)?

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的示例:

为了在代码中添加“todo”项,我想在编译器输出中添加一条消息。
我希望它看起来像这样:

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)