41

In order to add 'todo' items into my code, I want to put a message in the compiler output.
I would like it to look like this:

c:/temp/main.cpp(104): TODO - add code to implement this

in order to make use of the Visual Studio build output functionality to navigate to the respective line by double-clicking it.

But the __LINE__ macro seems to expand to an int, which disallows writing

#pragma message( __FILE__ "("__LINE__"): ..." )

Would there be another way?

xtofl
  • 40,723
  • 12
  • 105
  • 192

6 Answers6

53

Here is one that allows you to click on the output pane:

(There are also some other nice tips there)

http://www.highprogrammer.com/alan/windev/visualstudio.html

 // Statements like:
 // #pragma message(Reminder "Fix this problem!")
 // Which will cause messages like:
 // C:\Source\Project\main.cpp(47): Reminder: Fix this problem!
 // to show up during compiles. Note that you can NOT use the
 // words "error" or "warning" in your reminders, since it will
 // make the IDE think it should abort execution. You can double
 // click on these messages and jump to the line in question.

 #define Stringize( L )     #L 
 #define MakeString( M, L ) M(L)
 #define $Line MakeString( Stringize, __LINE__ )
 #define Reminder __FILE__ "(" $Line ") : Reminder: "

Once defined, use like so:

#pragma message(Reminder "Fix this problem!") 

This will create output like:

C:\Source\Project\main.cpp(47): Reminder: Fix this problem!

RedX
  • 14,749
  • 1
  • 53
  • 76
  • How is "#define $Line" even a valid preprocessor directive? I'm looking squarely at the dollar sign. – Vinnie Falco Jun 23 '13 at 16:10
  • 1
    @VinnieFalco See http://stackoverflow.com/questions/369495/what-are-the-valid-characters-for-macro-names I could not find any source on the allowed tokens for macros in VS so i'm guessing it supports it. – RedX Jun 23 '13 at 16:46
  • Remove the backslashes or it won't compile. (Or re-format on multiple lines like the original from the link.) (My edit was rejected.) – Nick Westgate May 12 '16 at 00:15
  • 2
    The claim that tells you can't put the words "error" or "warning" in your message is dubious to say the least... – Gregory Pakosz Jan 04 '17 at 12:35
  • These tweaks allow it to be used as simple macro and also to appear in the error list warnings with error code 'TODO' that can be sorted and filtered. Tested on vs2017 : 'code' #define TODO(x) __pragma(message(__FILE__ "(" $Line ") : warning TODO : " #x )) example usage (still works if the argument is enclosed in double quotes): TODO(Fix this code) – persiflage Jun 29 '18 at 13:22
  • 1
    Just FYI: when I submitted the Reminder macro to the WinDev Journal over 20 years ago, the existing Microsoft IDE interpreted ANY message containing warning or error as an actual warning or error, with errors stopping a build. – Steve Valliere Aug 05 '19 at 19:50
14

just whipped this up now, and it sure beats my old solution of using #error :D

#define _STR(x) #x
#define STR(x) _STR(x)
#define TODO(x) __pragma(message("TODO: "_STR(x) " :: " __FILE__ "@" STR(__LINE__)))

you can modify this how ever you like/to whatever suits your needs. An example of its usage:

//in code somewhere
TODO(Fix this);

output in the console pane:

1>TODO: Fix this :: c:\users\administrator\documents\visual studio 2008\projects\metatest\metatest\metatest.cpp@33

only downside is you can't jump to the line of this (by double clicking the message in the console pane) using __pragma (but testing with #pragma it doesn't seem to be the case anyways...)

Marco A.
  • 43,032
  • 26
  • 132
  • 246
Necrolis
  • 25,836
  • 3
  • 63
  • 101
  • @Martinho: see me comment on Jacobs answer – Necrolis May 11 '11 at 15:30
  • 1
    Just a note, `__pragma()` doesn't exist prior to VS2010... luckily the question is tagged as 2010 but I was wondering why it wasn't working. – Mr. Boy Apr 24 '14 at 15:17
  • @John: interesting, MSDN lists it as available from 2008 ( http://msdn.microsoft.com/en-us/library/d9x1s805(v=vs.90).aspx ), but a) MSDN is know to be wrong & b) they never state if it requires a service or power pack... – Necrolis Apr 24 '14 at 18:48
  • I saw somewhere say 2010 but I use 2005 so didn't check 2008... I think it's more likely you are correct! – Mr. Boy Apr 25 '14 at 08:36
  • @R.MartinhoFernandes if you do just `#__LINE__` you get the string `"__LINE__"` in your warning instead of the real line number. – jrh Feb 10 '18 at 23:40
9

On Visual C++ you can just do

#pragma message(__FILE__ "(" _CRT_STRINGIZE(__LINE__) ")" ": warning: [blah]")

_CRT_STRINGIZE is often already defined in some header, but if it's not, you can define it:

#define _CRT_STRINGIZE_(x) #x
#define _CRT_STRINGIZE(x) _CRT_STRINGIZE_(x)
user541686
  • 205,094
  • 128
  • 528
  • 886
4

This is an addendum to the answer for those who find it tedious to punch in #pragma directives every-time they need to put a bookmark in the code: You can save a few keystrokes by whipping up a macro to do this for you! While in general, you cannot have a #pragma directive within macros, MS C/C++ compilers 2008 and above do support a special vendor-specific extension called the __pragma which can be used with macros. See Pragma Directives and the __Pragma Keyword.

I use something akin to the following on a daily basis:

#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();
}

You can easily extend it to suit your needs and add more warnings. The good part of having such a system is that you can selectively turn-on say, only code-review items and not have to worry about anything else by setting the appropriate macro in the build settings.

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
dirkgently
  • 108,024
  • 16
  • 131
  • 187
  • This doesn't seem to work for me, I get error C2059: syntax error: 'string' Can you give an example .cpp file that illustrates it working? – Peter Nimmo Jan 10 '23 at 17:45
4

This one allows it to be used without #pragma (Microsoft specific I think) and when you click it takes you to the line since it shows the file and line number just like a regular err/warning message does since none of the other ones seem to do this. This used to work without the __pragma but newer versions of msvc require it. Ive been using it since sometime in the 90's. I use Visual Studio 2013

#define MacroStr(x)   #x
#define MacroStr2(x)  MacroStr(x)
#define Message(desc) __pragma(message(__FILE__ "(" MacroStr2(__LINE__) ") :" #desc))

example :

Message("Need to add unit testing here")

output: 1> c:\source\include\mithrilsoftware.h(180) :"Need to add unit testing here"

  • It's the format of your message that decides whether it's 'clickable' in VS. Indeed, `__pragma`, with it's two leading underscores, is toolchain-specific. On top of that, `#pragma`, while not being standard, is supported by most toolchains (gcc, clang, vs...) too. – xtofl Nov 05 '13 at 05:59
  • Nice, but how can I make it to "pop" only one time? It appear for every file that uses the header. – Pedro77 Sep 09 '22 at 20:17
0

Use the # token. I've posted an example from MSDN below:

// 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")
Jacob
  • 34,255
  • 14
  • 110
  • 165
  • its no so simple, you need to expand `__LINE__` to its integer form before turning that into a string – Necrolis May 11 '11 at 15:26
  • @Necrolis: Found the MSDN KB article for this and posted a snippet – Jacob May 11 '11 at 15:27
  • 5
    While Microsoft is within their rights to define symbols with double underscores, you should avoid them. The standard reserves them for identifiers created by the compiler manufacturer. – Mark Ransom May 11 '11 at 20:39