Go Premium for a chance to win a PS4. Enter to Win


How can I see a CTime variable using the debugger QuickWatch window

Posted on 2002-03-23
Medium Priority
Last Modified: 2013-11-20
I have a number of CTime variables and when I ask to see them in the debugger they show as {time=0x3982f170} for my variable startTime.  What I'd like to see is 2Mar2002 10:11:53.

I can do this by inserting code after the variable is set as:

CString sTime = startTime.Format(_T("%c"));

and I can look at the sTime to see the full date and time for the locale.

This is a pain to have to insert these lines every time I want to look at a time value.

I think it should be possible to define a function in my project as:

CString ShowTime(CTime& time)
    return time.Format(_T("%c"));
Just to make sure that the routine was loaded, I added the following line directly after my unknown variable as:

CString sTime = ShowTime(startTime);

When I step to this point, sure enough I can display the value of sTime.

What I'd really like to do would be to use the ShowTime function in the QuickWatch window. However, when I type ShowTime(startTime) in QuickWatch, there is a message generated in the Value column:

Error: cannot display value

I tried putting a TRACE inside the function so possibly something would show up in the debug window but no such luck.

The general question really is: How can one invoke a function in the QuickWatch window so that it's output value is displayed?
Question by:emitchell

Expert Comment

ID: 6891205
Are you looking for functionality of Variables Window locals tab?

Author Comment

ID: 6891335
Not really. I can see the variable either by looking in the Locals tab or by highlighting the name and choosing QuickWatch. In both case, a CTime variable shows as an big integer. I want to see it as a date/time value.

I assume that there should be some way to invoke my function on the variable to show me what I want.

Accepted Solution

Triskelion earned 400 total points
ID: 6891777
The CTime::Format() performs a conversion on the (long) data of the CTime.  If what you were asking was to just CAST the CTime as another type of variable, it would make sense.  You're asking the debugger to run a function on every step to show you the result.  This would be extremely dangerous for the compiler.  What if it was a custom built function that accessed the disk or allocated memory outside of the current module?  There my be many steps in the conversion that would modify your results -- steps that cannot be stepped through with the debugger -- rendering it useless.
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 6892192
I don't want to see the value at every step. The program stops at a breakpoint and then I want to type in an expression into the quick watch window to see what the CTime variables actually contain. The expression rules for the quick watch window are supposed to allow me to use some of the functions in the project but it appears, not all the time.

As an example, I can look at a time_t value by defining the following function (and making sure it's linked into the .exe file):

const TCHAR *
Timet(time_t iTime)
    static TCHAR buffer[100];
    CTime cTime(iTime);
    CString sTime = cTime.Format(_T("%c"));
    _tcscpy(buffer, sTime);
    TRACE(_T("Timet:%s\n"), buffer);
    return buffer;

Now when I stop the program at a breakpoint, I can type in Timet(1233455) and I see the following in the quick watch window:

- Timet(1233455)     0x00548f28 "08/09/70 17:12:53"

and the trace value shows up in the debug window (twice!), showing that my routine has been executed.

I tried another ShowTime() function that used a static buffer to return the const TCHAR* pointer as follows:

const TCHAR*
ShowTime(CTime t)
    static TCHAR buffer[100];
    CString st = t.Format(_T("%c"));
    _tcscpy(buffer, st);
    TRACE(_T("ShowTime:%s\n"), buffer);
    return buffer;

but when I try typing ShowTime(m_startTime) as the expression in the quick watch window, I get the message

ShowTime(m_startTime)     Error: cannot display value

Also I get no TRACE output in the debug window showing that the function was never executed. How can the Timet() function that returns the const TCHAR* show a value and the ShowTime() function that returns the same thing show the error that it can't display the value?

I even tried Timet(m_startTime.GetTime()) to extract the time_t part from the CTime variable but the message here is that the member function is not present.


Expert Comment

ID: 6896517
You could add the following line just before your breakpoint:

afxDump << t << "\n";

Where t is your CTime object. This will dump it to the output window in a neat form.

Author Comment

ID: 6897454
I don't want to have to put anything into the code. I could do this already with:

CString sTime = timeVar.Format(_T("%c"));

and then I can look at the sTime just by hovering over the variable with the mouse.

My purpose is to try and find a way to look at CTime variables by using an expression in the quick watch window. Then I can look at any time to check its value as I step through the code.

I can use my function as long as it has in int as an argument and a const TCHAR* as the output.

It doesn't like a CTime as a argument. I wonder if it also doesn't like a CTime& reference. It also doesn't like a CString as an output. Again I haven't tried a reference.

I can't find where the debugger limits the expression that one can type.

If I could extract the time_t long from inside the CTime then I could use this in the Timet(time_t) function above. I know that I can get the time_t conversion from Time1234).


Expert Comment

ID: 6897557
The afxDump is only active in Debug mode, so there won't be any overhead for Release mode.

I understand what you're trying to do, but then I'll have to point you back to my previous comment.

Sometimes "no you can't" is the proper answer to questions.

Author Comment

ID: 6898252
I think that I have solved the problem. In two ways in fact. By using a reference argument to my format function, the CTime value can be listed.  Define the ShowTime() function as follows:

const TCHAR*
ShowTime(CTime& time)
    static TCHAR buffer[100];
    CString sTime = time.Format(_T("%c"));
    _tcscpy(buffer, sTime);
    TRACE(_T("ShowTime:%s\n"), buffer);
    return buffer;

and then stopping at a breakpoint where we want to look at the CTime variable timeVar, type in the quick watch window:


and the time value will be listed out. I also tested transferring this expression to the Watch window and when the timeVar variable is reassigned, the ShowTime() expression is reevaluated.

The second method was that I could also use the Timet(time_t) function above since one can get at the time_t member of the CTime variable. Instead of using ShowTime() one can type:


since the m_time member of the CTime variable carries the time_t information.

From these experiments, it would seem that the debugger can't create variables. If the argument to the ShowTime() function is not a reference, then a copy has to be made to pass to the routine. This fails so that it seems that the debugger can't do this.

Similarly on output, it doesn't work to have a CString variable as output. I just tested returning a reference to an internal static CSTring. This also works fine.

Microsoft has given us a pretty powerful mechanism of examining variables of home grown types. Just define a function that can format the view on the variable and then invoke it from the quick watch or regular watch windows. Just make sure that the debugger never has to actually create any temporary variables.


Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…

877 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question