PDA

View Full Version : QDebug output to file



gpuckett
16th May 2015, 14:48
I am developing an application using Qt Creator. It is version 3.1.2 based on Qt 5.3.1 (MSVC 2010, 32bit) running on Win 7. I have been working on this project for about 9 months. Before that I had no experience with Qt and almost none with C++. So I'm very inexperienced with resolving some issues I run into. This is one of them.

I picked up some code a few months ago that allows me to put the output of QDebug in a file rather than the console. I added it to a project at the time and it worked great. I am now attempting to put the same code in a new project and I am encountering build errors. The code goes in the main.cpp module. Here is the code:


#define MY_ASSERT(c) if (c == false) ;
#define MY_ASSERT_X(c, where, what) if (c == false) ;

void myLogger(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QFile file("E:/temp/logs/QDebug."+QDate::currentDate().toString("yyyyMMdd")+".log.txt");

MY_ASSERT(file.open(QIODevice::Append | QIODevice::Text));

QTextStream out(&file);
out << QTime::currentTime().toString("hh:mm:ss.zzzz ");

out << context.file << "::" << context.function << "::" << context.line;

switch (type)
{
case QtDebugMsg: out << " DBG "; break;
case QtWarningMsg: out << " WRN "; break;
case QtCriticalMsg: out << " CRT "; break;
case QtFatalMsg: out << " FTL "; break;
}

out << " " << msg << '\n';
out.flush();
}

And then in the function main I put


qInstallMessageHandler(myLogger);

In the new project I get the following errors:


C:\Qt\Qt5.3.1\5.3\msvc2010_opengl\include\QtCore\q datetime.h:122: warning: C4003: not enough actual parameters for macro 'min'
C:\Qt\Qt5.3.1\5.3\msvc2010_opengl\include\QtCore\q datetime.h:122: error: C2589: '(' : illegal token on right side of '::'
C:\Qt\Qt5.3.1\5.3\msvc2010_opengl\include\QtCore\q datetime.h:122: error: C2059: syntax error : '::'

The main difference between the two projects is that the one that works is a console application and uses QCoreApplication. The one that doesn't work is a widgets application and uses QApplication.

What do I need to do to get this code in the QWidgets application to work?

d_stranz
16th May 2015, 17:18
This looks like the line in question from qdatetime.h: (I'm using Qt 5.4.1, so the line numbers don't match exactly to your error message)


// using extra parentheses around min to avoid expanding it if it is a macro
static inline qint64 nullJd() { return (std::numeric_limits<qint64>::min)(); }


I think the clue is in the comment - somewhere in your code, "min" has been defined as a macro, and the compiler is expanding it to whatever the macro has defined it to be. This happens before the include of <QDateTime> in your code, so check your code (as well as any included files in your code that appear before <QDateTime>) and you'll most likely find a #define min... macro.

An easy test you can do before searching - modify your code like this:



#if defined( min )
#undef min
#endif

#include <QDateTime>


If this now compiles, then you know what's going wrong. Note that this #undef only affects the file being compiled, so if you don't use min() elsewhere in the same file, you're fine.


#define MY_ASSERT(c) if (c == false) ;
#define MY_ASSERT_X(c, where, what) if (c == false) ;

And this has got to be the most bizarre couple of lines I've ever seen. What do you think this is actually supposed to do? It certainly isn't an assert of any sort - it's an empty if statement that does absolutely nothing after evaluating its condition (which has the side effect of executing some code). If the condition is true, it does nothing, if the condition is false, it does nothing. MY_ASSERT() basically ignores the result of the test, no matter what happens.

If you want to test if something critical succeeded, then assign the result to a variable, test the variable, and do something sensible if the test shows the operation failed.

And note that you *do not* want to do this using assert() - if you execute critical code inside an assert(), it will only happen in a debug build. In release mode, assert() statements turn into no-ops.