Improve company productivity with a Business Account.Sign Up

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 402
  • Last Modified:

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

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?
1 Solution
Are you looking for functionality of Variables Window locals tab?
emitchellAuthor Commented:
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.
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.
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

emitchellAuthor Commented:
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.

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.
emitchellAuthor Commented:
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).

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.
emitchellAuthor Commented:
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.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now